diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors')
3 files changed, 0 insertions, 1467 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java deleted file mode 100644 index 6df6929a7..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java +++ /dev/null @@ -1,621 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.ide.eclipse.adt.internal.editors.layout.descriptors; - -import static com.android.SdkConstants.ANDROID_NS_NAME_PREFIX; -import static com.android.SdkConstants.ANDROID_URI; -import static com.android.SdkConstants.AUTO_URI; -import static com.android.SdkConstants.CLASS_VIEWGROUP; -import static com.android.SdkConstants.URI_PREFIX; - -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.ide.common.resources.ResourceFile; -import com.android.ide.common.resources.ResourceItem; -import com.android.ide.common.resources.platform.AttributeInfo; -import com.android.ide.common.resources.platform.AttrsXmlParser; -import com.android.ide.common.resources.platform.ViewClassInfo; -import com.android.ide.common.resources.platform.ViewClassInfo.LayoutParamsInfo; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.AdtUtils; -import com.android.ide.eclipse.adt.internal.editors.IconFactory; -import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo; -import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources; -import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager; -import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; -import com.android.ide.eclipse.adt.internal.sdk.ProjectState; -import com.android.ide.eclipse.adt.internal.sdk.Sdk; -import com.android.resources.ResourceType; -import com.android.sdklib.IAndroidTarget; -import com.google.common.collect.Maps; -import com.google.common.collect.ObjectArrays; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jdt.core.IClassFile; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.ITypeHierarchy; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.swt.graphics.Image; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Service responsible for creating/managing {@link ViewElementDescriptor} objects for custom - * View classes per project. - * <p/> - * The service provides an on-demand monitoring of custom classes to check for changes. Monitoring - * starts once a request for an {@link ViewElementDescriptor} object has been done for a specific - * class. - * <p/> - * The monitoring will notify a listener of any changes in the class triggering a change in its - * associated {@link ViewElementDescriptor} object. - * <p/> - * If the custom class does not exist, no monitoring is put in place to avoid having to listen - * to all class changes in the projects. - */ -public final class CustomViewDescriptorService { - - private static CustomViewDescriptorService sThis = new CustomViewDescriptorService(); - - /** - * Map where keys are the project, and values are another map containing all the known - * custom View class for this project. The custom View class are stored in a map - * where the keys are the fully qualified class name, and the values are their associated - * {@link ViewElementDescriptor}. - */ - private HashMap<IProject, HashMap<String, ViewElementDescriptor>> mCustomDescriptorMap = - new HashMap<IProject, HashMap<String, ViewElementDescriptor>>(); - - /** - * TODO will be used to update the ViewElementDescriptor of the custom view when it - * is modified (either the class itself or its attributes.xml) - */ - @SuppressWarnings("unused") - private ICustomViewDescriptorListener mListener; - - /** - * Classes which implements this interface provide a method that deal with modifications - * in custom View class triggering a change in its associated {@link ViewClassInfo} object. - */ - public interface ICustomViewDescriptorListener { - /** - * Sent when a custom View class has changed and - * its {@link ViewElementDescriptor} was modified. - * - * @param project the project containing the class. - * @param className the fully qualified class name. - * @param descriptor the updated ElementDescriptor. - */ - public void updatedClassInfo(IProject project, - String className, - ViewElementDescriptor descriptor); - } - - /** - * Returns the singleton instance of {@link CustomViewDescriptorService}. - */ - public static CustomViewDescriptorService getInstance() { - return sThis; - } - - /** - * Sets the listener receiving custom View class modification notifications. - * @param listener the listener to receive the notifications. - * - * TODO will be used to update the ViewElementDescriptor of the custom view when it - * is modified (either the class itself or its attributes.xml) - */ - public void setListener(ICustomViewDescriptorListener listener) { - mListener = listener; - } - - /** - * Returns the {@link ViewElementDescriptor} for a particular project/class when the - * fully qualified class name actually matches a class from the given project. - * <p/> - * Custom descriptors are created as needed. - * <p/> - * If it is the first time the {@link ViewElementDescriptor} is requested, the method - * will check that the specified class is in fact a custom View class. Once this is - * established, a monitoring for that particular class is initiated. Any change will - * trigger a notification to the {@link ICustomViewDescriptorListener}. - * - * @param project the project containing the class. - * @param fqcn the fully qualified name of the class. - * @return a {@link ViewElementDescriptor} or <code>null</code> if the class was not - * a custom View class. - */ - public ViewElementDescriptor getDescriptor(IProject project, String fqcn) { - // look in the map first - synchronized (mCustomDescriptorMap) { - HashMap<String, ViewElementDescriptor> map = mCustomDescriptorMap.get(project); - - if (map != null) { - ViewElementDescriptor descriptor = map.get(fqcn); - if (descriptor != null) { - return descriptor; - } - } - - // if we step here, it looks like we haven't created it yet. - // First lets check this is in fact a valid type in the project - - try { - // We expect the project to be both opened and of java type (since it's an android - // project), so we can create a IJavaProject object from our IProject. - IJavaProject javaProject = JavaCore.create(project); - - // replace $ by . in the class name - String javaClassName = fqcn.replaceAll("\\$", "\\."); //$NON-NLS-1$ //$NON-NLS-2$ - - // look for the IType object for this class - IType type = javaProject.findType(javaClassName); - if (type != null && type.exists()) { - // the type exists. Let's get the parent class and its ViewClassInfo. - - // get the type hierarchy - ITypeHierarchy hierarchy = type.newSupertypeHierarchy( - new NullProgressMonitor()); - - ViewElementDescriptor parentDescriptor = createViewDescriptor( - hierarchy.getSuperclass(type), project, hierarchy); - - if (parentDescriptor != null) { - // we have a valid parent, lets create a new ViewElementDescriptor. - List<AttributeDescriptor> attrList = new ArrayList<AttributeDescriptor>(); - List<AttributeDescriptor> paramList = new ArrayList<AttributeDescriptor>(); - Map<ResourceFile, Long> files = findCustomDescriptors(project, type, - attrList, paramList); - - AttributeDescriptor[] attributes = - getAttributeDescriptor(type, parentDescriptor); - if (!attrList.isEmpty()) { - attributes = join(attrList, attributes); - } - AttributeDescriptor[] layoutAttributes = - getLayoutAttributeDescriptors(type, parentDescriptor); - if (!paramList.isEmpty()) { - layoutAttributes = join(paramList, layoutAttributes); - } - String name = DescriptorsUtils.getBasename(fqcn); - ViewElementDescriptor descriptor = new CustomViewDescriptor(name, fqcn, - attributes, - layoutAttributes, - parentDescriptor.getChildren(), - project, files); - descriptor.setSuperClass(parentDescriptor); - - synchronized (mCustomDescriptorMap) { - map = mCustomDescriptorMap.get(project); - if (map == null) { - map = new HashMap<String, ViewElementDescriptor>(); - mCustomDescriptorMap.put(project, map); - } - - map.put(fqcn, descriptor); - } - - //TODO setup listener on this resource change. - - return descriptor; - } - } - } catch (JavaModelException e) { - // there was an error accessing any of the IType, we'll just return null; - } - } - - return null; - } - - private static AttributeDescriptor[] join( - @NonNull List<AttributeDescriptor> attributeList, - @NonNull AttributeDescriptor[] attributes) { - if (!attributeList.isEmpty()) { - return ObjectArrays.concat( - attributeList.toArray(new AttributeDescriptor[attributeList.size()]), - attributes, - AttributeDescriptor.class); - } else { - return attributes; - } - - } - - /** Cache used by {@link #getParser(ResourceFile)} */ - private Map<ResourceFile, AttrsXmlParser> mParserCache; - - private AttrsXmlParser getParser(ResourceFile file) { - if (mParserCache == null) { - mParserCache = new HashMap<ResourceFile, AttrsXmlParser>(); - } - - AttrsXmlParser parser = mParserCache.get(file); - if (parser == null) { - parser = new AttrsXmlParser( - file.getFile().getOsLocation(), - AdtPlugin.getDefault(), 20); - parser.preload(); - mParserCache.put(file, parser); - } - - return parser; - } - - /** Compute/find the styleable resources for the given type, if possible */ - private Map<ResourceFile, Long> findCustomDescriptors( - IProject project, - IType type, - List<AttributeDescriptor> customAttributes, - List<AttributeDescriptor> customLayoutAttributes) { - // Look up the project where the type is declared (could be a library project; - // we cannot use type.getJavaProject().getProject()) - IProject library = getProjectDeclaringType(type); - if (library == null) { - library = project; - } - - String className = type.getElementName(); - Set<ResourceFile> resourceFiles = findAttrsFiles(library, className); - if (resourceFiles != null && resourceFiles.size() > 0) { - String appUri = getAppResUri(project); - Map<ResourceFile, Long> timestamps = - Maps.newHashMapWithExpectedSize(resourceFiles.size()); - for (ResourceFile file : resourceFiles) { - AttrsXmlParser attrsXmlParser = getParser(file); - String fqcn = type.getFullyQualifiedName(); - - // Attributes - ViewClassInfo classInfo = new ViewClassInfo(true, fqcn, className); - attrsXmlParser.loadViewAttributes(classInfo); - appendAttributes(customAttributes, classInfo.getAttributes(), appUri); - - // Layout params - LayoutParamsInfo layoutInfo = new ViewClassInfo.LayoutParamsInfo( - classInfo, "Layout", null /*superClassInfo*/); //$NON-NLS-1$ - attrsXmlParser.loadLayoutParamsAttributes(layoutInfo); - appendAttributes(customLayoutAttributes, layoutInfo.getAttributes(), appUri); - - timestamps.put(file, file.getFile().getModificationStamp()); - } - - return timestamps; - } - - return null; - } - - /** - * Finds the set of XML files (if any) in the given library declaring - * attributes for the given class name - */ - @Nullable - private static Set<ResourceFile> findAttrsFiles(IProject library, String className) { - Set<ResourceFile> resourceFiles = null; - ResourceManager manager = ResourceManager.getInstance(); - ProjectResources resources = manager.getProjectResources(library); - if (resources != null) { - Collection<ResourceItem> items = - resources.getResourceItemsOfType(ResourceType.DECLARE_STYLEABLE); - for (ResourceItem item : items) { - String viewName = item.getName(); - if (viewName.equals(className) - || (viewName.startsWith(className) - && viewName.equals(className + "_Layout"))) { //$NON-NLS-1$ - if (resourceFiles == null) { - resourceFiles = new HashSet<ResourceFile>(); - } - resourceFiles.addAll(item.getSourceFileList()); - } - } - } - return resourceFiles; - } - - /** - * Find the project containing this type declaration. We cannot use - * {@link IType#getJavaProject()} since that will return the including - * project and we're after the library project such that we can find the - * attrs.xml file in the same project. - */ - @Nullable - private static IProject getProjectDeclaringType(IType type) { - IClassFile classFile = type.getClassFile(); - if (classFile != null) { - IPath path = classFile.getPath(); - IWorkspaceRoot workspace = ResourcesPlugin.getWorkspace().getRoot(); - IResource resource; - if (path.isAbsolute()) { - resource = AdtUtils.fileToResource(path.toFile()); - } else { - resource = workspace.findMember(path); - } - if (resource != null && resource.getProject() != null) { - return resource.getProject(); - } - } - - return null; - } - - /** Returns the name space to use for application attributes */ - private static String getAppResUri(IProject project) { - String appResource; - ProjectState projectState = Sdk.getProjectState(project); - if (projectState != null && projectState.isLibrary()) { - appResource = AUTO_URI; - } else { - ManifestInfo manifestInfo = ManifestInfo.get(project); - appResource = URI_PREFIX + manifestInfo.getPackage(); - } - return appResource; - } - - - /** Append the {@link AttributeInfo} objects converted {@link AttributeDescriptor} - * objects into the given attribute list. - * <p> - * This is nearly identical to - * {@link DescriptorsUtils#appendAttribute(List, String, String, AttributeInfo, boolean, Map)} - * but it handles namespace declarations in the attrs.xml file where the android: - * namespace is included in the names. - */ - private static void appendAttributes(List<AttributeDescriptor> attributes, - AttributeInfo[] attributeInfos, String appResource) { - // Custom attributes - for (AttributeInfo info : attributeInfos) { - String nsUri; - if (info.getName().startsWith(ANDROID_NS_NAME_PREFIX)) { - info.setName(info.getName().substring(ANDROID_NS_NAME_PREFIX.length())); - nsUri = ANDROID_URI; - } else { - nsUri = appResource; - } - - DescriptorsUtils.appendAttribute(attributes, - null /*elementXmlName*/, nsUri, info, false /*required*/, - null /*overrides*/); - } - } - - /** - * Computes (if needed) and returns the {@link ViewElementDescriptor} for the specified type. - * - * @return A {@link ViewElementDescriptor} or null if type or typeHierarchy is null. - */ - private ViewElementDescriptor createViewDescriptor(IType type, IProject project, - ITypeHierarchy typeHierarchy) { - // check if the type is a built-in View class. - List<ViewElementDescriptor> builtInList = null; - - // give up if there's no type - if (type == null) { - return null; - } - - String fqcn = type.getFullyQualifiedName(); - - Sdk currentSdk = Sdk.getCurrent(); - if (currentSdk != null) { - IAndroidTarget target = currentSdk.getTarget(project); - if (target != null) { - AndroidTargetData data = currentSdk.getTargetData(target); - if (data != null) { - LayoutDescriptors descriptors = data.getLayoutDescriptors(); - ViewElementDescriptor d = descriptors.findDescriptorByClass(fqcn); - if (d != null) { - return d; - } - builtInList = descriptors.getViewDescriptors(); - } - } - } - - // it's not a built-in class? Lets look if the superclass is built-in - // give up if there's no type - if (typeHierarchy == null) { - return null; - } - - IType parentType = typeHierarchy.getSuperclass(type); - if (parentType != null) { - ViewElementDescriptor parentDescriptor = createViewDescriptor(parentType, project, - typeHierarchy); - - if (parentDescriptor != null) { - // parent class is a valid View class with a descriptor, so we create one - // for this class. - String name = DescriptorsUtils.getBasename(fqcn); - // A custom view accepts children if its parent descriptor also does. - // The only exception to this is ViewGroup, which accepts children even though - // its parent does not. - boolean isViewGroup = fqcn.equals(CLASS_VIEWGROUP); - boolean hasChildren = isViewGroup || parentDescriptor.hasChildren(); - ViewElementDescriptor[] children = null; - if (hasChildren && builtInList != null) { - // We can't figure out what the allowable children are by just - // looking at the class, so assume any View is valid - children = builtInList.toArray(new ViewElementDescriptor[builtInList.size()]); - } - ViewElementDescriptor descriptor = new CustomViewDescriptor(name, fqcn, - getAttributeDescriptor(type, parentDescriptor), - getLayoutAttributeDescriptors(type, parentDescriptor), - children, project, null); - descriptor.setSuperClass(parentDescriptor); - - // add it to the map - synchronized (mCustomDescriptorMap) { - HashMap<String, ViewElementDescriptor> map = mCustomDescriptorMap.get(project); - - if (map == null) { - map = new HashMap<String, ViewElementDescriptor>(); - mCustomDescriptorMap.put(project, map); - } - - map.put(fqcn, descriptor); - - } - - //TODO setup listener on this resource change. - - return descriptor; - } - } - - // class is neither a built-in view class, nor extend one. return null. - return null; - } - - /** - * Returns the array of {@link AttributeDescriptor} for the specified {@link IType}. - * <p/> - * The array should contain the descriptor for this type and all its supertypes. - * - * @param type the type for which the {@link AttributeDescriptor} are returned. - * @param parentDescriptor the {@link ViewElementDescriptor} of the direct superclass. - */ - private static AttributeDescriptor[] getAttributeDescriptor(IType type, - ViewElementDescriptor parentDescriptor) { - // TODO add the class attribute descriptors to the parent descriptors. - return parentDescriptor.getAttributes(); - } - - private static AttributeDescriptor[] getLayoutAttributeDescriptors(IType type, - ViewElementDescriptor parentDescriptor) { - return parentDescriptor.getLayoutAttributes(); - } - - private class CustomViewDescriptor extends ViewElementDescriptor { - private Map<ResourceFile, Long> mTimeStamps; - private IProject mProject; - - public CustomViewDescriptor(String name, String fqcn, AttributeDescriptor[] attributes, - AttributeDescriptor[] layoutAttributes, - ElementDescriptor[] children, IProject project, - Map<ResourceFile, Long> timestamps) { - super( - fqcn, // xml name - name, // ui name - fqcn, // full class name - fqcn, // tooltip - null, // sdk_url - attributes, - layoutAttributes, - children, - false // mandatory - ); - mTimeStamps = timestamps; - mProject = project; - } - - @Override - public Image getGenericIcon() { - IconFactory iconFactory = IconFactory.getInstance(); - - int index = mXmlName.lastIndexOf('.'); - if (index != -1) { - return iconFactory.getIcon(mXmlName.substring(index + 1), - "customView"); //$NON-NLS-1$ - } - - return iconFactory.getIcon("customView"); //$NON-NLS-1$ - } - - @Override - public boolean syncAttributes() { - // Check if any of the descriptors - if (mTimeStamps != null) { - // Prevent checking actual file timestamps too frequently on rapid burst calls - long now = System.currentTimeMillis(); - if (now - sLastCheck < 1000) { - return true; - } - sLastCheck = now; - - // Check whether the resource files (typically just one) which defined - // custom attributes for this custom view have changed, and if so, - // refresh the attribute descriptors. - // This doesn't work the cases where you add descriptors for a custom - // view after using it, or add attributes in a separate file, but those - // scenarios aren't quite as common (and would require a bit more expensive - // analysis.) - for (Map.Entry<ResourceFile, Long> entry : mTimeStamps.entrySet()) { - ResourceFile file = entry.getKey(); - Long timestamp = entry.getValue(); - boolean recompute = false; - if (file.getFile().getModificationStamp() > timestamp.longValue()) { - // One or more attributes changed: recompute - recompute = true; - mParserCache.remove(file); - } - - if (recompute) { - IJavaProject javaProject = JavaCore.create(mProject); - String fqcn = getFullClassName(); - IType type = null; - try { - type = javaProject.findType(fqcn); - } catch (CoreException e) { - AdtPlugin.log(e, null); - } - if (type == null || !type.exists()) { - return true; - } - - List<AttributeDescriptor> attrList = new ArrayList<AttributeDescriptor>(); - List<AttributeDescriptor> paramList = new ArrayList<AttributeDescriptor>(); - - mTimeStamps = findCustomDescriptors(mProject, type, attrList, paramList); - - ViewElementDescriptor parentDescriptor = getSuperClassDesc(); - AttributeDescriptor[] attributes = - getAttributeDescriptor(type, parentDescriptor); - if (!attrList.isEmpty()) { - attributes = join(attrList, attributes); - } - attributes = attrList.toArray(new AttributeDescriptor[attrList.size()]); - setAttributes(attributes); - - return false; - } - } - } - - return true; - } - } - - /** Timestamp of the most recent {@link CustomViewDescriptor#syncAttributes} check */ - private static long sLastCheck; -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java deleted file mode 100644 index 7b2fe84f0..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java +++ /dev/null @@ -1,597 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.ide.eclipse.adt.internal.editors.layout.descriptors; - -import static com.android.SdkConstants.ANDROID_URI; -import static com.android.SdkConstants.ATTR_CLASS; -import static com.android.SdkConstants.ATTR_LAYOUT; -import static com.android.SdkConstants.ATTR_NAME; -import static com.android.SdkConstants.ATTR_TAG; -import static com.android.SdkConstants.CLASS_VIEW; -import static com.android.SdkConstants.FQCN_GESTURE_OVERLAY_VIEW; -import static com.android.SdkConstants.REQUEST_FOCUS; -import static com.android.SdkConstants.VIEW_FRAGMENT; -import static com.android.SdkConstants.VIEW_INCLUDE; -import static com.android.SdkConstants.VIEW_MERGE; -import static com.android.SdkConstants.VIEW_TAG; - -import com.android.SdkConstants; -import com.android.ide.common.api.IAttributeInfo.Format; -import com.android.ide.common.resources.platform.AttributeInfo; -import com.android.ide.common.resources.platform.DeclareStyleableInfo; -import com.android.ide.common.resources.platform.ViewClassInfo; -import com.android.ide.common.resources.platform.ViewClassInfo.LayoutParamsInfo; -import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; -import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider; -import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.ClassAttributeDescriptor; -import com.android.sdklib.IAndroidTarget; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - - -/** - * Complete description of the layout structure. - */ -public final class LayoutDescriptors implements IDescriptorProvider { - /** The document descriptor. Contains all layouts and views linked together. */ - private DocumentDescriptor mRootDescriptor = - new DocumentDescriptor("layout_doc", null); //$NON-NLS-1$ - - /** The list of all known ViewLayout descriptors. */ - private List<ViewElementDescriptor> mLayoutDescriptors = Collections.emptyList(); - - /** Read-Only list of View Descriptors. */ - private List<ViewElementDescriptor> mROLayoutDescriptors; - - /** The list of all known View (not ViewLayout) descriptors. */ - private List<ViewElementDescriptor> mViewDescriptors = Collections.emptyList(); - - /** Read-Only list of View Descriptors. */ - private List<ViewElementDescriptor> mROViewDescriptors; - - /** The descriptor matching android.view.View. */ - private ViewElementDescriptor mBaseViewDescriptor; - - /** Map from view full class name to view descriptor */ - private Map<String, ViewElementDescriptor> mFqcnToDescriptor = - // As of 3.1 there are 58 items in this map - new HashMap<String, ViewElementDescriptor>(80); - - /** Returns the document descriptor. Contains all layouts and views linked together. */ - @Override - public DocumentDescriptor getDescriptor() { - return mRootDescriptor; - } - - /** Returns the read-only list of all known ViewLayout descriptors. */ - public List<ViewElementDescriptor> getLayoutDescriptors() { - return mROLayoutDescriptors; - } - - /** Returns the read-only list of all known View (not ViewLayout) descriptors. */ - public List<ViewElementDescriptor> getViewDescriptors() { - return mROViewDescriptors; - } - - @Override - public ElementDescriptor[] getRootElementDescriptors() { - return mRootDescriptor.getChildren(); - } - - /** - * Returns the descriptor matching android.view.View, which is guaranteed - * to be a {@link ViewElementDescriptor}. - */ - public ViewElementDescriptor getBaseViewDescriptor() { - if (mBaseViewDescriptor == null) { - mBaseViewDescriptor = findDescriptorByClass(SdkConstants.CLASS_VIEW); - } - return mBaseViewDescriptor; - } - - /** - * Updates the document descriptor. - * <p/> - * It first computes the new children of the descriptor and then update them - * all at once. - * <p/> - * TODO: differentiate groups from views in the tree UI? => rely on icons - * <p/> - * - * @param views The list of views in the framework. - * @param layouts The list of layouts in the framework. - * @param styleMap A map from style names to style information provided by the SDK - * @param target The android target being initialized - */ - public synchronized void updateDescriptors(ViewClassInfo[] views, ViewClassInfo[] layouts, - Map<String, DeclareStyleableInfo> styleMap, IAndroidTarget target) { - - // This map links every ViewClassInfo to the ElementDescriptor we created. - // It is filled by convertView() and used later to fix the super-class hierarchy. - HashMap<ViewClassInfo, ViewElementDescriptor> infoDescMap = - new HashMap<ViewClassInfo, ViewElementDescriptor>(); - - ArrayList<ViewElementDescriptor> newViews = new ArrayList<ViewElementDescriptor>(40); - if (views != null) { - for (ViewClassInfo info : views) { - ViewElementDescriptor desc = convertView(info, infoDescMap); - newViews.add(desc); - mFqcnToDescriptor.put(desc.getFullClassName(), desc); - } - } - - // Create <include> as a synthetic regular view. - // Note: ViewStub is already described by attrs.xml - insertInclude(newViews); - - List<ViewElementDescriptor> newLayouts = new ArrayList<ViewElementDescriptor>(30); - if (layouts != null) { - for (ViewClassInfo info : layouts) { - ViewElementDescriptor desc = convertView(info, infoDescMap); - newLayouts.add(desc); - mFqcnToDescriptor.put(desc.getFullClassName(), desc); - } - } - - // Find View and inherit all its layout attributes - AttributeDescriptor[] frameLayoutAttrs = findViewLayoutAttributes( - SdkConstants.CLASS_FRAMELAYOUT); - - if (target.getVersion().getApiLevel() >= 4) { - ViewElementDescriptor fragmentTag = createFragment(frameLayoutAttrs, styleMap); - newViews.add(fragmentTag); - } - - List<ElementDescriptor> newDescriptors = new ArrayList<ElementDescriptor>(80); - newDescriptors.addAll(newLayouts); - newDescriptors.addAll(newViews); - - ViewElementDescriptor viewTag = createViewTag(frameLayoutAttrs); - newViews.add(viewTag); - newDescriptors.add(viewTag); - - ViewElementDescriptor requestFocus = createRequestFocus(); - newViews.add(requestFocus); - newDescriptors.add(requestFocus); - - // Link all layouts to everything else here.. recursively - for (ViewElementDescriptor layoutDesc : newLayouts) { - layoutDesc.setChildren(newDescriptors); - } - - // The gesture overlay descriptor is really a layout but not included in the layouts list - // so handle it specially - ViewElementDescriptor gestureView = findDescriptorByClass(FQCN_GESTURE_OVERLAY_VIEW); - if (gestureView != null) { - gestureView.setChildren(newDescriptors); - // Inherit layout attributes from FrameLayout - gestureView.setLayoutAttributes(frameLayoutAttrs); - } - - fixSuperClasses(infoDescMap); - - // The <merge> tag can only be a root tag, so it is added at the end. - // It gets everything else as children but it is not made a child itself. - ViewElementDescriptor mergeTag = createMerge(frameLayoutAttrs); - mergeTag.setChildren(newDescriptors); // mergeTag makes a copy of the list - newDescriptors.add(mergeTag); - newLayouts.add(mergeTag); - - // Sort palette contents - Collections.sort(newViews); - Collections.sort(newLayouts); - - mViewDescriptors = newViews; - mLayoutDescriptors = newLayouts; - mRootDescriptor.setChildren(newDescriptors); - - mBaseViewDescriptor = null; - mROLayoutDescriptors = Collections.unmodifiableList(mLayoutDescriptors); - mROViewDescriptors = Collections.unmodifiableList(mViewDescriptors); - } - - /** - * Creates an element descriptor from a given {@link ViewClassInfo}. - * - * @param info The {@link ViewClassInfo} to convert into a new {@link ViewElementDescriptor}. - * @param infoDescMap This map links every ViewClassInfo to the ElementDescriptor it created. - * It is filled by here and used later to fix the super-class hierarchy. - */ - private ViewElementDescriptor convertView( - ViewClassInfo info, - HashMap<ViewClassInfo, ViewElementDescriptor> infoDescMap) { - String xmlName = info.getShortClassName(); - String uiName = xmlName; - String fqcn = info.getFullClassName(); - if (ViewElementDescriptor.viewNeedsPackage(fqcn)) { - xmlName = fqcn; - } - String tooltip = info.getJavaDoc(); - - // Average is around 90, max (in 3.2) is 145 - ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>(120); - - // All views and groups have an implicit "style" attribute which is a reference. - AttributeInfo styleInfo = new AttributeInfo( - "style", //$NON-NLS-1$ xmlLocalName - Format.REFERENCE_SET); - styleInfo.setJavaDoc("A reference to a custom style"); //tooltip - DescriptorsUtils.appendAttribute(attributes, - "style", //$NON-NLS-1$ - null, //nsUri - styleInfo, - false, //required - null); // overrides - styleInfo.setDefinedBy(SdkConstants.CLASS_VIEW); - - // Process all View attributes - DescriptorsUtils.appendAttributes(attributes, - null, // elementName - ANDROID_URI, - info.getAttributes(), - null, // requiredAttributes - null /* overrides */); - - List<String> attributeSources = new ArrayList<String>(); - if (info.getAttributes() != null && info.getAttributes().length > 0) { - attributeSources.add(fqcn); - } - - for (ViewClassInfo link = info.getSuperClass(); - link != null; - link = link.getSuperClass()) { - AttributeInfo[] attrList = link.getAttributes(); - if (attrList.length > 0) { - attributeSources.add(link.getFullClassName()); - DescriptorsUtils.appendAttributes(attributes, - null, // elementName - ANDROID_URI, - attrList, - null, // requiredAttributes - null /* overrides */); - } - } - - // Process all LayoutParams attributes - ArrayList<AttributeDescriptor> layoutAttributes = new ArrayList<AttributeDescriptor>(); - LayoutParamsInfo layoutParams = info.getLayoutData(); - - for(; layoutParams != null; layoutParams = layoutParams.getSuperClass()) { - for (AttributeInfo attrInfo : layoutParams.getAttributes()) { - if (DescriptorsUtils.containsAttribute(layoutAttributes, - ANDROID_URI, attrInfo)) { - continue; - } - DescriptorsUtils.appendAttribute(layoutAttributes, - null, // elementName - ANDROID_URI, - attrInfo, - false, // required - null /* overrides */); - } - } - - ViewElementDescriptor desc = new ViewElementDescriptor( - xmlName, - uiName, - fqcn, - tooltip, - null, // sdk_url - attributes.toArray(new AttributeDescriptor[attributes.size()]), - layoutAttributes.toArray(new AttributeDescriptor[layoutAttributes.size()]), - null, // children - false /* mandatory */); - desc.setAttributeSources(Collections.unmodifiableList(attributeSources)); - infoDescMap.put(info, desc); - return desc; - } - - /** - * Creates a new {@code <include>} descriptor and adds it to the list of view descriptors. - * - * @param knownViews A list of view descriptors being populated. Also used to find the - * View descriptor and extract its layout attributes. - */ - private void insertInclude(List<ViewElementDescriptor> knownViews) { - String xmlName = VIEW_INCLUDE; - - // Create the include custom attributes - ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>(); - - // Find View and inherit all its layout attributes - AttributeDescriptor[] viewLayoutAttribs; - AttributeDescriptor[] viewAttributes = null; - ViewElementDescriptor viewDesc = findDescriptorByClass(SdkConstants.CLASS_VIEW); - if (viewDesc != null) { - viewAttributes = viewDesc.getAttributes(); - attributes = new ArrayList<AttributeDescriptor>(viewAttributes.length + 1); - viewLayoutAttribs = viewDesc.getLayoutAttributes(); - } else { - viewLayoutAttribs = new AttributeDescriptor[0]; - } - - // Note that the "layout" attribute does NOT have the Android namespace - DescriptorsUtils.appendAttribute(attributes, - null, //elementXmlName - null, //nsUri - new AttributeInfo( - ATTR_LAYOUT, - Format.REFERENCE_SET ), - true, //required - null); //overrides - - if (viewAttributes != null) { - for (AttributeDescriptor descriptor : viewAttributes) { - attributes.add(descriptor); - } - } - - // Create the include descriptor - ViewElementDescriptor desc = new ViewElementDescriptor(xmlName, - xmlName, // ui_name - VIEW_INCLUDE, // "class name"; the GLE only treats this as an element tag - "Lets you statically include XML layouts inside other XML layouts.", // tooltip - null, // sdk_url - attributes.toArray(new AttributeDescriptor[attributes.size()]), - viewLayoutAttribs, // layout attributes - null, // children - false /* mandatory */); - - knownViews.add(desc); - } - - /** - * Creates and returns a new {@code <merge>} descriptor. - * @param viewLayoutAttribs The layout attributes to use for the new descriptor - */ - private ViewElementDescriptor createMerge(AttributeDescriptor[] viewLayoutAttribs) { - String xmlName = VIEW_MERGE; - - // Create the include descriptor - ViewElementDescriptor desc = new ViewElementDescriptor(xmlName, - xmlName, // ui_name - VIEW_MERGE, // "class name"; the GLE only treats this as an element tag - "A root tag useful for XML layouts inflated using a ViewStub.", // tooltip - null, // sdk_url - null, // attributes - viewLayoutAttribs, // layout attributes - null, // children - false /* mandatory */); - - return desc; - } - - /** - * Creates and returns a new {@code <fragment>} descriptor. - * @param viewLayoutAttribs The layout attributes to use for the new descriptor - * @param styleMap The style map provided by the SDK - */ - private ViewElementDescriptor createFragment(AttributeDescriptor[] viewLayoutAttribs, - Map<String, DeclareStyleableInfo> styleMap) { - String xmlName = VIEW_FRAGMENT; - final ViewElementDescriptor descriptor; - - // First try to create the descriptor from metadata in attrs.xml: - DeclareStyleableInfo style = styleMap.get("Fragment"); //$NON-NLS-1$ - String fragmentTooltip = - "A Fragment is a piece of an application's user interface or behavior that " - + "can be placed in an Activity"; - String sdkUrl = "http://developer.android.com/guide/topics/fundamentals/fragments.html"; - TextAttributeDescriptor classAttribute = new ClassAttributeDescriptor( - // Should accept both CLASS_V4_FRAGMENT and CLASS_FRAGMENT - null /*superClassName*/, - ATTR_CLASS, null /* namespace */, - new AttributeInfo(ATTR_CLASS, Format.STRING_SET), - true /*mandatory*/) - .setTooltip("Supply the name of the fragment class to instantiate"); - - if (style != null) { - descriptor = new ViewElementDescriptor( - VIEW_FRAGMENT, VIEW_FRAGMENT, VIEW_FRAGMENT, - fragmentTooltip, // tooltip - sdkUrl, //, - null /* attributes */, - viewLayoutAttribs, // layout attributes - null /*childrenElements*/, - false /*mandatory*/); - ArrayList<AttributeDescriptor> descs = new ArrayList<AttributeDescriptor>(); - // The class attribute is not included in the attrs.xml - descs.add(classAttribute); - DescriptorsUtils.appendAttributes(descs, - null, // elementName - ANDROID_URI, - style.getAttributes(), - null, // requiredAttributes - null); // overrides - //descriptor.setTooltip(style.getJavaDoc()); - descriptor.setAttributes(descs.toArray(new AttributeDescriptor[descs.size()])); - } else { - // The above will only work on API 11 and up. However, fragments are *also* available - // on older platforms, via the fragment support library, so add in a manual - // entry if necessary. - descriptor = new ViewElementDescriptor(xmlName, - xmlName, // ui_name - xmlName, // "class name"; the GLE only treats this as an element tag - fragmentTooltip, - sdkUrl, - new AttributeDescriptor[] { - new ClassAttributeDescriptor( - null /*superClassName*/, - ATTR_NAME, ANDROID_URI, - new AttributeInfo(ATTR_NAME, Format.STRING_SET), - true /*mandatory*/) - .setTooltip("Supply the name of the fragment class to instantiate"), - classAttribute, - new ClassAttributeDescriptor( - null /*superClassName*/, - ATTR_TAG, ANDROID_URI, - new AttributeInfo(ATTR_TAG, Format.STRING_SET), - true /*mandatory*/) - .setTooltip("Supply a tag for the top-level view containing a String"), - }, // attributes - viewLayoutAttribs, // layout attributes - null, // children - false /* mandatory */); - } - - return descriptor; - } - - /** - * Creates and returns a new {@code <view>} descriptor. - * @param viewLayoutAttribs The layout attributes to use for the new descriptor - * @param styleMap The style map provided by the SDK - */ - private ViewElementDescriptor createViewTag(AttributeDescriptor[] viewLayoutAttribs) { - String xmlName = VIEW_TAG; - - TextAttributeDescriptor classAttribute = new ClassAttributeDescriptor( - CLASS_VIEW, - ATTR_CLASS, null /* namespace */, - new AttributeInfo(ATTR_CLASS, Format.STRING_SET), - true /*mandatory*/) - .setTooltip("Supply the name of the view class to instantiate"); - - // Create the include descriptor - ViewElementDescriptor desc = new ViewElementDescriptor(xmlName, - xmlName, // ui_name - xmlName, // "class name"; the GLE only treats this as an element tag - "A view tag whose class attribute names the class to be instantiated", // tooltip - null, // sdk_url - new AttributeDescriptor[] { // attributes - classAttribute - }, - viewLayoutAttribs, // layout attributes - null, // children - false /* mandatory */); - - return desc; - } - - /** - * Creates and returns a new {@code <requestFocus>} descriptor. - */ - private ViewElementDescriptor createRequestFocus() { - String xmlName = REQUEST_FOCUS; - - // Create the include descriptor - return new ViewElementDescriptor( - xmlName, // xml_name - xmlName, // ui_name - xmlName, // "class name"; the GLE only treats this as an element tag - "Requests focus for the parent element or one of its descendants", // tooltip - null, // sdk_url - null, // attributes - null, // layout attributes - null, // children - false /* mandatory */); - } - - /** - * Finds the descriptor and retrieves all its layout attributes. - */ - private AttributeDescriptor[] findViewLayoutAttributes( - String viewFqcn) { - ViewElementDescriptor viewDesc = findDescriptorByClass(viewFqcn); - if (viewDesc != null) { - return viewDesc.getLayoutAttributes(); - } - - return null; - } - - /** - * Set the super-class of each {@link ViewElementDescriptor} by using the super-class - * information available in the {@link ViewClassInfo}. - */ - private void fixSuperClasses(Map<ViewClassInfo, ViewElementDescriptor> infoDescMap) { - - for (Entry<ViewClassInfo, ViewElementDescriptor> entry : infoDescMap.entrySet()) { - ViewClassInfo info = entry.getKey(); - ViewElementDescriptor desc = entry.getValue(); - - ViewClassInfo sup = info.getSuperClass(); - if (sup != null) { - ViewElementDescriptor supDesc = infoDescMap.get(sup); - while (supDesc == null && sup != null) { - // We don't have a descriptor for the super-class. That means the class is - // probably abstract, so we just need to walk up the super-class chain till - // we find one we have. All views derive from android.view.View so we should - // surely find that eventually. - sup = sup.getSuperClass(); - if (sup != null) { - supDesc = infoDescMap.get(sup); - } - } - if (supDesc != null) { - desc.setSuperClass(supDesc); - } - } - } - } - - /** - * Returns the {@link ViewElementDescriptor} with the given fully qualified class - * name, or null if not found. This is a quick map lookup. - * - * @param fqcn the fully qualified class name - * @return the corresponding {@link ViewElementDescriptor} or null - */ - public ViewElementDescriptor findDescriptorByClass(String fqcn) { - return mFqcnToDescriptor.get(fqcn); - } - - /** - * Returns the {@link ViewElementDescriptor} with the given XML tag name, - * which usually does not include the package (depending on the - * value of {@link ViewElementDescriptor#viewNeedsPackage(String)}). - * - * @param tag the XML tag name - * @return the corresponding {@link ViewElementDescriptor} or null - */ - public ViewElementDescriptor findDescriptorByTag(String tag) { - // TODO: Consider whether we need to add a direct map lookup for this as well. - // Currently not done since this is not frequently needed (only needed for - // exploded rendering which was already performing list iteration.) - for (ViewElementDescriptor descriptor : mLayoutDescriptors) { - if (tag.equals(descriptor.getXmlLocalName())) { - return descriptor; - } - } - - return null; - } - - /** - * Returns a collection of all the view class names, including layouts - * - * @return a collection of all the view class names, never null - */ - public Collection<String> getAllViewClassNames() { - return mFqcnToDescriptor.keySet(); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/ViewElementDescriptor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/ViewElementDescriptor.java deleted file mode 100644 index 79995249c..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/ViewElementDescriptor.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.ide.eclipse.adt.internal.editors.layout.descriptors; - -import static com.android.SdkConstants.ANDROID_VIEW_PKG; -import static com.android.SdkConstants.ANDROID_WEBKIT_PKG; -import static com.android.SdkConstants.ANDROID_WIDGET_PREFIX; -import static com.android.SdkConstants.VIEW; -import static com.android.SdkConstants.VIEW_TAG; - -import com.android.ide.common.resources.platform.AttributeInfo; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.IconFactory; -import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; -import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; -import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode; -import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; - -import org.eclipse.swt.graphics.Image; - -import java.util.Collections; -import java.util.List; - -/** - * {@link ViewElementDescriptor} describes the properties expected for a given XML element node - * representing a class in an XML Layout file. - * <p/> - * These descriptors describe Android views XML elements. - * <p/> - * The base class {@link ElementDescriptor} has a notion of "children", that is an XML element - * can produce another set of XML elements. Because of the flat nature of Android's layout - * XML files all possible views are children of the document and of themselves (that is any - * view group can contain any other view). This is an implied contract of this class that is - * enforces at construction by {@link LayoutDescriptors}. Note that by construction any code - * that deals with the children hierarchy must also deal with potential infinite loops since views - * <em>will</em> reference themselves (e.g. a ViewGroup can contain a ViewGroup). - * <p/> - * Since Views are also Java classes, they derive from each other. Here this is represented - * as the "super class", which denotes the fact that a given View java class derives from - * another class. These properties are also set at construction by {@link LayoutDescriptors}. - * The super class hierarchy is very different from the descriptor's children hierarchy: the - * later represents Java inheritance, the former represents an XML nesting capability. - * - * @see ElementDescriptor - */ -public class ViewElementDescriptor extends ElementDescriptor { - - /** The full class name (FQCN) of this view. */ - private final String mFullClassName; - - /** The list of layout attributes. Can be empty but not null. */ - private AttributeDescriptor[] mLayoutAttributes; - - /** The super-class descriptor. Can be null. */ - private ViewElementDescriptor mSuperClassDesc; - - /** List of attribute sources, classes that contribute attributes to {@link #mAttributes} */ - private List<String> mAttributeSources; - - /** - * Constructs a new {@link ViewElementDescriptor} based on its XML name, UI name, - * the canonical name of the class it represents, its tooltip, its SDK url, its attributes list, - * its children list and its mandatory flag. - * - * @param xml_name The XML element node name. Case sensitive. - * @param ui_name The XML element name for the user interface, typically capitalized. - * @param fullClassName The fully qualified class name the {@link ViewElementDescriptor} is - * representing. - * @param tooltip An optional tooltip. Can be null or empty. - * @param sdk_url An optional SKD URL. Can be null or empty. - * @param attributes The list of allowed attributes. Can be null or empty. - * @param layoutAttributes The list of layout attributes. Can be null or empty. - * @param children The list of allowed children. Can be null or empty. - * @param mandatory Whether this node must always exist (even for empty models). A mandatory - * UI node is never deleted and it may lack an actual XML node attached. A non-mandatory - * UI node MUST have an XML node attached and it will cease to exist when the XML node - * ceases to exist. - */ - public ViewElementDescriptor(String xml_name, String ui_name, - String fullClassName, - String tooltip, String sdk_url, - AttributeDescriptor[] attributes, AttributeDescriptor[] layoutAttributes, - ElementDescriptor[] children, boolean mandatory) { - super(xml_name, ui_name, tooltip, sdk_url, attributes, children, mandatory); - mFullClassName = fullClassName; - mLayoutAttributes = layoutAttributes != null ? layoutAttributes : new AttributeDescriptor[0]; - } - - /** - * Constructs a new {@link ElementDescriptor} based on its XML name and on the canonical - * name of the class it represents. - * The UI name is build by capitalizing the XML name. - * The UI nodes will be non-mandatory. - * - * @param xml_name The XML element node name. Case sensitive. - * @param fullClassName The fully qualified class name the {@link ViewElementDescriptor} is - * representing. - */ - public ViewElementDescriptor(String xml_name, String fullClassName) { - super(xml_name); - mFullClassName = fullClassName; - mLayoutAttributes = null; - } - - /** - * Returns the fully qualified name of the View class represented by this element descriptor - * e.g. "android.view.View". - * - * @return the fully qualified class name, never null - */ - public String getFullClassName() { - return mFullClassName; - } - - /** Returns the list of layout attributes. Can be empty but not null. - * - * @return the list of layout attributes, never null - */ - public AttributeDescriptor[] getLayoutAttributes() { - return mLayoutAttributes; - } - - /** - * Sets the list of layout attribute attributes. - * - * @param attributes the new layout attributes, not null - */ - public void setLayoutAttributes(AttributeDescriptor[] attributes) { - assert attributes != null; - mLayoutAttributes = attributes; - } - - /** - * Returns a new {@link UiViewElementNode} linked to this descriptor. - */ - @Override - public UiElementNode createUiNode() { - return new UiViewElementNode(this); - } - - /** - * Returns the {@link ViewElementDescriptor} of the super-class of this View descriptor - * that matches the java View hierarchy. Can be null. - * - * @return the super class' descriptor or null - */ - public ViewElementDescriptor getSuperClassDesc() { - return mSuperClassDesc; - } - - /** - * Sets the {@link ViewElementDescriptor} of the super-class of this View descriptor - * that matches the java View hierarchy. Can be null. - * - * @param superClassDesc the descriptor for the super class, or null - */ - public void setSuperClass(ViewElementDescriptor superClassDesc) { - mSuperClassDesc = superClassDesc; - } - - /** - * Returns an optional icon for the element. - * <p/> - * By default this tries to return an icon based on the XML name of the element. - * If this fails, it tries to return the default element icon as defined in the - * plugin. If all fails, it returns null. - * - * @return An icon for this element or null. - */ - @Override - public Image getGenericIcon() { - IconFactory factory = IconFactory.getInstance(); - String name = mXmlName; - if (name.indexOf('.') != -1) { - // If the user uses a fully qualified name, such as - // "android.gesture.GestureOverlayView" in their XML, we need to look up - // only by basename - name = name.substring(name.lastIndexOf('.') + 1); - } else if (VIEW_TAG.equals(name)) { - // Can't have both view.png and View.png; issues on case sensitive vs - // case insensitive file systems - name = VIEW; - } - - Image icon = factory.getIcon(name); - if (icon == null) { - icon = AdtPlugin.getAndroidLogo(); - } - - return icon; - } - - /** - * Returns the list of attribute sources for the attributes provided by this - * descriptor. An attribute source is the fully qualified class name of the - * defining class for some of the properties. The specific attribute source - * of a given {@link AttributeInfo} can be found by calling - * {@link AttributeInfo#getDefinedBy()}. - * <p> - * The attribute sources are ordered from class to super class. - * <p> - * The list may <b>not</b> be modified by clients. - * - * @return a non null list of attribute sources for this view - */ - public List<String> getAttributeSources() { - return mAttributeSources != null ? mAttributeSources : Collections.<String>emptyList(); - } - - /** - * Sets the attribute sources for this view. See {@link #getAttributes()} - * for details. - * - * @param attributeSources a non null list of attribute sources for this - * view descriptor - * @see #getAttributeSources() - */ - public void setAttributeSources(List<String> attributeSources) { - mAttributeSources = attributeSources; - } - - /** - * Returns true if views with the given fully qualified class name need to include - * their package in the layout XML tag - * - * @param fqcn the fully qualified class name, such as android.widget.Button - * @return true if the full package path should be included in the layout XML element - * tag - */ - public static boolean viewNeedsPackage(String fqcn) { - return !(fqcn.startsWith(ANDROID_WIDGET_PREFIX) - || fqcn.startsWith(ANDROID_VIEW_PKG) - || fqcn.startsWith(ANDROID_WEBKIT_PKG)); - } -} |