| /* |
| * Copyright (C) 2007 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.sdk; |
| |
| import com.android.annotations.NonNull; |
| import com.android.annotations.Nullable; |
| import com.android.ide.common.rendering.LayoutLibrary; |
| import com.android.ide.common.rendering.api.LayoutLog; |
| import com.android.ide.common.resources.ResourceRepository; |
| import com.android.ide.common.resources.platform.AttributeInfo; |
| import com.android.ide.common.sdk.LoadStatus; |
| import com.android.ide.eclipse.adt.AdtPlugin; |
| import com.android.ide.eclipse.adt.internal.editors.animator.AnimDescriptors; |
| import com.android.ide.eclipse.adt.internal.editors.animator.AnimatorDescriptors; |
| import com.android.ide.eclipse.adt.internal.editors.color.ColorDescriptors; |
| import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider; |
| import com.android.ide.eclipse.adt.internal.editors.drawable.DrawableDescriptors; |
| import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors; |
| import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors; |
| import com.android.ide.eclipse.adt.internal.editors.menu.descriptors.MenuDescriptors; |
| import com.android.ide.eclipse.adt.internal.editors.otherxml.descriptors.OtherXmlDescriptors; |
| import com.android.ide.eclipse.adt.internal.editors.values.descriptors.ValuesDescriptors; |
| import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources; |
| import com.android.sdklib.IAndroidTarget; |
| import com.android.sdklib.IAndroidTarget.IOptionalLibrary; |
| |
| import org.eclipse.core.runtime.IStatus; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.Hashtable; |
| import java.util.Map; |
| |
| /** |
| * This class contains the data of an Android Target as loaded from the SDK. |
| */ |
| public class AndroidTargetData { |
| |
| public final static int DESCRIPTOR_MANIFEST = 1; |
| public final static int DESCRIPTOR_LAYOUT = 2; |
| public final static int DESCRIPTOR_MENU = 3; |
| public final static int DESCRIPTOR_OTHER_XML = 4; |
| public final static int DESCRIPTOR_RESOURCES = 5; |
| public final static int DESCRIPTOR_SEARCHABLE = 6; |
| public final static int DESCRIPTOR_PREFERENCES = 7; |
| public final static int DESCRIPTOR_APPWIDGET_PROVIDER = 8; |
| public final static int DESCRIPTOR_DRAWABLE = 9; |
| public final static int DESCRIPTOR_ANIMATOR = 10; |
| public final static int DESCRIPTOR_ANIM = 11; |
| public final static int DESCRIPTOR_COLOR = 12; |
| |
| private final IAndroidTarget mTarget; |
| |
| /** |
| * mAttributeValues is a map { key => list [ values ] }. |
| * The key for the map is "(element-xml-name,attribute-namespace:attribute-xml-local-name)". |
| * The attribute namespace prefix must be: |
| * - "android" for SdkConstants.NS_RESOURCES |
| * - "xmlns" for the XMLNS URI. |
| * |
| * This is used for attributes that do not have a unique name, but still need to be populated |
| * with values in the UI. Uniquely named attributes have their values in {@link #mEnumValueMap}. |
| */ |
| private Hashtable<String, String[]> mAttributeValues = new Hashtable<String, String[]>(); |
| |
| private AndroidManifestDescriptors mManifestDescriptors; |
| private DrawableDescriptors mDrawableDescriptors; |
| private AnimatorDescriptors mAnimatorDescriptors; |
| private AnimDescriptors mAnimDescriptors; |
| private ColorDescriptors mColorDescriptors; |
| private LayoutDescriptors mLayoutDescriptors; |
| private MenuDescriptors mMenuDescriptors; |
| private OtherXmlDescriptors mOtherXmlDescriptors; |
| |
| private Map<String, Map<String, Integer>> mEnumValueMap; |
| |
| private ResourceRepository mFrameworkResources; |
| private LayoutLibrary mLayoutLibrary; |
| private Map<String, AttributeInfo> mAttributeMap; |
| |
| private boolean mLayoutBridgeInit = false; |
| |
| AndroidTargetData(IAndroidTarget androidTarget) { |
| mTarget = androidTarget; |
| } |
| |
| /** |
| * Sets the associated map from string attribute name to |
| * {@link AttributeInfo} |
| * |
| * @param attributeMap the map |
| */ |
| public void setAttributeMap(@NonNull Map<String, AttributeInfo> attributeMap) { |
| mAttributeMap = attributeMap; |
| } |
| |
| /** |
| * Returns the associated map from string attribute name to |
| * {@link AttributeInfo} |
| * |
| * @return the map |
| */ |
| @Nullable |
| public Map<String, AttributeInfo> getAttributeMap() { |
| return mAttributeMap; |
| } |
| |
| /** |
| * Creates an AndroidTargetData object. |
| */ |
| void setExtraData( |
| AndroidManifestDescriptors manifestDescriptors, |
| LayoutDescriptors layoutDescriptors, |
| MenuDescriptors menuDescriptors, |
| OtherXmlDescriptors otherXmlDescriptors, |
| DrawableDescriptors drawableDescriptors, |
| AnimatorDescriptors animatorDescriptors, |
| AnimDescriptors animDescriptors, |
| ColorDescriptors colorDescriptors, |
| Map<String, Map<String, Integer>> enumValueMap, |
| String[] permissionValues, |
| String[] activityIntentActionValues, |
| String[] broadcastIntentActionValues, |
| String[] serviceIntentActionValues, |
| String[] intentCategoryValues, |
| String[] platformLibraries, |
| IOptionalLibrary[] optionalLibraries, |
| ResourceRepository frameworkResources, |
| LayoutLibrary layoutLibrary) { |
| |
| mManifestDescriptors = manifestDescriptors; |
| mDrawableDescriptors = drawableDescriptors; |
| mAnimatorDescriptors = animatorDescriptors; |
| mAnimDescriptors = animDescriptors; |
| mColorDescriptors = colorDescriptors; |
| mLayoutDescriptors = layoutDescriptors; |
| mMenuDescriptors = menuDescriptors; |
| mOtherXmlDescriptors = otherXmlDescriptors; |
| mEnumValueMap = enumValueMap; |
| mFrameworkResources = frameworkResources; |
| mLayoutLibrary = layoutLibrary; |
| |
| setPermissions(permissionValues); |
| setIntentFilterActionsAndCategories(activityIntentActionValues, broadcastIntentActionValues, |
| serviceIntentActionValues, intentCategoryValues); |
| setOptionalLibraries(platformLibraries, optionalLibraries); |
| } |
| |
| /** |
| * Returns an {@link IDescriptorProvider} from a given Id. |
| * The Id can be one of {@link #DESCRIPTOR_MANIFEST}, {@link #DESCRIPTOR_LAYOUT}, |
| * {@link #DESCRIPTOR_MENU}, or {@link #DESCRIPTOR_OTHER_XML}. |
| * All other values will throw an {@link IllegalArgumentException}. |
| */ |
| public IDescriptorProvider getDescriptorProvider(int descriptorId) { |
| switch (descriptorId) { |
| case DESCRIPTOR_MANIFEST: |
| return mManifestDescriptors; |
| case DESCRIPTOR_LAYOUT: |
| return mLayoutDescriptors; |
| case DESCRIPTOR_MENU: |
| return mMenuDescriptors; |
| case DESCRIPTOR_OTHER_XML: |
| return mOtherXmlDescriptors; |
| case DESCRIPTOR_RESOURCES: |
| // FIXME: since it's hard-coded the Resources Descriptors are not platform dependent. |
| return ValuesDescriptors.getInstance(); |
| case DESCRIPTOR_PREFERENCES: |
| return mOtherXmlDescriptors.getPreferencesProvider(); |
| case DESCRIPTOR_APPWIDGET_PROVIDER: |
| return mOtherXmlDescriptors.getAppWidgetProvider(); |
| case DESCRIPTOR_SEARCHABLE: |
| return mOtherXmlDescriptors.getSearchableProvider(); |
| case DESCRIPTOR_DRAWABLE: |
| return mDrawableDescriptors; |
| case DESCRIPTOR_ANIMATOR: |
| return mAnimatorDescriptors; |
| case DESCRIPTOR_ANIM: |
| return mAnimDescriptors; |
| case DESCRIPTOR_COLOR: |
| return mColorDescriptors; |
| default : |
| throw new IllegalArgumentException(); |
| } |
| } |
| |
| /** |
| * Returns the manifest descriptors. |
| */ |
| public AndroidManifestDescriptors getManifestDescriptors() { |
| return mManifestDescriptors; |
| } |
| |
| /** |
| * Returns the drawable descriptors |
| */ |
| public DrawableDescriptors getDrawableDescriptors() { |
| return mDrawableDescriptors; |
| } |
| |
| /** |
| * Returns the animation descriptors |
| */ |
| public AnimDescriptors getAnimDescriptors() { |
| return mAnimDescriptors; |
| } |
| |
| /** |
| * Returns the color descriptors |
| */ |
| public ColorDescriptors getColorDescriptors() { |
| return mColorDescriptors; |
| } |
| |
| /** |
| * Returns the animator descriptors |
| */ |
| public AnimatorDescriptors getAnimatorDescriptors() { |
| return mAnimatorDescriptors; |
| } |
| |
| /** |
| * Returns the layout Descriptors. |
| */ |
| public LayoutDescriptors getLayoutDescriptors() { |
| return mLayoutDescriptors; |
| } |
| |
| /** |
| * Returns the menu descriptors. |
| */ |
| public MenuDescriptors getMenuDescriptors() { |
| return mMenuDescriptors; |
| } |
| |
| /** |
| * Returns the XML descriptors |
| */ |
| public OtherXmlDescriptors getXmlDescriptors() { |
| return mOtherXmlDescriptors; |
| } |
| |
| /** |
| * Returns this list of possible values for an XML attribute. |
| * <p/>This should only be called for attributes for which possible values depend on the |
| * parent element node. |
| * <p/>For attributes that have the same values no matter the parent node, use |
| * {@link #getEnumValueMap()}. |
| * @param elementName the name of the element containing the attribute. |
| * @param attributeName the name of the attribute |
| * @return an array of String with the possible values, or <code>null</code> if no values were |
| * found. |
| */ |
| public String[] getAttributeValues(String elementName, String attributeName) { |
| String key = String.format("(%1$s,%2$s)", elementName, attributeName); //$NON-NLS-1$ |
| return mAttributeValues.get(key); |
| } |
| |
| /** |
| * Returns this list of possible values for an XML attribute. |
| * <p/>This should only be called for attributes for which possible values depend on the |
| * parent and great-grand-parent element node. |
| * <p/>The typical example of this is for the 'name' attribute under |
| * activity/intent-filter/action |
| * <p/>For attributes that have the same values no matter the parent node, use |
| * {@link #getEnumValueMap()}. |
| * @param elementName the name of the element containing the attribute. |
| * @param attributeName the name of the attribute |
| * @param greatGrandParentElementName the great-grand-parent node. |
| * @return an array of String with the possible values, or <code>null</code> if no values were |
| * found. |
| */ |
| public String[] getAttributeValues(String elementName, String attributeName, |
| String greatGrandParentElementName) { |
| if (greatGrandParentElementName != null) { |
| String key = String.format("(%1$s,%2$s,%3$s)", //$NON-NLS-1$ |
| greatGrandParentElementName, elementName, attributeName); |
| String[] values = mAttributeValues.get(key); |
| if (values != null) { |
| return values; |
| } |
| } |
| |
| return getAttributeValues(elementName, attributeName); |
| } |
| |
| /** |
| * Returns the enum values map. |
| * <p/>The map defines the possible values for XML attributes. The key is the attribute name |
| * and the value is a map of (string, integer) in which the key (string) is the name of |
| * the value, and the Integer is the numerical value in the compiled binary XML files. |
| */ |
| public Map<String, Map<String, Integer>> getEnumValueMap() { |
| return mEnumValueMap; |
| } |
| |
| /** |
| * Returns the {@link ProjectResources} containing the Framework Resources. |
| */ |
| public ResourceRepository getFrameworkResources() { |
| return mFrameworkResources; |
| } |
| |
| /** |
| * Returns a {@link LayoutLibrary} object possibly containing a {@link LayoutBridge} object. |
| * <p/>If {@link LayoutLibrary#getBridge()} is <code>null</code>, |
| * {@link LayoutBridge#getStatus()} will contain the reason (either {@link LoadStatus#LOADING} |
| * or {@link LoadStatus#FAILED}). |
| * <p/>Valid {@link LayoutBridge} objects are always initialized before being returned. |
| */ |
| public synchronized LayoutLibrary getLayoutLibrary() { |
| if (mLayoutBridgeInit == false && mLayoutLibrary.getStatus() == LoadStatus.LOADED) { |
| boolean ok = mLayoutLibrary.init( |
| mTarget.getProperties(), |
| new File(mTarget.getPath(IAndroidTarget.FONTS)), |
| getEnumValueMap(), |
| new LayoutLog() { |
| |
| @Override |
| public void error(String tag, String message, Throwable throwable, |
| Object data) { |
| AdtPlugin.log(throwable, message); |
| } |
| |
| @Override |
| public void error(String tag, String message, Object data) { |
| AdtPlugin.log(IStatus.ERROR, message); |
| } |
| |
| @Override |
| public void warning(String tag, String message, Object data) { |
| AdtPlugin.log(IStatus.WARNING, message); |
| } |
| }); |
| if (!ok) { |
| AdtPlugin.log(IStatus.ERROR, |
| "LayoutLibrary initialization failed"); |
| } |
| mLayoutBridgeInit = true; |
| } |
| |
| return mLayoutLibrary; |
| } |
| |
| /** |
| * Sets the permission values |
| * @param permissionValues the list of permissions |
| */ |
| private void setPermissions(String[] permissionValues) { |
| setValues("(uses-permission,android:name)", permissionValues); //$NON-NLS-1$ |
| setValues("(application,android:permission)", permissionValues); //$NON-NLS-1$ |
| setValues("(activity,android:permission)", permissionValues); //$NON-NLS-1$ |
| setValues("(receiver,android:permission)", permissionValues); //$NON-NLS-1$ |
| setValues("(service,android:permission)", permissionValues); //$NON-NLS-1$ |
| setValues("(provider,android:permission)", permissionValues); //$NON-NLS-1$ |
| } |
| |
| private void setIntentFilterActionsAndCategories(String[] activityIntentActions, |
| String[] broadcastIntentActions, String[] serviceIntentActions, |
| String[] intentCategoryValues) { |
| setValues("(activity,action,android:name)", activityIntentActions); //$NON-NLS-1$ |
| setValues("(receiver,action,android:name)", broadcastIntentActions); //$NON-NLS-1$ |
| setValues("(service,action,android:name)", serviceIntentActions); //$NON-NLS-1$ |
| setValues("(category,android:name)", intentCategoryValues); //$NON-NLS-1$ |
| } |
| |
| private void setOptionalLibraries(String[] platformLibraries, |
| IOptionalLibrary[] optionalLibraries) { |
| |
| ArrayList<String> libs = new ArrayList<String>(); |
| |
| if (platformLibraries != null) { |
| for (String name : platformLibraries) { |
| libs.add(name); |
| } |
| } |
| |
| if (optionalLibraries != null) { |
| for (int i = 0; i < optionalLibraries.length; i++) { |
| libs.add(optionalLibraries[i].getName()); |
| } |
| } |
| setValues("(uses-library,android:name)", libs.toArray(new String[libs.size()])); |
| } |
| |
| /** |
| * Sets a (name, values) pair in the hash map. |
| * <p/> |
| * If the name is already present in the map, it is first removed. |
| * @param name the name associated with the values. |
| * @param values The values to add. |
| */ |
| private void setValues(String name, String[] values) { |
| mAttributeValues.remove(name); |
| mAttributeValues.put(name, values); |
| } |
| |
| public void dispose() { |
| if (mLayoutLibrary != null) { |
| mLayoutLibrary.dispose(); |
| } |
| } |
| } |