diff options
author | Siva Velusamy <vsiva@google.com> | 2012-09-18 14:51:46 -0700 |
---|---|---|
committer | Siva Velusamy <vsiva@google.com> | 2012-09-18 15:09:33 -0700 |
commit | 6837aad30d6c51783ca1dc784ca6bdcc8a3d9f2d (patch) | |
tree | 90af15ddcc9f0bbc3151a0978b3e637f77fdd54a /ide_common/src/com/android/ide/common/resources | |
parent | 6184f12fa097e1c5bddfe50700b3b0740c736a5a (diff) | |
download | sdk-6837aad30d6c51783ca1dc784ca6bdcc8a3d9f2d.zip sdk-6837aad30d6c51783ca1dc784ca6bdcc8a3d9f2d.tar.gz sdk-6837aad30d6c51783ca1dc784ca6bdcc8a3d9f2d.tar.bz2 |
Rename ide_common to sdk_common
Change-Id: I1b39ee439a532f3f6758be35b569948e2e906665
Diffstat (limited to 'ide_common/src/com/android/ide/common/resources')
41 files changed, 0 insertions, 7316 deletions
diff --git a/ide_common/src/com/android/ide/common/resources/FrameworkResourceItem.java b/ide_common/src/com/android/ide/common/resources/FrameworkResourceItem.java deleted file mode 100644 index 70bbcef..0000000 --- a/ide_common/src/com/android/ide/common/resources/FrameworkResourceItem.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources; - -/** - * A custom {@link ResourceItem} for resources provided by the framework. - * - * The main change is that {@link #isEditableDirectly()} returns false. - */ -class FrameworkResourceItem extends ResourceItem { - - FrameworkResourceItem(String name) { - super(name); - } - - @Override - public boolean isEditableDirectly() { - return false; - } - - @Override - public String toString() { - return "FrameworkResourceItem [mName=" + getName() + ", mFiles=" //$NON-NLS-1$ //$NON-NLS-2$ - + getSourceFileList() + "]"; //$NON-NLS-1$ - } -} diff --git a/ide_common/src/com/android/ide/common/resources/FrameworkResources.java b/ide_common/src/com/android/ide/common/resources/FrameworkResources.java deleted file mode 100755 index fbf5926..0000000 --- a/ide_common/src/com/android/ide/common/resources/FrameworkResources.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources; - - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.io.IAbstractFile; -import com.android.io.IAbstractFolder; -import com.android.resources.ResourceType; -import com.android.utils.ILogger; - -import org.kxml2.io.KXmlParser; -import org.xmlpull.v1.XmlPullParser; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; - -/** - * Framework resources repository. - * - * This behaves the same as {@link ResourceRepository} except that it differentiates between - * resources that are public and non public. - * {@link #getResources(ResourceType)} and {@link #hasResourcesOfType(ResourceType)} only return - * public resources. This is typically used to display resource lists in the UI. - * - * {@link #getConfiguredResources(com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration)} - * returns all resources, even the non public ones so that this can be used for rendering. - */ -public class FrameworkResources extends ResourceRepository { - - /** - * Map of {@link ResourceType} to list of items. It is guaranteed to contain a list for all - * possible values of ResourceType. - */ - protected final Map<ResourceType, List<ResourceItem>> mPublicResourceMap = - new EnumMap<ResourceType, List<ResourceItem>>(ResourceType.class); - - public FrameworkResources() { - super(true /*isFrameworkRepository*/); - } - - /** - * Returns a {@link Collection} (always non null, but can be empty) of <b>public</b> - * {@link ResourceItem} matching a given {@link ResourceType}. - * - * @param type the type of the resources to return - * @return a collection of items, possible empty. - */ - @Override - @NonNull - public List<ResourceItem> getResourceItemsOfType(@NonNull ResourceType type) { - return mPublicResourceMap.get(type); - } - - /** - * Returns whether the repository has <b>public</b> resources of a given {@link ResourceType}. - * @param type the type of resource to check. - * @return true if the repository contains resources of the given type, false otherwise. - */ - @Override - public boolean hasResourcesOfType(@NonNull ResourceType type) { - return mPublicResourceMap.get(type).size() > 0; - } - - @Override - @NonNull - protected ResourceItem createResourceItem(@NonNull String name) { - return new FrameworkResourceItem(name); - } - - /** - * Reads the public.xml file in data/res/values/ for a given resource folder and builds up - * a map of public resources. - * - * This map is a subset of the full resource map that only contains framework resources - * that are public. - * - * @param resFolder The root folder of the resources - * @param logger a logger to report issues to - */ - public void loadPublicResources(@NonNull IAbstractFolder resFolder, @Nullable ILogger logger) { - IAbstractFolder valueFolder = resFolder.getFolder(SdkConstants.FD_RES_VALUES); - if (valueFolder.exists() == false) { - return; - } - - IAbstractFile publicXmlFile = valueFolder.getFile("public.xml"); //$NON-NLS-1$ - if (publicXmlFile.exists()) { - Reader reader = null; - try { - reader = new BufferedReader(new InputStreamReader(publicXmlFile.getContents(), - "UTF-8")); //$NON-NLS-1$ - KXmlParser parser = new KXmlParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); - parser.setInput(reader); - - ResourceType lastType = null; - String lastTypeName = ""; - while (true) { - int event = parser.next(); - if (event == XmlPullParser.START_TAG) { - // As of API 15 there are a number of "java-symbol" entries here - if (!parser.getName().equals("public")) { //$NON-NLS-1$ - continue; - } - - String name = null; - String typeName = null; - for (int i = 0, n = parser.getAttributeCount(); i < n; i++) { - String attribute = parser.getAttributeName(i); - - if (attribute.equals("name")) { //$NON-NLS-1$ - name = parser.getAttributeValue(i); - if (typeName != null) { - // Skip id attribute processing - break; - } - } else if (attribute.equals("type")) { //$NON-NLS-1$ - typeName = parser.getAttributeValue(i); - } - } - - if (name != null && typeName != null) { - ResourceType type = null; - if (typeName.equals(lastTypeName)) { - type = lastType; - } else { - type = ResourceType.getEnum(typeName); - lastType = type; - lastTypeName = typeName; - } - if (type != null) { - ResourceItem match = null; - Map<String, ResourceItem> map = mResourceMap.get(type); - if (map != null) { - match = map.get(name); - } - - if (match != null) { - List<ResourceItem> publicList = mPublicResourceMap.get(type); - if (publicList == null) { - // Pick initial size for the list to hold the public - // resources. We could just use map.size() here, - // but they're usually much bigger; for example, - // in one platform version, there are 1500 drawables - // and 1200 strings but only 175 and 25 public ones - // respectively. - int size; - switch (type) { - case STYLE: size = 500; break; - case ATTR: size = 1000; break; - case DRAWABLE: size = 200; break; - case ID: size = 50; break; - case LAYOUT: - case COLOR: - case STRING: - case ANIM: - case INTERPOLATOR: - size = 30; - break; - default: - size = 10; - break; - } - publicList = new ArrayList<ResourceItem>(size); - mPublicResourceMap.put(type, publicList); - } - - publicList.add(match); - } else { - // log that there's a public resource that doesn't actually - // exist? - } - } else { - // log that there was a reference to a typo that doesn't actually - // exist? - } - } - } else if (event == XmlPullParser.END_DOCUMENT) { - break; - } - } - } catch (Exception e) { - if (logger != null) { - logger.error(e, "Can't read and parse public attribute list"); - } - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException e) { - // Nothing to be done here - we don't care if it closed or not. - } - } - } - } - - // put unmodifiable list for all res type in the public resource map - // this will simplify access - for (ResourceType type : ResourceType.values()) { - List<ResourceItem> list = mPublicResourceMap.get(type); - if (list == null) { - list = Collections.emptyList(); - } else { - list = Collections.unmodifiableList(list); - } - - // put the new list in the map - mPublicResourceMap.put(type, list); - } - } -} - diff --git a/ide_common/src/com/android/ide/common/resources/IdGeneratingResourceFile.java b/ide_common/src/com/android/ide/common/resources/IdGeneratingResourceFile.java deleted file mode 100644 index 9ff1748..0000000 --- a/ide_common/src/com/android/ide/common/resources/IdGeneratingResourceFile.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources; - -import com.android.ide.common.rendering.api.DensityBasedResourceValue; -import com.android.ide.common.rendering.api.ResourceValue; -import com.android.ide.common.resources.ValueResourceParser.IValueResourceRepository; -import com.android.ide.common.resources.configuration.DensityQualifier; -import com.android.io.IAbstractFile; -import com.android.io.StreamException; -import com.android.resources.ResourceType; - -import java.io.IOException; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * Represents a resource file that also generates ID resources. - * <p/> - * This is typically an XML file in res/layout or res/menu - */ -public final class IdGeneratingResourceFile extends ResourceFile - implements IValueResourceRepository { - - private final Map<String, ResourceValue> mIdResources = - new HashMap<String, ResourceValue>(); - - private final Collection<ResourceType> mResourceTypeList; - - private final String mFileName; - - private final ResourceType mFileType; - - private final ResourceValue mFileValue; - - public IdGeneratingResourceFile(IAbstractFile file, ResourceFolder folder, ResourceType type) { - super(file, folder); - - mFileType = type; - - // Set up our resource types - mResourceTypeList = new HashSet<ResourceType>(); - mResourceTypeList.add(mFileType); - mResourceTypeList.add(ResourceType.ID); - - // compute the resource name - mFileName = getFileName(type); - - // Get the resource value of this file as a whole layout - mFileValue = getFileValue(file, folder); - } - - @Override - protected void load(ScanningContext context) { - // Parse the file and look for @+id/ entries - parseFileForIds(context); - - // create the resource items in the repository - updateResourceItems(context); - } - - @Override - protected void update(ScanningContext context) { - // Copy the previous list of ID names - Set<String> oldIdNames = new HashSet<String>(mIdResources.keySet()); - - // reset current content. - mIdResources.clear(); - - // need to parse the file and find the IDs. - if (!parseFileForIds(context)) { - context.requestFullAapt(); - // Continue through to updating the resource item here since it - // will make for example layout rendering more accurate until - // aapt is re-run - } - - // We only need to update the repository if our IDs have changed - Set<String> keySet = mIdResources.keySet(); - assert keySet != oldIdNames; - if (oldIdNames.equals(keySet) == false) { - updateResourceItems(context); - } - } - - @Override - protected void dispose(ScanningContext context) { - ResourceRepository repository = getRepository(); - - // Remove declarations from this file from the repository - repository.removeFile(mResourceTypeList, this); - - // Ask for an ID refresh since we'll be taking away ID generating items - context.requestFullAapt(); - } - - @Override - public Collection<ResourceType> getResourceTypes() { - return mResourceTypeList; - } - - @Override - public boolean hasResources(ResourceType type) { - return (type == mFileType) || (type == ResourceType.ID && !mIdResources.isEmpty()); - } - - @Override - public ResourceValue getValue(ResourceType type, String name) { - // Check to see if they're asking for one of the right types: - if (type != mFileType && type != ResourceType.ID) { - return null; - } - - // If they're looking for a resource of this type with this name give them the whole file - if (type == mFileType && name.equals(mFileName)) { - return mFileValue; - } else { - // Otherwise try to return them an ID - // the map will return null if it's not found - return mIdResources.get(name); - } - } - - /** - * Looks through the file represented for Ids and adds them to - * our id repository - * - * @return true if parsing succeeds and false if it fails - */ - private boolean parseFileForIds(ScanningContext context) { - IdResourceParser parser = new IdResourceParser(this, context, isFramework()); - try { - IAbstractFile file = getFile(); - return parser.parse(mFileType, file.getOsLocation(), file.getContents()); - } catch (IOException e) { - // Pass - } catch (StreamException e) { - // Pass - } - - return false; - } - - /** - * Add the resources represented by this file to the repository - */ - private void updateResourceItems(ScanningContext context) { - ResourceRepository repository = getRepository(); - - // remove this file from all existing ResourceItem. - repository.removeFile(mResourceTypeList, this); - - // First add this as a layout file - ResourceItem item = repository.getResourceItem(mFileType, mFileName); - item.add(this); - - // Now iterate through our IDs and add - for (String idName : mIdResources.keySet()) { - item = repository.getResourceItem(ResourceType.ID, idName); - // add this file to the list of files generating ID resources. - item.add(this); - } - - // Ask the repository for an ID refresh - context.requestFullAapt(); - } - - /** - * Returns the resource value associated with this whole file as a layout resource - * @param file the file handler that represents this file - * @param folder the folder this file is under - * @return a resource value associated with this layout - */ - private ResourceValue getFileValue(IAbstractFile file, ResourceFolder folder) { - // test if there's a density qualifier associated with the resource - DensityQualifier qualifier = folder.getConfiguration().getDensityQualifier(); - - ResourceValue value; - if (qualifier == null) { - value = new ResourceValue(mFileType, mFileName, - file.getOsLocation(), isFramework()); - } else { - value = new DensityBasedResourceValue( - mFileType, mFileName, - file.getOsLocation(), - qualifier.getValue(), - isFramework()); - } - return value; - } - - - /** - * Returns the name of this resource. - */ - private String getFileName(ResourceType type) { - // get the name from the filename. - String name = getFile().getName(); - - int pos = name.indexOf('.'); - if (pos != -1) { - name = name.substring(0, pos); - } - - return name; - } - - @Override - public void addResourceValue(ResourceValue value) { - // Just overwrite collisions. We're only interested in the unique - // IDs declared - mIdResources.put(value.getName(), value); - } - - @Override - public boolean hasResourceValue(ResourceType type, String name) { - if (type == ResourceType.ID) { - return mIdResources.containsKey(name); - } - - return false; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/IdResourceParser.java b/ide_common/src/com/android/ide/common/resources/IdResourceParser.java deleted file mode 100644 index 1de664e..0000000 --- a/ide_common/src/com/android/ide/common/resources/IdResourceParser.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources; - -import com.android.ide.common.rendering.api.ResourceValue; -import com.android.ide.common.resources.ValueResourceParser.IValueResourceRepository; -import com.android.resources.ResourceType; - -import org.kxml2.io.KXmlParser; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.BufferedInputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * Parser for scanning an id-generating resource file such as a layout or a menu - * file, which registers any ids it encounters with an - * {@link IValueResourceRepository}, and which registers errors with a - * {@link ScanningContext}. - */ -public class IdResourceParser { - private final IValueResourceRepository mRepository; - private final boolean mIsFramework; - private ScanningContext mContext; - - /** - * Creates a new {@link IdResourceParser} - * - * @param repository value repository for registering resource declaration - * @param context a context object with state for the current update, such - * as a place to stash errors encountered - * @param isFramework true if scanning a framework resource - */ - public IdResourceParser(IValueResourceRepository repository, ScanningContext context, - boolean isFramework) { - mRepository = repository; - mContext = context; - mIsFramework = isFramework; - } - - /** - * Parse the given input and register ids with the given - * {@link IValueResourceRepository}. - * - * @param type the type of resource being scanned - * @param path the full OS path to the file being parsed - * @param input the input stream of the XML to be parsed - * @return true if parsing succeeds and false if it fails - * @throws IOException if reading the contents fails - */ - public boolean parse(ResourceType type, final String path, InputStream input) - throws IOException { - KXmlParser parser = new KXmlParser(); - try { - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - - if (input instanceof FileInputStream) { - input = new BufferedInputStream(input); - } - parser.setInput(input, "UTF-8"); //$NON-NLS-1$ - - return parse(type, path, parser); - } catch (XmlPullParserException e) { - String message = e.getMessage(); - - // Strip off position description - int index = message.indexOf("(position:"); //$NON-NLS-1$ (Hardcoded in KXml) - if (index != -1) { - message = message.substring(0, index); - } - - String error = String.format("%1$s:%2$d: Error: %3$s", //$NON-NLS-1$ - path, parser.getLineNumber(), message); - mContext.addError(error); - return false; - } catch (RuntimeException e) { - // Some exceptions are thrown by the KXmlParser that are not XmlPullParserExceptions, - // such as this one: - // java.lang.RuntimeException: Undefined Prefix: w in org.kxml2.io.KXmlParser@... - // at org.kxml2.io.KXmlParser.adjustNsp(Unknown Source) - // at org.kxml2.io.KXmlParser.parseStartTag(Unknown Source) - String message = e.getMessage(); - String error = String.format("%1$s:%2$d: Error: %3$s", //$NON-NLS-1$ - path, parser.getLineNumber(), message); - mContext.addError(error); - return false; - } - } - - private boolean parse(ResourceType type, String path, KXmlParser parser) - throws XmlPullParserException, IOException { - boolean valid = true; - ResourceRepository resources = mContext.getRepository(); - boolean checkForErrors = !mIsFramework && !mContext.needsFullAapt(); - - while (true) { - int event = parser.next(); - if (event == XmlPullParser.START_TAG) { - for (int i = 0, n = parser.getAttributeCount(); i < n; i++) { - String attribute = parser.getAttributeName(i); - String value = parser.getAttributeValue(i); - assert value != null : attribute; - - if (value.startsWith("@")) { //$NON-NLS-1$ - // Gather IDs - if (value.startsWith("@+")) { //$NON-NLS-1$ - // Strip out the @+id/ or @+android:id/ section - String id = value.substring(value.indexOf('/') + 1); - ResourceValue newId = new ResourceValue(ResourceType.ID, id, - mIsFramework); - mRepository.addResourceValue(newId); - } else if (checkForErrors){ - // Validate resource references (unless we're scanning a framework - // resource or if we've already scheduled a full aapt run) - boolean exists = resources.hasResourceItem(value); - if (!exists && !mRepository.hasResourceValue(ResourceType.ID, - value.substring(value.indexOf('/') + 1))) { - String error = String.format( - // Don't localize because the exact pattern matches AAPT's - // output which has hardcoded regexp matching in - // AaptParser. - "%1$s:%2$d: Error: No resource found that matches " + //$NON-NLS-1$ - "the given name (at '%3$s' with value '%4$s')", //$NON-NLS-1$ - path, parser.getLineNumber(), - attribute, value); - mContext.addError(error); - valid = false; - } - } - } - } - } else if (event == XmlPullParser.END_DOCUMENT) { - break; - } - } - - return valid; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/InlineResourceItem.java b/ide_common/src/com/android/ide/common/resources/InlineResourceItem.java deleted file mode 100644 index 37fdc81..0000000 --- a/ide_common/src/com/android/ide/common/resources/InlineResourceItem.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources; - -import com.android.ide.common.rendering.api.ResourceValue; -import com.android.ide.common.resources.configuration.FolderConfiguration; -import com.android.resources.ResourceType; - - -/** - * Represents a resource item that has been declared inline in another resource file. - * - * This covers the typical ID declaration of "@+id/foo", but does not cover normal value - * resources declared in strings.xml or other similar value files. - * - * This resource will return {@code true} for {@link #isDeclaredInline()} and {@code false} for - * {@link #isEditableDirectly()}. - */ -public class InlineResourceItem extends ResourceItem { - - private ResourceValue mValue = null; - - /** - * Constructs a new inline ResourceItem. - * @param name the name of the resource as it appears in the XML and R.java files. - */ - public InlineResourceItem(String name) { - super(name); - } - - @Override - public boolean isDeclaredInline() { - return true; - } - - @Override - public boolean isEditableDirectly() { - return false; - } - - @Override - public ResourceValue getResourceValue(ResourceType type, FolderConfiguration referenceConfig, - boolean isFramework) { - assert type == ResourceType.ID; - if (mValue == null) { - mValue = new ResourceValue(type, getName(), isFramework); - } - - return mValue; - } - - @Override - public String toString() { - return "InlineResourceItem [mName=" + getName() + ", mFiles=" //$NON-NLS-1$ //$NON-NLS-2$ - + getSourceFileList() + "]"; //$NON-NLS-1$ - } -} diff --git a/ide_common/src/com/android/ide/common/resources/IntArrayWrapper.java b/ide_common/src/com/android/ide/common/resources/IntArrayWrapper.java deleted file mode 100644 index 668c677..0000000 --- a/ide_common/src/com/android/ide/common/resources/IntArrayWrapper.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources; - -import java.util.Arrays; - - -/** - * Wrapper around a int[] to provide hashCode/equals support. - */ -public final class IntArrayWrapper { - - private int[] mData; - - public IntArrayWrapper(int[] data) { - mData = data; - } - - public void set(int[] data) { - mData = data; - } - - @Override - public int hashCode() { - return Arrays.hashCode(mData); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass().equals(obj.getClass())) { - return Arrays.equals(mData, ((IntArrayWrapper)obj).mData); - } - - return super.equals(obj); - } -} diff --git a/ide_common/src/com/android/ide/common/resources/MultiResourceFile.java b/ide_common/src/com/android/ide/common/resources/MultiResourceFile.java deleted file mode 100644 index c9a8bc7..0000000 --- a/ide_common/src/com/android/ide/common/resources/MultiResourceFile.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources; - -import com.android.ide.common.rendering.api.ResourceValue; -import com.android.ide.common.resources.ValueResourceParser.IValueResourceRepository; -import com.android.io.IAbstractFile; -import com.android.io.StreamException; -import com.android.resources.ResourceType; - -import org.xml.sax.SAXException; - -import java.io.IOException; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.Map; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -/** - * Represents a resource file able to declare multiple resources, which could be of - * different {@link ResourceType}. - * <p/> - * This is typically an XML file inside res/values. - */ -public final class MultiResourceFile extends ResourceFile implements IValueResourceRepository { - - private final static SAXParserFactory sParserFactory = SAXParserFactory.newInstance(); - - private final Map<ResourceType, Map<String, ResourceValue>> mResourceItems = - new EnumMap<ResourceType, Map<String, ResourceValue>>(ResourceType.class); - - private Collection<ResourceType> mResourceTypeList = null; - - public MultiResourceFile(IAbstractFile file, ResourceFolder folder) { - super(file, folder); - } - - // Boolean flag to track whether a named element has been added or removed, thus requiring - // a new ID table to be generated - private boolean mNeedIdRefresh; - - @Override - protected void load(ScanningContext context) { - // need to parse the file and find the content. - parseFile(); - - // create new ResourceItems for the new content. - mResourceTypeList = Collections.unmodifiableCollection(mResourceItems.keySet()); - - // We need an ID generation step - mNeedIdRefresh = true; - - // create/update the resource items. - updateResourceItems(context); - } - - @Override - protected void update(ScanningContext context) { - // Reset the ID generation flag - mNeedIdRefresh = false; - - // Copy the previous version of our list of ResourceItems and types - Map<ResourceType, Map<String, ResourceValue>> oldResourceItems - = new EnumMap<ResourceType, Map<String, ResourceValue>>(mResourceItems); - - // reset current content. - mResourceItems.clear(); - - // need to parse the file and find the content. - parseFile(); - - // create new ResourceItems for the new content. - mResourceTypeList = Collections.unmodifiableCollection(mResourceItems.keySet()); - - // Check to see if any names have changed. If so, mark the flag so updateResourceItems - // can notify the ResourceRepository that an ID refresh is needed - if (oldResourceItems.keySet().equals(mResourceItems.keySet())) { - for (ResourceType type : mResourceTypeList) { - // We just need to check the names of the items. - // If there are new or removed names then we'll have to regenerate IDs - if (mResourceItems.get(type).keySet() - .equals(oldResourceItems.get(type).keySet()) == false) { - mNeedIdRefresh = true; - } - } - } else { - // If our type list is different, obviously the names will be different - mNeedIdRefresh = true; - } - // create/update the resource items. - updateResourceItems(context); - } - - @Override - protected void dispose(ScanningContext context) { - ResourceRepository repository = getRepository(); - - // only remove this file from all existing ResourceItem. - repository.removeFile(mResourceTypeList, this); - - // We'll need an ID refresh because we deleted items - context.requestFullAapt(); - - // don't need to touch the content, it'll get reclaimed as this objects disappear. - // In the mean time other objects may need to access it. - } - - @Override - public Collection<ResourceType> getResourceTypes() { - return mResourceTypeList; - } - - @Override - public boolean hasResources(ResourceType type) { - Map<String, ResourceValue> list = mResourceItems.get(type); - return (list != null && list.size() > 0); - } - - private void updateResourceItems(ScanningContext context) { - ResourceRepository repository = getRepository(); - - // remove this file from all existing ResourceItem. - repository.removeFile(mResourceTypeList, this); - - for (ResourceType type : mResourceTypeList) { - Map<String, ResourceValue> list = mResourceItems.get(type); - - if (list != null) { - Collection<ResourceValue> values = list.values(); - for (ResourceValue res : values) { - ResourceItem item = repository.getResourceItem(type, res.getName()); - - // add this file to the list of files generating this resource item. - item.add(this); - } - } - } - - // If we need an ID refresh, ask the repository for that now - if (mNeedIdRefresh) { - context.requestFullAapt(); - } - } - - /** - * Parses the file and creates a list of {@link ResourceType}. - */ - private void parseFile() { - try { - SAXParser parser = sParserFactory.newSAXParser(); - parser.parse(getFile().getContents(), new ValueResourceParser(this, isFramework())); - } catch (ParserConfigurationException e) { - } catch (SAXException e) { - } catch (IOException e) { - } catch (StreamException e) { - } - } - - /** - * Adds a resource item to the list - * @param value The value of the resource. - */ - @Override - public void addResourceValue(ResourceValue value) { - ResourceType resType = value.getResourceType(); - - Map<String, ResourceValue> list = mResourceItems.get(resType); - - // if the list does not exist, create it. - if (list == null) { - list = new HashMap<String, ResourceValue>(); - mResourceItems.put(resType, list); - } else { - // look for a possible value already existing. - ResourceValue oldValue = list.get(value.getName()); - - if (oldValue != null) { - oldValue.replaceWith(value); - return; - } - } - - // empty list or no match found? add the given resource - list.put(value.getName(), value); - } - - @Override - public boolean hasResourceValue(ResourceType type, String name) { - Map<String, ResourceValue> map = mResourceItems.get(type); - return map != null && map.containsKey(name); - } - - @Override - public ResourceValue getValue(ResourceType type, String name) { - // get the list for the given type - Map<String, ResourceValue> list = mResourceItems.get(type); - - if (list != null) { - return list.get(name); - } - - return null; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/ResourceDeltaKind.java b/ide_common/src/com/android/ide/common/resources/ResourceDeltaKind.java deleted file mode 100644 index 769b6ea..0000000 --- a/ide_common/src/com/android/ide/common/resources/ResourceDeltaKind.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources; - -/** - * Enum indicating a type of resource change. - * - * This is similar, and can be easily mapped to Eclipse's integer constants in IResourceDelta. - */ -public enum ResourceDeltaKind { - CHANGED, ADDED, REMOVED; -} diff --git a/ide_common/src/com/android/ide/common/resources/ResourceFile.java b/ide_common/src/com/android/ide/common/resources/ResourceFile.java deleted file mode 100644 index 378602a..0000000 --- a/ide_common/src/com/android/ide/common/resources/ResourceFile.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources; - -import com.android.ide.common.rendering.api.ResourceValue; -import com.android.ide.common.resources.configuration.Configurable; -import com.android.ide.common.resources.configuration.FolderConfiguration; -import com.android.io.IAbstractFile; -import com.android.resources.ResourceType; - -import java.util.Collection; - -/** - * Represents a Resource file (a file under $Project/res/) - */ -public abstract class ResourceFile implements Configurable { - - private final IAbstractFile mFile; - private final ResourceFolder mFolder; - - protected ResourceFile(IAbstractFile file, ResourceFolder folder) { - mFile = file; - mFolder = folder; - } - - protected abstract void load(ScanningContext context); - protected abstract void update(ScanningContext context); - protected abstract void dispose(ScanningContext context); - - @Override - public FolderConfiguration getConfiguration() { - return mFolder.getConfiguration(); - } - - /** - * Returns the IFile associated with the ResourceFile. - */ - public final IAbstractFile getFile() { - return mFile; - } - - /** - * Returns the parent folder as a {@link ResourceFolder}. - */ - public final ResourceFolder getFolder() { - return mFolder; - } - - public final ResourceRepository getRepository() { - return mFolder.getRepository(); - } - - /** - * Returns whether the resource is a framework resource. - */ - public final boolean isFramework() { - return mFolder.getRepository().isFrameworkRepository(); - } - - /** - * Returns the list of {@link ResourceType} generated by the file. This is never null. - */ - public abstract Collection<ResourceType> getResourceTypes(); - - /** - * Returns whether the file generated a resource of a specific type. - * @param type The {@link ResourceType} - */ - public abstract boolean hasResources(ResourceType type); - - /** - * Returns the value of a resource generated by this file by {@link ResourceType} and name. - * <p/>If no resource match, <code>null</code> is returned. - * @param type the type of the resource. - * @param name the name of the resource. - */ - public abstract ResourceValue getValue(ResourceType type, String name); - - @Override - public String toString() { - return mFile.toString(); - } -} - diff --git a/ide_common/src/com/android/ide/common/resources/ResourceFolder.java b/ide_common/src/com/android/ide/common/resources/ResourceFolder.java deleted file mode 100644 index d6464c8..0000000 --- a/ide_common/src/com/android/ide/common/resources/ResourceFolder.java +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources; - -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.ide.common.resources.configuration.Configurable; -import com.android.ide.common.resources.configuration.FolderConfiguration; -import com.android.io.IAbstractFile; -import com.android.io.IAbstractFolder; -import com.android.resources.FolderTypeRelationship; -import com.android.resources.ResourceFolderType; -import com.android.resources.ResourceType; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Resource Folder class. Contains list of {@link ResourceFile}s, - * the {@link FolderConfiguration}, and a link to the {@link IAbstractFolder} object. - */ -public final class ResourceFolder implements Configurable { - final ResourceFolderType mType; - final FolderConfiguration mConfiguration; - IAbstractFolder mFolder; - List<ResourceFile> mFiles = null; - Map<String, ResourceFile> mNames = null; - private final ResourceRepository mRepository; - - /** - * Creates a new {@link ResourceFolder} - * @param type The type of the folder - * @param config The configuration of the folder - * @param folder The associated {@link IAbstractFolder} object. - * @param repository The associated {@link ResourceRepository} - */ - protected ResourceFolder(ResourceFolderType type, FolderConfiguration config, - IAbstractFolder folder, ResourceRepository repository) { - mType = type; - mConfiguration = config; - mFolder = folder; - mRepository = repository; - } - - /** - * Processes a file and adds it to its parent folder resource. - * - * @param file the underlying resource file. - * @param kind the file change kind. - * @param context a context object with state for the current update, such - * as a place to stash errors encountered - * @return the {@link ResourceFile} that was created. - */ - public ResourceFile processFile(IAbstractFile file, ResourceDeltaKind kind, - ScanningContext context) { - // look for this file if it's already been created - ResourceFile resFile = getFile(file, context); - - if (resFile == null) { - if (kind != ResourceDeltaKind.REMOVED) { - // create a ResourceFile for it. - - resFile = createResourceFile(file); - resFile.load(context); - - // add it to the folder - addFile(resFile); - } - } else { - if (kind == ResourceDeltaKind.REMOVED) { - removeFile(resFile, context); - } else { - resFile.update(context); - } - } - - return resFile; - } - - private ResourceFile createResourceFile(IAbstractFile file) { - // check if that's a single or multi resource type folder. For now we define this by - // the number of possible resource type output by files in the folder. - // We have a special case for layout/menu folders which can also generate IDs. - // This does - // not make the difference between several resource types from a single file or - // the ability to have 2 files in the same folder generating 2 different types of - // resource. The former is handled by MultiResourceFile properly while we don't - // handle the latter. If we were to add this behavior we'd have to change this call. - List<ResourceType> types = FolderTypeRelationship.getRelatedResourceTypes(mType); - - ResourceFile resFile = null; - if (types.size() == 1) { - resFile = new SingleResourceFile(file, this); - } else if (types.contains(ResourceType.LAYOUT)) { - resFile = new IdGeneratingResourceFile(file, this, ResourceType.LAYOUT); - } else if (types.contains(ResourceType.MENU)) { - resFile = new IdGeneratingResourceFile(file, this, ResourceType.MENU); - } else { - resFile = new MultiResourceFile(file, this); - } - return resFile; - } - - /** - * Adds a {@link ResourceFile} to the folder. - * @param file The {@link ResourceFile}. - */ - @VisibleForTesting(visibility=Visibility.PROTECTED) - public void addFile(ResourceFile file) { - if (mFiles == null) { - int initialSize = 16; - if (mRepository.isFrameworkRepository()) { - String name = mFolder.getName(); - // Pick some reasonable initial sizes for framework data structures - // since they are typically (a) large and (b) their sizes are roughly known - // in advance - switch (mType) { - case DRAWABLE: { - // See if it's one of the -mdpi, -hdpi etc folders which - // are large (~1250 items) - int index = name.indexOf('-'); - if (index == -1) { - initialSize = 230; // "drawable" folder - } else { - index = name.indexOf('-', index + 1); - if (index == -1) { - // One of the "drawable-<density>" folders - initialSize = 1260; - } else { - // "drawable-sw600dp-hdpi" etc - initialSize = 30; - } - } - break; - } - case LAYOUT: { - // The main layout folder has about ~185 layouts in it; - // the others are small - if (name.indexOf('-') == -1) { - initialSize = 200; - } - break; - } - case VALUES: { - if (name.indexOf('-') == -1) { - initialSize = 32; - } else { - initialSize = 4; - } - break; - } - case ANIM: initialSize = 85; break; - case COLOR: initialSize = 32; break; - case RAW: initialSize = 4; break; - default: - // Stick with the 16 default - break; - } - } - - mFiles = new ArrayList<ResourceFile>(initialSize); - mNames = new HashMap<String, ResourceFile>(initialSize, 2.0f); - } - - mFiles.add(file); - mNames.put(file.getFile().getName(), file); - } - - protected void removeFile(ResourceFile file, ScanningContext context) { - file.dispose(context); - mFiles.remove(file); - mNames.remove(file.getFile().getName()); - } - - protected void dispose(ScanningContext context) { - if (mFiles != null) { - for (ResourceFile file : mFiles) { - file.dispose(context); - } - - mFiles.clear(); - mNames.clear(); - } - } - - /** - * Returns the {@link IAbstractFolder} associated with this object. - */ - public IAbstractFolder getFolder() { - return mFolder; - } - - /** - * Returns the {@link ResourceFolderType} of this object. - */ - public ResourceFolderType getType() { - return mType; - } - - public ResourceRepository getRepository() { - return mRepository; - } - - /** - * Returns the list of {@link ResourceType}s generated by the files inside this folder. - */ - public Collection<ResourceType> getResourceTypes() { - ArrayList<ResourceType> list = new ArrayList<ResourceType>(); - - if (mFiles != null) { - for (ResourceFile file : mFiles) { - Collection<ResourceType> types = file.getResourceTypes(); - - // loop through those and add them to the main list, - // if they are not already present - for (ResourceType resType : types) { - if (list.indexOf(resType) == -1) { - list.add(resType); - } - } - } - } - - return list; - } - - @Override - public FolderConfiguration getConfiguration() { - return mConfiguration; - } - - /** - * Returns whether the folder contains a file with the given name. - * @param name the name of the file. - */ - public boolean hasFile(String name) { - if (mNames != null && mNames.containsKey(name)) { - return true; - } - - // Note: mNames.containsKey(name) is faster, but doesn't give the same result; this - // method seems to be called on this ResourceFolder before it has been processed, - // so we need to use the file system check instead: - return mFolder.hasFile(name); - } - - /** - * Returns the {@link ResourceFile} matching a {@link IAbstractFile} object. - * - * @param file The {@link IAbstractFile} object. - * @param context a context object with state for the current update, such - * as a place to stash errors encountered - * @return the {@link ResourceFile} or null if no match was found. - */ - private ResourceFile getFile(IAbstractFile file, ScanningContext context) { - assert mFolder.equals(file.getParentFolder()); - - if (mNames != null) { - ResourceFile resFile = mNames.get(file.getName()); - if (resFile != null) { - return resFile; - } - } - - // If the file actually exists, the resource folder may not have been - // scanned yet; add it lazily - if (file.exists()) { - ResourceFile resFile = createResourceFile(file); - resFile.load(context); - addFile(resFile); - return resFile; - } - - return null; - } - - /** - * Returns the {@link ResourceFile} matching a given name. - * @param filename The name of the file to return. - * @return the {@link ResourceFile} or <code>null</code> if no match was found. - */ - public ResourceFile getFile(String filename) { - if (mNames != null) { - ResourceFile resFile = mNames.get(filename); - if (resFile != null) { - return resFile; - } - } - - // If the file actually exists, the resource folder may not have been - // scanned yet; add it lazily - IAbstractFile file = mFolder.getFile(filename); - if (file != null && file.exists()) { - ResourceFile resFile = createResourceFile(file); - resFile.load(new ScanningContext(mRepository)); - addFile(resFile); - return resFile; - } - - return null; - } - - /** - * Returns whether a file in the folder is generating a resource of a specified type. - * @param type The {@link ResourceType} being looked up. - */ - public boolean hasResources(ResourceType type) { - // Check if the folder type is able to generate resource of the type that was asked. - // this is a first check to avoid going through the files. - List<ResourceFolderType> folderTypes = FolderTypeRelationship.getRelatedFolders(type); - - boolean valid = false; - for (ResourceFolderType rft : folderTypes) { - if (rft == mType) { - valid = true; - break; - } - } - - if (valid) { - if (mFiles != null) { - for (ResourceFile f : mFiles) { - if (f.hasResources(type)) { - return true; - } - } - } - } - return false; - } - - @Override - public String toString() { - return mFolder.toString(); - } -} diff --git a/ide_common/src/com/android/ide/common/resources/ResourceItem.java b/ide_common/src/com/android/ide/common/resources/ResourceItem.java deleted file mode 100644 index 49396eb..0000000 --- a/ide_common/src/com/android/ide/common/resources/ResourceItem.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources; - -import com.android.ide.common.rendering.api.ResourceValue; -import com.android.ide.common.resources.configuration.FolderConfiguration; -import com.android.resources.ResourceType; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -/** - * An android resource. - * - * This is a representation of the resource, not of its value(s). It gives access to all - * the source files that generate this particular resource which then can be used to access - * the actual value(s). - * - * @see ResourceFile#getResources(ResourceType, ResourceRepository) - */ -public class ResourceItem implements Comparable<ResourceItem> { - - private final static Comparator<ResourceFile> sComparator = new Comparator<ResourceFile>() { - @Override - public int compare(ResourceFile file1, ResourceFile file2) { - // get both FolderConfiguration and compare them - FolderConfiguration fc1 = file1.getFolder().getConfiguration(); - FolderConfiguration fc2 = file2.getFolder().getConfiguration(); - - return fc1.compareTo(fc2); - } - }; - - private final String mName; - - /** - * List of files generating this ResourceItem. - */ - private final List<ResourceFile> mFiles = new ArrayList<ResourceFile>(); - - /** - * Constructs a new ResourceItem. - * @param name the name of the resource as it appears in the XML and R.java files. - */ - public ResourceItem(String name) { - mName = name; - } - - /** - * Returns the name of the resource. - */ - public final String getName() { - return mName; - } - - /** - * Compares the {@link ResourceItem} to another. - * @param other the ResourceItem to be compared to. - */ - @Override - public int compareTo(ResourceItem other) { - return mName.compareTo(other.mName); - } - - /** - * Returns whether the resource is editable directly. - * <p/> - * This is typically the case for resources that don't have alternate versions, or resources - * of type {@link ResourceType#ID} that aren't declared inline. - */ - public boolean isEditableDirectly() { - return hasAlternates() == false; - } - - /** - * Returns whether the ID resource has been declared inline inside another resource XML file. - * If the resource type is not {@link ResourceType#ID}, this will always return {@code false}. - */ - public boolean isDeclaredInline() { - return false; - } - - /** - * Returns a {@link ResourceValue} for this item based on the given configuration. - * If the ResourceItem has several source files, one will be selected based on the config. - * @param type the type of the resource. This is necessary because ResourceItem doesn't embed - * its type, but ResourceValue does. - * @param referenceConfig the config of the resource item. - * @param isFramework whether the resource is a framework value. Same as the type. - * @return a ResourceValue or null if none match the config. - */ - public ResourceValue getResourceValue(ResourceType type, FolderConfiguration referenceConfig, - boolean isFramework) { - // look for the best match for the given configuration - // the match has to be of type ResourceFile since that's what the input list contains - ResourceFile match = (ResourceFile) referenceConfig.findMatchingConfigurable(mFiles); - - if (match != null) { - // get the value of this configured resource. - return match.getValue(type, mName); - } - - return null; - } - - /** - * Adds a new source file. - * @param file the source file. - */ - protected void add(ResourceFile file) { - mFiles.add(file); - } - - /** - * Removes a file from the list of source files. - * @param file the file to remove - */ - protected void removeFile(ResourceFile file) { - mFiles.remove(file); - } - - /** - * Returns {@code true} if the item has no source file. - * @return - */ - protected boolean hasNoSourceFile() { - return mFiles.size() == 0; - } - - /** - * Reset the item by emptying its source file list. - */ - protected void reset() { - mFiles.clear(); - } - - /** - * Returns the sorted list of {@link ResourceItem} objects for this resource item. - */ - public ResourceFile[] getSourceFileArray() { - ArrayList<ResourceFile> list = new ArrayList<ResourceFile>(); - list.addAll(mFiles); - - Collections.sort(list, sComparator); - - return list.toArray(new ResourceFile[list.size()]); - } - - /** - * Returns the list of source file for this resource. - */ - public List<ResourceFile> getSourceFileList() { - return Collections.unmodifiableList(mFiles); - } - - /** - * Returns if the resource has at least one non-default version. - * - * @see ResourceFile#getConfiguration() - * @see FolderConfiguration#isDefault() - */ - public boolean hasAlternates() { - for (ResourceFile file : mFiles) { - if (file.getFolder().getConfiguration().isDefault() == false) { - return true; - } - } - - return false; - } - - /** - * Returns whether the resource has a default version, with no qualifier. - * - * @see ResourceFile#getConfiguration() - * @see FolderConfiguration#isDefault() - */ - public boolean hasDefault() { - for (ResourceFile file : mFiles) { - if (file.getFolder().getConfiguration().isDefault()) { - return true; - } - } - - // We only want to return false if there's no default and more than 0 items. - return (mFiles.size() == 0); - } - - /** - * Returns the number of alternate versions for this resource. - * - * @see ResourceFile#getConfiguration() - * @see FolderConfiguration#isDefault() - */ - public int getAlternateCount() { - int count = 0; - for (ResourceFile file : mFiles) { - if (file.getFolder().getConfiguration().isDefault() == false) { - count++; - } - } - - return count; - } - - /** - * Returns a formatted string usable in an XML to use for the {@link ResourceItem}. - * @param system Whether this is a system resource or a project resource. - * @return a string in the format @[type]/[name] - */ - public String getXmlString(ResourceType type, boolean system) { - if (type == ResourceType.ID && isDeclaredInline()) { - return (system ? "@android:" : "@+") + type.getName() + "/" + mName; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - - return (system ? "@android:" : "@") + type.getName() + "/" + mName; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - - @Override - public String toString() { - return "ResourceItem [mName=" + mName + ", mFiles=" + mFiles + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } -} diff --git a/ide_common/src/com/android/ide/common/resources/ResourceRepository.java b/ide_common/src/com/android/ide/common/resources/ResourceRepository.java deleted file mode 100755 index ac0614d..0000000 --- a/ide_common/src/com/android/ide/common/resources/ResourceRepository.java +++ /dev/null @@ -1,719 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.ide.common.rendering.api.ResourceValue; -import com.android.ide.common.resources.configuration.Configurable; -import com.android.ide.common.resources.configuration.FolderConfiguration; -import com.android.ide.common.resources.configuration.LanguageQualifier; -import com.android.ide.common.resources.configuration.RegionQualifier; -import com.android.io.IAbstractFile; -import com.android.io.IAbstractFolder; -import com.android.io.IAbstractResource; -import com.android.resources.FolderTypeRelationship; -import com.android.resources.ResourceFolderType; -import com.android.resources.ResourceType; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; - -/** - * Base class for resource repository. - * - * A repository is both a file representation of a resource folder and a representation - * of the generated resources, organized by type. - * - * {@link #getResourceFolder(IAbstractFolder)} and {@link #getSourceFiles(ResourceType, String, FolderConfiguration)} - * give access to the folders and files of the resource folder. - * - * {@link #getResources(ResourceType)} gives access to the resources directly. - * - */ -public abstract class ResourceRepository { - - protected final Map<ResourceFolderType, List<ResourceFolder>> mFolderMap = - new EnumMap<ResourceFolderType, List<ResourceFolder>>(ResourceFolderType.class); - - protected final Map<ResourceType, Map<String, ResourceItem>> mResourceMap = - new EnumMap<ResourceType, Map<String, ResourceItem>>( - ResourceType.class); - - private final Map<Map<String, ResourceItem>, Collection<ResourceItem>> mReadOnlyListMap = - new IdentityHashMap<Map<String, ResourceItem>, Collection<ResourceItem>>(); - - private final boolean mFrameworkRepository; - - protected final IntArrayWrapper mWrapper = new IntArrayWrapper(null); - - /** - * Makes a resource repository - * @param isFrameworkRepository whether the repository is for framework resources. - */ - protected ResourceRepository(boolean isFrameworkRepository) { - mFrameworkRepository = isFrameworkRepository; - } - - public boolean isFrameworkRepository() { - return mFrameworkRepository; - } - - /** - * Adds a Folder Configuration to the project. - * @param type The resource type. - * @param config The resource configuration. - * @param folder The workspace folder object. - * @return the {@link ResourceFolder} object associated to this folder. - */ - private ResourceFolder add( - @NonNull ResourceFolderType type, - @NonNull FolderConfiguration config, - @NonNull IAbstractFolder folder) { - // get the list for the resource type - List<ResourceFolder> list = mFolderMap.get(type); - - if (list == null) { - list = new ArrayList<ResourceFolder>(); - - ResourceFolder cf = new ResourceFolder(type, config, folder, this); - list.add(cf); - - mFolderMap.put(type, list); - - return cf; - } - - // look for an already existing folder configuration. - for (ResourceFolder cFolder : list) { - if (cFolder.mConfiguration.equals(config)) { - // config already exist. Nothing to be done really, besides making sure - // the IAbstractFolder object is up to date. - cFolder.mFolder = folder; - return cFolder; - } - } - - // If we arrive here, this means we didn't find a matching configuration. - // So we add one. - ResourceFolder cf = new ResourceFolder(type, config, folder, this); - list.add(cf); - - return cf; - } - - /** - * Removes a {@link ResourceFolder} associated with the specified {@link IAbstractFolder}. - * @param type The type of the folder - * @param removedFolder the IAbstractFolder object. - * @param context the scanning context - * @return the {@link ResourceFolder} that was removed, or null if no matches were found. - */ - @Nullable - public ResourceFolder removeFolder( - @NonNull ResourceFolderType type, - @NonNull IAbstractFolder removedFolder, - @Nullable ScanningContext context) { - // get the list of folders for the resource type. - List<ResourceFolder> list = mFolderMap.get(type); - - if (list != null) { - int count = list.size(); - for (int i = 0 ; i < count ; i++) { - ResourceFolder resFolder = list.get(i); - IAbstractFolder folder = resFolder.getFolder(); - if (removedFolder.equals(folder)) { - // we found the matching ResourceFolder. we need to remove it. - list.remove(i); - - // remove its content - resFolder.dispose(context); - - return resFolder; - } - } - } - - return null; - } - - /** - * Returns true if this resource repository contains a resource of the given - * name. - * - * @param url the resource URL - * @return true if the resource is known - */ - public boolean hasResourceItem(@NonNull String url) { - assert url.startsWith("@") : url; - - int typeEnd = url.indexOf('/', 1); - if (typeEnd != -1) { - int nameBegin = typeEnd + 1; - - // Skip @ and @+ - int typeBegin = url.startsWith("@+") ? 2 : 1; //$NON-NLS-1$ - - int colon = url.lastIndexOf(':', typeEnd); - if (colon != -1) { - typeBegin = colon + 1; - } - String typeName = url.substring(typeBegin, typeEnd); - ResourceType type = ResourceType.getEnum(typeName); - if (type != null) { - String name = url.substring(nameBegin); - return hasResourceItem(type, name); - } - } - - return false; - } - - /** - * Returns true if this resource repository contains a resource of the given - * name. - * - * @param type the type of resource to look up - * @param name the name of the resource - * @return true if the resource is known - */ - public boolean hasResourceItem(@NonNull ResourceType type, @NonNull String name) { - Map<String, ResourceItem> map = mResourceMap.get(type); - - if (map != null) { - - ResourceItem resourceItem = map.get(name); - if (resourceItem != null) { - return true; - } - } - - return false; - } - - /** - * Returns a {@link ResourceItem} matching the given {@link ResourceType} and name. If none - * exist, it creates one. - * - * @param type the resource type - * @param name the name of the resource. - * @return A resource item matching the type and name. - */ - @NonNull - protected ResourceItem getResourceItem(@NonNull ResourceType type, @NonNull String name) { - // looking for an existing ResourceItem with this type and name - ResourceItem item = findDeclaredResourceItem(type, name); - - // create one if there isn't one already, or if the existing one is inlined, since - // clearly we need a non inlined one (the inline one is removed too) - if (item == null || item.isDeclaredInline()) { - ResourceItem oldItem = item != null && item.isDeclaredInline() ? item : null; - - item = createResourceItem(name); - - Map<String, ResourceItem> map = mResourceMap.get(type); - - if (map == null) { - if (isFrameworkRepository()) { - // Pick initial size for the maps. Also change the load factor to 1.0 - // to avoid rehashing the whole table when we (as expected) get near - // the known rough size of each resource type map. - int size; - switch (type) { - // Based on counts in API 16. Going back to API 10, the counts - // are roughly 25-50% smaller (e.g. compared to the top 5 types below - // the fractions are 1107 vs 1734, 831 vs 1508, 895 vs 1255, - // 733 vs 1064 and 171 vs 783. - case PUBLIC: size = 1734; break; - case DRAWABLE: size = 1508; break; - case STRING: size = 1255; break; - case ATTR: size = 1064; break; - case STYLE: size = 783; break; - case ID: size = 347; break; - case DECLARE_STYLEABLE: size = 210; break; - case LAYOUT: size = 187; break; - case COLOR: size = 120; break; - case ANIM: size = 95; break; - case DIMEN: size = 81; break; - case BOOL: size = 54; break; - case INTEGER: size = 52; break; - case ARRAY: size = 51; break; - case PLURALS: size = 20; break; - case XML: size = 14; break; - case INTERPOLATOR : size = 13; break; - case ANIMATOR: size = 8; break; - case RAW: size = 4; break; - case MENU: size = 2; break; - case MIPMAP: size = 2; break; - case FRACTION: size = 1; break; - default: - size = 2; - } - map = new HashMap<String, ResourceItem>(size, 1.0f); - } else { - map = new HashMap<String, ResourceItem>(); - } - mResourceMap.put(type, map); - } - - map.put(item.getName(), item); - - if (oldItem != null) { - map.remove(oldItem.getName()); - - } - } - - return item; - } - - /** - * Creates a resource item with the given name. - * @param name the name of the resource - * @return a new ResourceItem (or child class) instance. - */ - @NonNull - protected abstract ResourceItem createResourceItem(@NonNull String name); - - /** - * Processes a folder and adds it to the list of existing folders. - * @param folder the folder to process - * @return the ResourceFolder created from this folder, or null if the process failed. - */ - @Nullable - public ResourceFolder processFolder(@NonNull IAbstractFolder folder) { - // split the name of the folder in segments. - String[] folderSegments = folder.getName().split(SdkConstants.RES_QUALIFIER_SEP); - - // get the enum for the resource type. - ResourceFolderType type = ResourceFolderType.getTypeByName(folderSegments[0]); - - if (type != null) { - // get the folder configuration. - FolderConfiguration config = FolderConfiguration.getConfig(folderSegments); - - if (config != null) { - return add(type, config, folder); - } - } - - return null; - } - - /** - * Returns a list of {@link ResourceFolder} for a specific {@link ResourceFolderType}. - * @param type The {@link ResourceFolderType} - */ - @Nullable - public List<ResourceFolder> getFolders(@NonNull ResourceFolderType type) { - return mFolderMap.get(type); - } - - @NonNull - public List<ResourceType> getAvailableResourceTypes() { - List<ResourceType> list = new ArrayList<ResourceType>(); - - // For each key, we check if there's a single ResourceType match. - // If not, we look for the actual content to give us the resource type. - - for (ResourceFolderType folderType : mFolderMap.keySet()) { - List<ResourceType> types = FolderTypeRelationship.getRelatedResourceTypes(folderType); - if (types.size() == 1) { - // before we add it we check if it's not already present, since a ResourceType - // could be created from multiple folders, even for the folders that only create - // one type of resource (drawable for instance, can be created from drawable/ and - // values/) - if (list.contains(types.get(0)) == false) { - list.add(types.get(0)); - } - } else { - // there isn't a single resource type out of this folder, so we look for all - // content. - List<ResourceFolder> folders = mFolderMap.get(folderType); - if (folders != null) { - for (ResourceFolder folder : folders) { - Collection<ResourceType> folderContent = folder.getResourceTypes(); - - // then we add them, but only if they aren't already in the list. - for (ResourceType folderResType : folderContent) { - if (list.contains(folderResType) == false) { - list.add(folderResType); - } - } - } - } - } - } - - return list; - } - - /** - * Returns a list of {@link ResourceItem} matching a given {@link ResourceType}. - * @param type the type of the resource items to return - * @return a non null collection of resource items - */ - @NonNull - public Collection<ResourceItem> getResourceItemsOfType(@NonNull ResourceType type) { - Map<String, ResourceItem> map = mResourceMap.get(type); - - if (map == null) { - return Collections.emptyList(); - } - - Collection<ResourceItem> roList = mReadOnlyListMap.get(map); - if (roList == null) { - roList = Collections.unmodifiableCollection(map.values()); - mReadOnlyListMap.put(map, roList); - } - - return roList; - } - - /** - * Returns whether the repository has resources of a given {@link ResourceType}. - * @param type the type of resource to check. - * @return true if the repository contains resources of the given type, false otherwise. - */ - public boolean hasResourcesOfType(@NonNull ResourceType type) { - Map<String, ResourceItem> items = mResourceMap.get(type); - return (items != null && items.size() > 0); - } - - /** - * Returns the {@link ResourceFolder} associated with a {@link IAbstractFolder}. - * @param folder The {@link IAbstractFolder} object. - * @return the {@link ResourceFolder} or null if it was not found. - */ - @Nullable - public ResourceFolder getResourceFolder(@NonNull IAbstractFolder folder) { - Collection<List<ResourceFolder>> values = mFolderMap.values(); - - if (values.isEmpty()) { // This shouldn't be necessary, but has been observed - try { - loadResources(folder.getParentFolder()); - } catch (IOException e) { - e.printStackTrace(); - } - } - - for (List<ResourceFolder> list : values) { - for (ResourceFolder resFolder : list) { - IAbstractFolder wrapper = resFolder.getFolder(); - if (wrapper.equals(folder)) { - return resFolder; - } - } - } - - return null; - } - - /** - * Returns the {@link ResourceFile} matching the given name, {@link ResourceFolderType} and - * configuration. - * <p/>This only works with files generating one resource named after the file (for instance, - * layouts, bitmap based drawable, xml, anims). - * @return the matching file or <code>null</code> if no match was found. - */ - @Nullable - public ResourceFile getMatchingFile(@NonNull String name, @NonNull ResourceFolderType type, - @NonNull FolderConfiguration config) { - // get the folders for the given type - List<ResourceFolder> folders = mFolderMap.get(type); - - // look for folders containing a file with the given name. - ArrayList<ResourceFolder> matchingFolders = new ArrayList<ResourceFolder>(folders.size()); - - // remove the folders that do not have a file with the given name. - for (int i = 0 ; i < folders.size(); i++) { - ResourceFolder folder = folders.get(i); - - if (folder.hasFile(name) == true) { - matchingFolders.add(folder); - } - } - - // from those, get the folder with a config matching the given reference configuration. - Configurable match = config.findMatchingConfigurable(matchingFolders); - - // do we have a matching folder? - if (match instanceof ResourceFolder) { - // get the ResourceFile from the filename - return ((ResourceFolder)match).getFile(name); - } - - return null; - } - - /** - * Returns the list of source files for a given resource. - * Optionally, if a {@link FolderConfiguration} is given, then only the best - * match for this config is returned. - * - * @param type the type of the resource. - * @param name the name of the resource. - * @param referenceConfig an optional config for which only the best match will be returned. - * - * @return a list of files generating this resource or null if it was not found. - */ - @Nullable - public List<ResourceFile> getSourceFiles(@NonNull ResourceType type, @NonNull String name, - @Nullable FolderConfiguration referenceConfig) { - - Collection<ResourceItem> items = getResourceItemsOfType(type); - - for (ResourceItem item : items) { - if (name.equals(item.getName())) { - if (referenceConfig != null) { - Configurable match = referenceConfig.findMatchingConfigurable( - item.getSourceFileList()); - - if (match instanceof ResourceFile) { - return Collections.singletonList((ResourceFile) match); - } - - return null; - } - return item.getSourceFileList(); - } - } - - return null; - } - - /** - * Returns the resources values matching a given {@link FolderConfiguration}. - * - * @param referenceConfig the configuration that each value must match. - * @return a map with guaranteed to contain an entry for each {@link ResourceType} - */ - @NonNull - public Map<ResourceType, Map<String, ResourceValue>> getConfiguredResources( - @NonNull FolderConfiguration referenceConfig) { - return doGetConfiguredResources(referenceConfig); - } - - /** - * Returns the resources values matching a given {@link FolderConfiguration} for the current - * project. - * - * @param referenceConfig the configuration that each value must match. - * @return a map with guaranteed to contain an entry for each {@link ResourceType} - */ - @NonNull - protected final Map<ResourceType, Map<String, ResourceValue>> doGetConfiguredResources( - @NonNull FolderConfiguration referenceConfig) { - - Map<ResourceType, Map<String, ResourceValue>> map = - new EnumMap<ResourceType, Map<String, ResourceValue>>(ResourceType.class); - - for (ResourceType key : ResourceType.values()) { - // get the local results and put them in the map - map.put(key, getConfiguredResource(key, referenceConfig)); - } - - return map; - } - - /** - * Returns the sorted list of languages used in the resources. - */ - @NonNull - public SortedSet<String> getLanguages() { - SortedSet<String> set = new TreeSet<String>(); - - Collection<List<ResourceFolder>> folderList = mFolderMap.values(); - for (List<ResourceFolder> folderSubList : folderList) { - for (ResourceFolder folder : folderSubList) { - FolderConfiguration config = folder.getConfiguration(); - LanguageQualifier lang = config.getLanguageQualifier(); - if (lang != null) { - set.add(lang.getShortDisplayValue()); - } - } - } - - return set; - } - - /** - * Returns the sorted list of regions used in the resources with the given language. - * @param currentLanguage the current language the region must be associated with. - */ - @NonNull - public SortedSet<String> getRegions(@NonNull String currentLanguage) { - SortedSet<String> set = new TreeSet<String>(); - - Collection<List<ResourceFolder>> folderList = mFolderMap.values(); - for (List<ResourceFolder> folderSubList : folderList) { - for (ResourceFolder folder : folderSubList) { - FolderConfiguration config = folder.getConfiguration(); - - // get the language - LanguageQualifier lang = config.getLanguageQualifier(); - if (lang != null && lang.getShortDisplayValue().equals(currentLanguage)) { - RegionQualifier region = config.getRegionQualifier(); - if (region != null) { - set.add(region.getShortDisplayValue()); - } - } - } - } - - return set; - } - - /** - * Loads the resources from a resource folder. - * <p/> - * - * @param rootFolder The folder to read the resources from. This is the top level - * resource folder (res/) - * @throws IOException - */ - public void loadResources(@NonNull IAbstractFolder rootFolder) - throws IOException { - ScanningContext context = new ScanningContext(this); - - IAbstractResource[] files = rootFolder.listMembers(); - for (IAbstractResource file : files) { - if (file instanceof IAbstractFolder) { - IAbstractFolder folder = (IAbstractFolder) file; - ResourceFolder resFolder = processFolder(folder); - - if (resFolder != null) { - // now we process the content of the folder - IAbstractResource[] children = folder.listMembers(); - - for (IAbstractResource childRes : children) { - if (childRes instanceof IAbstractFile) { - resFolder.processFile((IAbstractFile) childRes, - ResourceDeltaKind.ADDED, context); - } - } - } - } - } - } - - - protected void removeFile(@NonNull Collection<ResourceType> types, - @NonNull ResourceFile file) { - for (ResourceType type : types) { - removeFile(type, file); - } - } - - protected void removeFile(@NonNull ResourceType type, @NonNull ResourceFile file) { - Map<String, ResourceItem> map = mResourceMap.get(type); - if (map != null) { - Collection<ResourceItem> values = map.values(); - for (ResourceItem item : values) { - item.removeFile(file); - } - } - } - - /** - * Returns a map of (resource name, resource value) for the given {@link ResourceType}. - * <p/>The values returned are taken from the resource files best matching a given - * {@link FolderConfiguration}. - * @param type the type of the resources. - * @param referenceConfig the configuration to best match. - */ - @NonNull - private Map<String, ResourceValue> getConfiguredResource(@NonNull ResourceType type, - @NonNull FolderConfiguration referenceConfig) { - - // get the resource item for the given type - Map<String, ResourceItem> items = mResourceMap.get(type); - if (items == null) { - return new HashMap<String, ResourceValue>(); - } - - // create the map - HashMap<String, ResourceValue> map = new HashMap<String, ResourceValue>(items.size()); - - for (ResourceItem item : items.values()) { - ResourceValue value = item.getResourceValue(type, referenceConfig, - isFrameworkRepository()); - if (value != null) { - map.put(item.getName(), value); - } - } - - return map; - } - - - /** - * Cleans up the repository of resource items that have no source file anymore. - */ - public void postUpdateCleanUp() { - // Since removed files/folders remove source files from existing ResourceItem, loop through - // all resource items and remove the ones that have no source files. - - Collection<Map<String, ResourceItem>> maps = mResourceMap.values(); - for (Map<String, ResourceItem> map : maps) { - Set<String> keySet = map.keySet(); - Iterator<String> iterator = keySet.iterator(); - while (iterator.hasNext()) { - String name = iterator.next(); - ResourceItem resourceItem = map.get(name); - if (resourceItem.hasNoSourceFile()) { - iterator.remove(); - } - } - } - } - - /** - * Looks up an existing {@link ResourceItem} by {@link ResourceType} and name. This - * ignores inline resources. - * @param type the Resource Type. - * @param name the Resource name. - * @return the existing ResourceItem or null if no match was found. - */ - @Nullable - private ResourceItem findDeclaredResourceItem(@NonNull ResourceType type, - @NonNull String name) { - Map<String, ResourceItem> map = mResourceMap.get(type); - - if (map != null) { - ResourceItem resourceItem = map.get(name); - if (resourceItem != null && !resourceItem.isDeclaredInline()) { - return resourceItem; - } - } - - return null; - } -} - diff --git a/ide_common/src/com/android/ide/common/resources/ResourceResolver.java b/ide_common/src/com/android/ide/common/resources/ResourceResolver.java deleted file mode 100644 index d742c4a..0000000 --- a/ide_common/src/com/android/ide/common/resources/ResourceResolver.java +++ /dev/null @@ -1,560 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources; - -import static com.android.SdkConstants.ANDROID_PREFIX; -import static com.android.SdkConstants.ANDROID_THEME_PREFIX; -import static com.android.SdkConstants.PREFIX_ANDROID; -import static com.android.SdkConstants.PREFIX_RESOURCE_REF; -import static com.android.SdkConstants.PREFIX_THEME_REF; -import static com.android.SdkConstants.REFERENCE_STYLE; - -import com.android.ide.common.rendering.api.LayoutLog; -import com.android.ide.common.rendering.api.RenderResources; -import com.android.ide.common.rendering.api.ResourceValue; -import com.android.ide.common.rendering.api.StyleResourceValue; -import com.android.resources.ResourceType; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -public class ResourceResolver extends RenderResources { - - private final Map<ResourceType, Map<String, ResourceValue>> mProjectResources; - private final Map<ResourceType, Map<String, ResourceValue>> mFrameworkResources; - - private final Map<StyleResourceValue, StyleResourceValue> mStyleInheritanceMap = - new HashMap<StyleResourceValue, StyleResourceValue>(); - - private StyleResourceValue mTheme; - - private FrameworkResourceIdProvider mFrameworkProvider; - private LayoutLog mLogger; - private String mThemeName; - private boolean mIsProjectTheme; - - private ResourceResolver( - Map<ResourceType, Map<String, ResourceValue>> projectResources, - Map<ResourceType, Map<String, ResourceValue>> frameworkResources) { - mProjectResources = projectResources; - mFrameworkResources = frameworkResources; - } - - /** - * Creates a new {@link ResourceResolver} object. - * - * @param projectResources the project resources. - * @param frameworkResources the framework resources. - * @param themeName the name of the current theme. - * @param isProjectTheme Is this a project theme? - * @return a new {@link ResourceResolver} - */ - public static ResourceResolver create( - Map<ResourceType, Map<String, ResourceValue>> projectResources, - Map<ResourceType, Map<String, ResourceValue>> frameworkResources, - String themeName, boolean isProjectTheme) { - - ResourceResolver resolver = new ResourceResolver( - projectResources, frameworkResources); - - resolver.computeStyleMaps(themeName, isProjectTheme); - - return resolver; - } - - // ---- Methods to help dealing with older LayoutLibs. - - public String getThemeName() { - return mThemeName; - } - - public boolean isProjectTheme() { - return mIsProjectTheme; - } - - public Map<ResourceType, Map<String, ResourceValue>> getProjectResources() { - return mProjectResources; - } - - public Map<ResourceType, Map<String, ResourceValue>> getFrameworkResources() { - return mFrameworkResources; - } - - // ---- RenderResources Methods - - @Override - public void setFrameworkResourceIdProvider(FrameworkResourceIdProvider provider) { - mFrameworkProvider = provider; - } - - @Override - public void setLogger(LayoutLog logger) { - mLogger = logger; - } - - @Override - public StyleResourceValue getCurrentTheme() { - return mTheme; - } - - @Override - public StyleResourceValue getTheme(String name, boolean frameworkTheme) { - ResourceValue theme = null; - - if (frameworkTheme) { - Map<String, ResourceValue> frameworkStyleMap = mFrameworkResources.get( - ResourceType.STYLE); - theme = frameworkStyleMap.get(name); - } else { - Map<String, ResourceValue> projectStyleMap = mProjectResources.get(ResourceType.STYLE); - theme = projectStyleMap.get(name); - } - - if (theme instanceof StyleResourceValue) { - return (StyleResourceValue) theme; - } - - return null; - } - - @Override - public boolean themeIsParentOf(StyleResourceValue parentTheme, StyleResourceValue childTheme) { - do { - childTheme = mStyleInheritanceMap.get(childTheme); - if (childTheme == null) { - return false; - } else if (childTheme == parentTheme) { - return true; - } - } while (true); - } - - @Override - public ResourceValue getFrameworkResource(ResourceType resourceType, String resourceName) { - return getResource(resourceType, resourceName, mFrameworkResources); - } - - @Override - public ResourceValue getProjectResource(ResourceType resourceType, String resourceName) { - return getResource(resourceType, resourceName, mProjectResources); - } - - @Override - @Deprecated - public ResourceValue findItemInStyle(StyleResourceValue style, String attrName) { - // this method is deprecated because it doesn't know about the namespace of the - // attribute so we search for the project namespace first and then in the - // android namespace if needed. - ResourceValue item = findItemInStyle(style, attrName, false /*isFrameworkAttr*/); - if (item == null) { - item = findItemInStyle(style, attrName, true /*isFrameworkAttr*/); - } - - return item; - } - - @Override - public ResourceValue findItemInStyle(StyleResourceValue style, String itemName, - boolean isFrameworkAttr) { - ResourceValue item = style.findValue(itemName, isFrameworkAttr); - - // if we didn't find it, we look in the parent style (if applicable) - if (item == null && mStyleInheritanceMap != null) { - StyleResourceValue parentStyle = mStyleInheritanceMap.get(style); - if (parentStyle != null) { - return findItemInStyle(parentStyle, itemName, isFrameworkAttr); - } - } - - return item; - } - - @Override - public ResourceValue findResValue(String reference, boolean forceFrameworkOnly) { - if (reference == null) { - return null; - } - if (reference.startsWith(PREFIX_THEME_REF)) { - // no theme? no need to go further! - if (mTheme == null) { - return null; - } - - boolean frameworkOnly = false; - - // eliminate the prefix from the string - if (reference.startsWith(ANDROID_THEME_PREFIX)) { - frameworkOnly = true; - reference = reference.substring(ANDROID_THEME_PREFIX.length()); - } else { - reference = reference.substring(PREFIX_THEME_REF.length()); - } - - // at this point, value can contain type/name (drawable/foo for instance). - // split it to make sure. - String[] segments = reference.split("\\/"); - - // we look for the referenced item name. - String referenceName = null; - - if (segments.length == 2) { - // there was a resType in the reference. If it's attr, we ignore it - // else, we assert for now. - if (ResourceType.ATTR.getName().equals(segments[0])) { - referenceName = segments[1]; - } else { - // At this time, no support for ?type/name where type is not "attr" - return null; - } - } else { - // it's just an item name. - referenceName = segments[0]; - } - - // now we look for android: in the referenceName in order to support format - // such as: ?attr/android:name - if (referenceName.startsWith(PREFIX_ANDROID)) { - frameworkOnly = true; - referenceName = referenceName.substring(PREFIX_ANDROID.length()); - } - - // Now look for the item in the theme, starting with the current one. - ResourceValue item = findItemInStyle(mTheme, referenceName, - forceFrameworkOnly || frameworkOnly); - - if (item == null && mLogger != null) { - mLogger.warning(LayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR, - String.format("Couldn't find theme resource %1$s for the current theme", - reference), - new ResourceValue(ResourceType.ATTR, referenceName, frameworkOnly)); - } - - return item; - } else if (reference.startsWith(PREFIX_RESOURCE_REF)) { - boolean frameworkOnly = false; - - // check for the specific null reference value. - if (REFERENCE_NULL.equals(reference)) { - return null; - } - - // Eliminate the prefix from the string. - if (reference.startsWith(ANDROID_PREFIX)) { - frameworkOnly = true; - reference = reference.substring(ANDROID_PREFIX.length()); - } else { - reference = reference.substring(PREFIX_RESOURCE_REF.length()); - } - - // at this point, value contains type/[android:]name (drawable/foo for instance) - String[] segments = reference.split("\\/"); - - // now we look for android: in the resource name in order to support format - // such as: @drawable/android:name - if (segments[1].startsWith(PREFIX_ANDROID)) { - frameworkOnly = true; - segments[1] = segments[1].substring(PREFIX_ANDROID.length()); - } - - ResourceType type = ResourceType.getEnum(segments[0]); - - // unknown type? - if (type == null) { - return null; - } - - return findResValue(type, segments[1], - forceFrameworkOnly ? true :frameworkOnly); - } - - // Looks like the value didn't reference anything. Return null. - return null; - } - - @Override - public ResourceValue resolveValue(ResourceType type, String name, String value, - boolean isFrameworkValue) { - if (value == null) { - return null; - } - - // get the ResourceValue referenced by this value - ResourceValue resValue = findResValue(value, isFrameworkValue); - - // if resValue is null, but value is not null, this means it was not a reference. - // we return the name/value wrapper in a ResourceValue. the isFramework flag doesn't - // matter. - if (resValue == null) { - return new ResourceValue(type, name, value, isFrameworkValue); - } - - // we resolved a first reference, but we need to make sure this isn't a reference also. - return resolveResValue(resValue); - } - - @Override - public ResourceValue resolveResValue(ResourceValue resValue) { - if (resValue == null) { - return null; - } - - // if the resource value is null, we simply return it. - String value = resValue.getValue(); - if (value == null) { - return resValue; - } - - // else attempt to find another ResourceValue referenced by this one. - ResourceValue resolvedResValue = findResValue(value, resValue.isFramework()); - - // if the value did not reference anything, then we simply return the input value - if (resolvedResValue == null) { - return resValue; - } - - // detect potential loop due to mishandled namespace in attributes - if (resValue == resolvedResValue) { - if (mLogger != null) { - mLogger.error(LayoutLog.TAG_BROKEN, - String.format("Potential stackoverflow trying to resolve '%s'. Render may not be accurate.", value), - null); - } - return resValue; - } - - // otherwise, we attempt to resolve this new value as well - return resolveResValue(resolvedResValue); - } - - // ---- Private helper methods. - - /** - * Searches for, and returns a {@link ResourceValue} by its name, and type. - * @param resType the type of the resource - * @param resName the name of the resource - * @param frameworkOnly if <code>true</code>, the method does not search in the - * project resources - */ - private ResourceValue findResValue(ResourceType resType, String resName, - boolean frameworkOnly) { - // map of ResouceValue for the given type - Map<String, ResourceValue> typeMap; - - // if allowed, search in the project resources first. - if (frameworkOnly == false) { - typeMap = mProjectResources.get(resType); - ResourceValue item = typeMap.get(resName); - if (item != null) { - return item; - } - } - - // now search in the framework resources. - typeMap = mFrameworkResources.get(resType); - ResourceValue item = typeMap.get(resName); - if (item != null) { - return item; - } - - // if it was not found and the type is an id, it is possible that the ID was - // generated dynamically when compiling the framework resources. - // Look for it in the R map. - if (mFrameworkProvider != null && resType == ResourceType.ID) { - if (mFrameworkProvider.getId(resType, resName) != null) { - return new ResourceValue(resType, resName, true); - } - } - - // didn't find the resource anywhere. - if (mLogger != null) { - mLogger.warning(LayoutLog.TAG_RESOURCES_RESOLVE, - "Couldn't resolve resource @" + - (frameworkOnly ? "android:" : "") + resType + "/" + resName, - new ResourceValue(resType, resName, frameworkOnly)); - } - return null; - } - - private ResourceValue getResource(ResourceType resourceType, String resourceName, - Map<ResourceType, Map<String, ResourceValue>> resourceRepository) { - Map<String, ResourceValue> typeMap = resourceRepository.get(resourceType); - if (typeMap != null) { - ResourceValue item = typeMap.get(resourceName); - if (item != null) { - item = resolveResValue(item); - return item; - } - } - - // didn't find the resource anywhere. - return null; - - } - - /** - * Compute style information from the given list of style for the project and framework. - * @param themeName the name of the current theme. - * @param isProjectTheme Is this a project theme? - */ - private void computeStyleMaps(String themeName, boolean isProjectTheme) { - mThemeName = themeName; - mIsProjectTheme = isProjectTheme; - Map<String, ResourceValue> projectStyleMap = mProjectResources.get(ResourceType.STYLE); - Map<String, ResourceValue> frameworkStyleMap = mFrameworkResources.get(ResourceType.STYLE); - - // first, get the theme - ResourceValue theme = null; - - // project theme names have been prepended with a * - if (isProjectTheme) { - theme = projectStyleMap.get(themeName); - } else { - theme = frameworkStyleMap.get(themeName); - } - - if (theme instanceof StyleResourceValue) { - // compute the inheritance map for both the project and framework styles - computeStyleInheritance(projectStyleMap.values(), projectStyleMap, - frameworkStyleMap); - - // Compute the style inheritance for the framework styles/themes. - // Since, for those, the style parent values do not contain 'android:' - // we want to force looking in the framework style only to avoid using - // similarly named styles from the project. - // To do this, we pass null in lieu of the project style map. - computeStyleInheritance(frameworkStyleMap.values(), null /*inProjectStyleMap */, - frameworkStyleMap); - - mTheme = (StyleResourceValue) theme; - } - } - - - - /** - * Compute the parent style for all the styles in a given list. - * @param styles the styles for which we compute the parent. - * @param inProjectStyleMap the map of project styles. - * @param inFrameworkStyleMap the map of framework styles. - * @param outInheritanceMap the map of style inheritance. This is filled by the method. - */ - private void computeStyleInheritance(Collection<ResourceValue> styles, - Map<String, ResourceValue> inProjectStyleMap, - Map<String, ResourceValue> inFrameworkStyleMap) { - for (ResourceValue value : styles) { - if (value instanceof StyleResourceValue) { - StyleResourceValue style = (StyleResourceValue)value; - StyleResourceValue parentStyle = null; - - // first look for a specified parent. - String parentName = style.getParentStyle(); - - // no specified parent? try to infer it from the name of the style. - if (parentName == null) { - parentName = getParentName(value.getName()); - } - - if (parentName != null) { - parentStyle = getStyle(parentName, inProjectStyleMap, inFrameworkStyleMap); - - if (parentStyle != null) { - mStyleInheritanceMap.put(style, parentStyle); - } - } - } - } - } - - - /** - * Computes the name of the parent style, or <code>null</code> if the style is a root style. - */ - private String getParentName(String styleName) { - int index = styleName.lastIndexOf('.'); - if (index != -1) { - return styleName.substring(0, index); - } - - return null; - } - - /** - * Searches for and returns the {@link StyleResourceValue} from a given name. - * <p/>The format of the name can be: - * <ul> - * <li>[android:]<name></li> - * <li>[android:]style/<name></li> - * <li>@[android:]style/<name></li> - * </ul> - * @param parentName the name of the style. - * @param inProjectStyleMap the project style map. Can be <code>null</code> - * @param inFrameworkStyleMap the framework style map. - * @return The matching {@link StyleResourceValue} object or <code>null</code> if not found. - */ - private StyleResourceValue getStyle(String parentName, - Map<String, ResourceValue> inProjectStyleMap, - Map<String, ResourceValue> inFrameworkStyleMap) { - boolean frameworkOnly = false; - - String name = parentName; - - // remove the useless @ if it's there - if (name.startsWith(PREFIX_RESOURCE_REF)) { - name = name.substring(PREFIX_RESOURCE_REF.length()); - } - - // check for framework identifier. - if (name.startsWith(PREFIX_ANDROID)) { - frameworkOnly = true; - name = name.substring(PREFIX_ANDROID.length()); - } - - // at this point we could have the format <type>/<name>. we want only the name as long as - // the type is style. - if (name.startsWith(REFERENCE_STYLE)) { - name = name.substring(REFERENCE_STYLE.length()); - } else if (name.indexOf('/') != -1) { - return null; - } - - ResourceValue parent = null; - - // if allowed, search in the project resources. - if (frameworkOnly == false && inProjectStyleMap != null) { - parent = inProjectStyleMap.get(name); - } - - // if not found, then look in the framework resources. - if (parent == null) { - parent = inFrameworkStyleMap.get(name); - } - - // make sure the result is the proper class type and return it. - if (parent instanceof StyleResourceValue) { - return (StyleResourceValue)parent; - } - - if (mLogger != null) { - mLogger.error(LayoutLog.TAG_RESOURCES_RESOLVE, - String.format("Unable to resolve parent style name: %s", parentName), - null /*data*/); - } - - return null; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/ScanningContext.java b/ide_common/src/com/android/ide/common/resources/ScanningContext.java deleted file mode 100644 index e4ed275..0000000 --- a/ide_common/src/com/android/ide/common/resources/ScanningContext.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2011 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.common.resources; - -import java.util.ArrayList; -import java.util.List; - -/** - * A {@link ScanningContext} keeps track of state during a resource file scan, - * such as any parsing errors encountered, whether Android ids have changed, and - * so on. - */ -public class ScanningContext { - private final ResourceRepository mRepository; - private boolean mNeedsFullAapt; - private List<String> mErrors = null; - - /** - * Constructs a new {@link ScanningContext} - * - * @param repository the associated resource repository - */ - public ScanningContext(ResourceRepository repository) { - super(); - mRepository = repository; - } - - /** - * Returns a list of errors encountered during scanning - * - * @return a list of errors encountered during scanning (or null) - */ - public List<String> getErrors() { - return mErrors; - } - - /** - * Adds the given error to the scanning context. The error should use the - * same syntax as real aapt error messages such that the aapt parser can - * properly detect the filename, line number, etc. - * - * @param error the error message, including file name and line number at - * the beginning - */ - public void addError(String error) { - if (mErrors == null) { - mErrors = new ArrayList<String>(); - } - mErrors.add(error); - } - - /** - * Returns the repository associated with this scanning context - * - * @return the associated repository, never null - */ - public ResourceRepository getRepository() { - return mRepository; - } - - /** - * Marks that a full aapt compilation of the resources is necessary because it has - * detected a change that cannot be incrementally handled. - */ - protected void requestFullAapt() { - mNeedsFullAapt = true; - } - - /** - * Returns whether this repository has been marked as "dirty"; if one or - * more of the constituent files have declared that the resource item names - * that they provide have changed. - * - * @return true if a full aapt compilation is required - */ - public boolean needsFullAapt() { - return mNeedsFullAapt; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/SingleResourceFile.java b/ide_common/src/com/android/ide/common/resources/SingleResourceFile.java deleted file mode 100644 index 6b663e9..0000000 --- a/ide_common/src/com/android/ide/common/resources/SingleResourceFile.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources; - -import com.android.ide.common.rendering.api.DensityBasedResourceValue; -import com.android.ide.common.rendering.api.ResourceValue; -import com.android.ide.common.resources.configuration.DensityQualifier; -import com.android.io.IAbstractFile; -import com.android.resources.FolderTypeRelationship; -import com.android.resources.ResourceType; - -import java.util.Collection; -import java.util.List; - -import javax.xml.parsers.SAXParserFactory; - -/** - * Represents a resource file describing a single resource. - * <p/> - * This is typically an XML file inside res/anim, res/layout, or res/menu or an image file - * under res/drawable. - */ -public class SingleResourceFile extends ResourceFile { - - private final static SAXParserFactory sParserFactory = SAXParserFactory.newInstance(); - static { - sParserFactory.setNamespaceAware(true); - } - - private final String mResourceName; - private final ResourceType mType; - private ResourceValue mValue; - - public SingleResourceFile(IAbstractFile file, ResourceFolder folder) { - super(file, folder); - - // we need to infer the type of the resource from the folder type. - // This is easy since this is a single Resource file. - List<ResourceType> types = FolderTypeRelationship.getRelatedResourceTypes(folder.getType()); - mType = types.get(0); - - // compute the resource name - mResourceName = getResourceName(mType); - - // test if there's a density qualifier associated with the resource - DensityQualifier qualifier = folder.getConfiguration().getDensityQualifier(); - - if (qualifier == null) { - mValue = new ResourceValue(mType, getResourceName(mType), - file.getOsLocation(), isFramework()); - } else { - mValue = new DensityBasedResourceValue( - mType, - getResourceName(mType), - file.getOsLocation(), - qualifier.getValue(), - isFramework()); - } - } - - @Override - protected void load(ScanningContext context) { - // get a resource item matching the given type and name - ResourceItem item = getRepository().getResourceItem(mType, mResourceName); - - // add this file to the list of files generating this resource item. - item.add(this); - - // Ask for an ID refresh since we're adding an item that will generate an ID - context.requestFullAapt(); - } - - @Override - protected void update(ScanningContext context) { - // when this happens, nothing needs to be done since the file only generates - // a single resources that doesn't actually change (its content is the file path) - } - - @Override - protected void dispose(ScanningContext context) { - // only remove this file from the existing ResourceItem. - getFolder().getRepository().removeFile(mType, this); - - // Ask for an ID refresh since we're removing an item that previously generated an ID - context.requestFullAapt(); - - // don't need to touch the content, it'll get reclaimed as this objects disappear. - // In the mean time other objects may need to access it. - } - - @Override - public Collection<ResourceType> getResourceTypes() { - return FolderTypeRelationship.getRelatedResourceTypes(getFolder().getType()); - } - - @Override - public boolean hasResources(ResourceType type) { - return FolderTypeRelationship.match(type, getFolder().getType()); - } - - /* - * (non-Javadoc) - * @see com.android.ide.eclipse.editors.resources.manager.ResourceFile#getValue(com.android.ide.eclipse.common.resources.ResourceType, java.lang.String) - * - * This particular implementation does not care about the type or name since a - * SingleResourceFile represents a file generating only one resource. - * The value returned is the full absolute path of the file in OS form. - */ - @Override - public ResourceValue getValue(ResourceType type, String name) { - return mValue; - } - - /** - * Returns the name of the resources. - */ - private String getResourceName(ResourceType type) { - // get the name from the filename. - String name = getFile().getName(); - - int pos = name.indexOf('.'); - if (pos != -1) { - name = name.substring(0, pos); - } - - return name; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/ValueResourceParser.java b/ide_common/src/com/android/ide/common/resources/ValueResourceParser.java deleted file mode 100644 index aabfd35..0000000 --- a/ide_common/src/com/android/ide/common/resources/ValueResourceParser.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources; - -import com.android.ide.common.rendering.api.AttrResourceValue; -import com.android.ide.common.rendering.api.DeclareStyleableResourceValue; -import com.android.ide.common.rendering.api.ResourceValue; -import com.android.ide.common.rendering.api.StyleResourceValue; -import com.android.resources.ResourceType; - -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -/** - * SAX handler to parser value resource files. - */ -public final class ValueResourceParser extends DefaultHandler { - - // TODO: reuse definitions from somewhere else. - private final static String NODE_RESOURCES = "resources"; - private final static String NODE_ITEM = "item"; - private final static String ATTR_NAME = "name"; - private final static String ATTR_TYPE = "type"; - private final static String ATTR_PARENT = "parent"; - private final static String ATTR_VALUE = "value"; - - private final static String DEFAULT_NS_PREFIX = "android:"; - private final static int DEFAULT_NS_PREFIX_LEN = DEFAULT_NS_PREFIX.length(); - - public interface IValueResourceRepository { - void addResourceValue(ResourceValue value); - boolean hasResourceValue(ResourceType type, String name); - } - - private boolean inResources = false; - private int mDepth = 0; - private ResourceValue mCurrentValue = null; - private StyleResourceValue mCurrentStyle = null; - private DeclareStyleableResourceValue mCurrentDeclareStyleable = null; - private AttrResourceValue mCurrentAttr; - private IValueResourceRepository mRepository; - private final boolean mIsFramework; - - public ValueResourceParser(IValueResourceRepository repository, boolean isFramework) { - mRepository = repository; - mIsFramework = isFramework; - } - - @Override - public void endElement(String uri, String localName, String qName) throws SAXException { - if (mCurrentValue != null) { - mCurrentValue.setValue(trimXmlWhitespaces(mCurrentValue.getValue())); - } - - if (inResources && qName.equals(NODE_RESOURCES)) { - inResources = false; - } else if (mDepth == 2) { - mCurrentValue = null; - mCurrentStyle = null; - mCurrentDeclareStyleable = null; - mCurrentAttr = null; - } else if (mDepth == 3) { - mCurrentValue = null; - if (mCurrentDeclareStyleable != null) { - mCurrentAttr = null; - } - } - - mDepth--; - super.endElement(uri, localName, qName); - } - - @Override - public void startElement(String uri, String localName, String qName, Attributes attributes) - throws SAXException { - try { - mDepth++; - if (inResources == false && mDepth == 1) { - if (qName.equals(NODE_RESOURCES)) { - inResources = true; - } - } else if (mDepth == 2 && inResources == true) { - ResourceType type = getType(qName, attributes); - - if (type != null) { - // get the resource name - String name = attributes.getValue(ATTR_NAME); - if (name != null) { - switch (type) { - case STYLE: - String parent = attributes.getValue(ATTR_PARENT); - mCurrentStyle = new StyleResourceValue(type, name, parent, - mIsFramework); - mRepository.addResourceValue(mCurrentStyle); - break; - case DECLARE_STYLEABLE: - mCurrentDeclareStyleable = new DeclareStyleableResourceValue( - type, name, mIsFramework); - mRepository.addResourceValue(mCurrentDeclareStyleable); - break; - case ATTR: - mCurrentAttr = new AttrResourceValue(type, name, mIsFramework); - mRepository.addResourceValue(mCurrentAttr); - break; - default: - mCurrentValue = new ResourceValue(type, name, mIsFramework); - mRepository.addResourceValue(mCurrentValue); - break; - } - } - } - } else if (mDepth == 3) { - // get the resource name - String name = attributes.getValue(ATTR_NAME); - if (name != null) { - - if (mCurrentStyle != null) { - // is the attribute in the android namespace? - boolean isFrameworkAttr = mIsFramework; - if (name.startsWith(DEFAULT_NS_PREFIX)) { - name = name.substring(DEFAULT_NS_PREFIX_LEN); - isFrameworkAttr = true; - } - - mCurrentValue = new ResourceValue(null, name, mIsFramework); - mCurrentStyle.addValue(mCurrentValue, isFrameworkAttr); - } else if (mCurrentDeclareStyleable != null) { - // is the attribute in the android namespace? - boolean isFramework = mIsFramework; - if (name.startsWith(DEFAULT_NS_PREFIX)) { - name = name.substring(DEFAULT_NS_PREFIX_LEN); - isFramework = true; - } - - mCurrentAttr = new AttrResourceValue(ResourceType.ATTR, name, isFramework); - mCurrentDeclareStyleable.addValue(mCurrentAttr); - - // also add it to the repository. - mRepository.addResourceValue(mCurrentAttr); - - } else if (mCurrentAttr != null) { - // get the enum/flag value - String value = attributes.getValue(ATTR_VALUE); - - try { - // Integer.decode/parseInt can't deal with hex value > 0x7FFFFFFF so we - // use Long.decode instead. - mCurrentAttr.addValue(name, (int)(long)Long.decode(value)); - } catch (NumberFormatException e) { - // pass, we'll just ignore this value - } - - } - } - } else if (mDepth == 4 && mCurrentAttr != null) { - // get the enum/flag name - String name = attributes.getValue(ATTR_NAME); - String value = attributes.getValue(ATTR_VALUE); - - try { - // Integer.decode/parseInt can't deal with hex value > 0x7FFFFFFF so we - // use Long.decode instead. - mCurrentAttr.addValue(name, (int)(long)Long.decode(value)); - } catch (NumberFormatException e) { - // pass, we'll just ignore this value - } - } - } finally { - super.startElement(uri, localName, qName, attributes); - } - } - - private ResourceType getType(String qName, Attributes attributes) { - String typeValue; - - // if the node is <item>, we get the type from the attribute "type" - if (NODE_ITEM.equals(qName)) { - typeValue = attributes.getValue(ATTR_TYPE); - } else { - // the type is the name of the node. - typeValue = qName; - } - - ResourceType type = ResourceType.getEnum(typeValue); - return type; - } - - - @Override - public void characters(char[] ch, int start, int length) throws SAXException { - if (mCurrentValue != null) { - String value = mCurrentValue.getValue(); - if (value == null) { - mCurrentValue.setValue(new String(ch, start, length)); - } else { - mCurrentValue.setValue(value + new String(ch, start, length)); - } - } - } - - public static String trimXmlWhitespaces(String value) { - if (value == null) { - return null; - } - - // look for carriage return and replace all whitespace around it by just 1 space. - int index; - - while ((index = value.indexOf('\n')) != -1) { - // look for whitespace on each side - int left = index - 1; - while (left >= 0) { - if (Character.isWhitespace(value.charAt(left))) { - left--; - } else { - break; - } - } - - int right = index + 1; - int count = value.length(); - while (right < count) { - if (Character.isWhitespace(value.charAt(right))) { - right++; - } else { - break; - } - } - - // remove all between left and right (non inclusive) and replace by a single space. - String leftString = null; - if (left >= 0) { - leftString = value.substring(0, left + 1); - } - String rightString = null; - if (right < count) { - rightString = value.substring(right); - } - - if (leftString != null) { - value = leftString; - if (rightString != null) { - value += " " + rightString; - } - } else { - value = rightString != null ? rightString : ""; - } - } - - // now we un-escape the string - int length = value.length(); - char[] buffer = value.toCharArray(); - - for (int i = 0 ; i < length ; i++) { - if (buffer[i] == '\\' && i + 1 < length) { - if (buffer[i+1] == 'u') { - if (i + 5 < length) { - // this is unicode char \u1234 - int unicodeChar = Integer.parseInt(new String(buffer, i+2, 4), 16); - - // put the unicode char at the location of the \ - buffer[i] = (char)unicodeChar; - - // offset the rest of the buffer since we go from 6 to 1 char - if (i + 6 < buffer.length) { - System.arraycopy(buffer, i+6, buffer, i+1, length - i - 6); - } - length -= 5; - } - } else { - if (buffer[i+1] == 'n') { - // replace the 'n' char with \n - buffer[i+1] = '\n'; - } - - // offset the buffer to erase the \ - System.arraycopy(buffer, i+1, buffer, i, length - i - 1); - length--; - } - } else if (buffer[i] == '"') { - // if the " was escaped it would have been processed above. - // offset the buffer to erase the " - System.arraycopy(buffer, i+1, buffer, i, length - i - 1); - length--; - - // unlike when unescaping, we want to process the next char too - i--; - } - } - - return new String(buffer, 0, length); - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/Configurable.java b/ide_common/src/com/android/ide/common/resources/configuration/Configurable.java deleted file mode 100644 index 5e7f910..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/Configurable.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - - -/** - * An object that is associated with a {@link FolderConfiguration}. - */ -public interface Configurable { - /** - * Returns the {@link FolderConfiguration} for this object. - */ - public FolderConfiguration getConfiguration(); -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/CountryCodeQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/CountryCodeQualifier.java deleted file mode 100644 index eb7cc0d..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/CountryCodeQualifier.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Resource Qualifier for Mobile Country Code. - */ -public final class CountryCodeQualifier extends ResourceQualifier { - /** Default pixel density value. This means the property is not set. */ - private final static int DEFAULT_CODE = -1; - - private final static Pattern sCountryCodePattern = Pattern.compile("^mcc(\\d{3})$");//$NON-NLS-1$ - - private final int mCode; - - public static final String NAME = "Mobile Country Code"; - - /** - * Creates and returns a qualifier from the given folder segment. If the segment is incorrect, - * <code>null</code> is returned. - * @param segment the folder segment from which to create a qualifier. - * @return a new {@link CountryCodeQualifier} object or <code>null</code> - */ - public static CountryCodeQualifier getQualifier(String segment) { - Matcher m = sCountryCodePattern.matcher(segment); - if (m.matches()) { - String v = m.group(1); - - int code = -1; - try { - code = Integer.parseInt(v); - } catch (NumberFormatException e) { - // looks like the string we extracted wasn't a valid number. - return null; - } - - CountryCodeQualifier qualifier = new CountryCodeQualifier(code); - return qualifier; - } - - return null; - } - - /** - * Returns the folder name segment for the given value. This is equivalent to calling - * {@link #toString()} on a {@link CountryCodeQualifier} object. - * @param code the value of the qualifier, as returned by {@link #getCode()}. - */ - public static String getFolderSegment(int code) { - if (code != DEFAULT_CODE && code >= 100 && code <=999) { // code is 3 digit.) { - return String.format("mcc%1$d", code); //$NON-NLS-1$ - } - - return ""; //$NON-NLS-1$ - } - - public CountryCodeQualifier() { - this(DEFAULT_CODE); - } - - public CountryCodeQualifier(int code) { - mCode = code; - } - - public int getCode() { - return mCode; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return "Country Code"; - } - - @Override - public int since() { - return 1; - } - - @Override - public boolean isValid() { - return mCode != DEFAULT_CODE; - } - - @Override - public boolean hasFakeValue() { - return false; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - CountryCodeQualifier qualifier = getQualifier(value); - if (qualifier != null) { - config.setCountryCodeQualifier(qualifier); - return true; - } - - return false; - } - - @Override - public boolean equals(Object qualifier) { - if (qualifier instanceof CountryCodeQualifier) { - return mCode == ((CountryCodeQualifier)qualifier).mCode; - } - - return false; - } - - @Override - public int hashCode() { - return mCode; - } - - /** - * Returns the string used to represent this qualifier in the folder name. - */ - @Override - public String getFolderSegment() { - return getFolderSegment(mCode); - } - - @Override - public String getShortDisplayValue() { - if (mCode != DEFAULT_CODE) { - return String.format("MCC %1$d", mCode); - } - - return ""; //$NON-NLS-1$ - } - - @Override - public String getLongDisplayValue() { - return getShortDisplayValue(); - } - -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/DensityQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/DensityQualifier.java deleted file mode 100644 index a9e4a01..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/DensityQualifier.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import com.android.resources.Density; -import com.android.resources.ResourceEnum; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Resource Qualifier for Screen Pixel Density. - */ -public final class DensityQualifier extends EnumBasedResourceQualifier { - private final static Pattern sDensityLegacyPattern = Pattern.compile("^(\\d+)dpi$");//$NON-NLS-1$ - - public static final String NAME = "Density"; - - private Density mValue = Density.MEDIUM; - - public DensityQualifier() { - // pass - } - - public DensityQualifier(Density value) { - mValue = value; - } - - public Density getValue() { - return mValue; - } - - @Override - ResourceEnum getEnumValue() { - return mValue; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return NAME; - } - - @Override - public int since() { - return 4; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - Density density = Density.getEnum(value); - if (density == null) { - - // attempt to read a legacy value. - Matcher m = sDensityLegacyPattern.matcher(value); - if (m.matches()) { - String v = m.group(1); - - try { - density = Density.getEnum(Integer.parseInt(v)); - } catch (NumberFormatException e) { - // looks like the string we extracted wasn't a valid number - // which really shouldn't happen since the regexp would have failed. - } - } - } - - if (density != null) { - DensityQualifier qualifier = new DensityQualifier(); - qualifier.mValue = density; - config.setDensityQualifier(qualifier); - return true; - } - - return false; - } - - @Override - public boolean isMatchFor(ResourceQualifier qualifier) { - if (qualifier instanceof DensityQualifier) { - // as long as there's a density qualifier, it's always a match. - // The best match will be found later. - return true; - } - - return false; - } - - @Override - public boolean isBetterMatchThan(ResourceQualifier compareTo, ResourceQualifier reference) { - if (compareTo == null) { - return true; - } - - DensityQualifier compareQ = (DensityQualifier)compareTo; - DensityQualifier referenceQ = (DensityQualifier)reference; - - if (compareQ.mValue == referenceQ.mValue) { - // what we have is already the best possible match (exact match) - return false; - } else if (mValue == referenceQ.mValue) { - // got new exact value, this is the best! - return true; - } else { - // in all case we're going to prefer the higher dpi. - // if reference is high, we want highest dpi. - // if reference is medium, we'll prefer to scale down high dpi, than scale up low dpi - // if reference if low, we'll prefer to scale down high than medium (2:1 over 4:3) - return mValue.getDpiValue() > compareQ.mValue.getDpiValue(); - } - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/DeviceConfigHelper.java b/ide_common/src/com/android/ide/common/resources/configuration/DeviceConfigHelper.java deleted file mode 100644 index 27eaa01..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/DeviceConfigHelper.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import com.android.annotations.Nullable; -import com.android.resources.NightMode; -import com.android.resources.UiMode; -import com.android.sdklib.devices.Device; -import com.android.sdklib.devices.Hardware; -import com.android.sdklib.devices.Screen; -import com.android.sdklib.devices.State; - -public class DeviceConfigHelper { - /** - * Returns a {@link FolderConfiguration} based on the given state - * - * @param state - * The {@link State} of the {@link Device} to base the - * {@link FolderConfiguration} on. Can be null. - * @return A {@link FolderConfiguration} based on the given {@link State}. - * If the given {@link State} is null, the result is also null; - */ - @Nullable - public static FolderConfiguration getFolderConfig(@Nullable State state) { - if (state == null) { - return null; - } - - Hardware hw = state.getHardware(); - - FolderConfiguration config = new FolderConfiguration(); - config.createDefault(); - Screen screen = hw.getScreen(); - config.setDensityQualifier(new DensityQualifier(screen.getPixelDensity())); - config.setNavigationMethodQualifier(new NavigationMethodQualifier(hw.getNav())); - ScreenDimensionQualifier sdq; - if (screen.getXDimension() > screen.getYDimension()) { - sdq = new ScreenDimensionQualifier(screen.getXDimension(), screen.getYDimension()); - } else { - sdq = new ScreenDimensionQualifier(screen.getYDimension(), screen.getXDimension()); - } - config.setScreenDimensionQualifier(sdq); - config.setScreenRatioQualifier(new ScreenRatioQualifier(screen.getRatio())); - config.setScreenSizeQualifier(new ScreenSizeQualifier(screen.getSize())); - config.setTextInputMethodQualifier(new TextInputMethodQualifier(hw.getKeyboard())); - config.setTouchTypeQualifier(new TouchScreenQualifier(screen.getMechanism())); - - config.setKeyboardStateQualifier(new KeyboardStateQualifier(state.getKeyState())); - config.setNavigationStateQualifier(new NavigationStateQualifier(state.getNavState())); - config.setScreenOrientationQualifier( - new ScreenOrientationQualifier(state.getOrientation())); - - config.updateScreenWidthAndHeight(); - - // Setup some default qualifiers - config.setUiModeQualifier(new UiModeQualifier(UiMode.NORMAL)); - config.setNightModeQualifier(new NightModeQualifier(NightMode.NOTNIGHT)); - config.setCountryCodeQualifier(new CountryCodeQualifier()); - config.setLanguageQualifier(new LanguageQualifier()); - config.setNetworkCodeQualifier(new NetworkCodeQualifier()); - config.setRegionQualifier(new RegionQualifier()); - config.setVersionQualifier(new VersionQualifier()); - - return config; - } - - /** - * Returns a {@link FolderConfiguration} based on the {@link State} given by - * the {@link Device} and the state name. - * - * @param d - * The {@link Device} to base the {@link FolderConfiguration} on. - * @param stateName - * The name of the state to base the {@link FolderConfiguration} - * on. - * @return The {@link FolderConfiguration} based on the determined - * {@link State}. If there is no {@link State} with the given state - * name for the given device, null is returned. - */ - @Nullable - public static FolderConfiguration getFolderConfig(Device d, String stateName) { - return getFolderConfig(d.getState(stateName)); - } - - /** - * Returns a {@link FolderConfiguration} based on the default {@link State} - * for the given {@link Device}. - * - * @param d - * The {@link Device} to generate the {@link FolderConfiguration} - * from. - * @return A {@link FolderConfiguration} based on the default {@link State} - * for the given {@link Device} - */ - public static FolderConfiguration getFolderConfig(Device d) { - return getFolderConfig(d.getDefaultState()); - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/EnumBasedResourceQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/EnumBasedResourceQualifier.java deleted file mode 100644 index 7bfda2d..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/EnumBasedResourceQualifier.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import com.android.resources.ResourceEnum; - -/** - * Base class for {@link ResourceQualifier} whose value is an {@link ResourceEnum}. - * - */ -abstract class EnumBasedResourceQualifier extends ResourceQualifier { - - abstract ResourceEnum getEnumValue(); - - @Override - public boolean isValid() { - return getEnumValue() != null; - } - - @Override - public boolean hasFakeValue() { - return getEnumValue().isFakeValue(); - } - - @Override - public boolean equals(Object qualifier) { - if (qualifier instanceof EnumBasedResourceQualifier) { - return getEnumValue() == ((EnumBasedResourceQualifier)qualifier).getEnumValue(); - } - - return false; - } - - @Override - public int hashCode() { - ResourceEnum value = getEnumValue(); - if (value != null) { - return value.hashCode(); - } - - return 0; - } - - /** - * Returns the string used to represent this qualifier in the folder name. - */ - @Override - public final String getFolderSegment() { - ResourceEnum value = getEnumValue(); - if (value != null) { - return value.getResourceValue(); - } - - return ""; //$NON-NLS-1$ - } - - - @Override - public String getShortDisplayValue() { - ResourceEnum value = getEnumValue(); - if (value != null) { - return value.getShortDisplayValue(); - } - - return ""; //$NON-NLS-1$ - } - - @Override - public String getLongDisplayValue() { - ResourceEnum value = getEnumValue(); - if (value != null) { - return value.getLongDisplayValue(); - } - - return ""; //$NON-NLS-1$ - } - -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/FolderConfiguration.java b/ide_common/src/com/android/ide/common/resources/configuration/FolderConfiguration.java deleted file mode 100644 index e2fe767..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/FolderConfiguration.java +++ /dev/null @@ -1,886 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import com.android.SdkConstants; -import com.android.resources.Density; -import com.android.resources.ResourceFolderType; -import com.android.resources.ScreenOrientation; - -import java.util.ArrayList; -import java.util.List; - - -/** - * Represents the configuration for Resource Folders. All the properties have a default - * value which means that the property is not set. - */ -public final class FolderConfiguration implements Comparable<FolderConfiguration> { - - private final static ResourceQualifier[] DEFAULT_QUALIFIERS; - - static { - // get the default qualifiers. - FolderConfiguration defaultConfig = new FolderConfiguration(); - defaultConfig.createDefault(); - DEFAULT_QUALIFIERS = defaultConfig.getQualifiers(); - } - - - private final ResourceQualifier[] mQualifiers = new ResourceQualifier[INDEX_COUNT]; - - private final static int INDEX_COUNTRY_CODE = 0; - private final static int INDEX_NETWORK_CODE = 1; - private final static int INDEX_LANGUAGE = 2; - private final static int INDEX_REGION = 3; - private final static int INDEX_SMALLEST_SCREEN_WIDTH = 4; - private final static int INDEX_SCREEN_WIDTH = 5; - private final static int INDEX_SCREEN_HEIGHT = 6; - private final static int INDEX_SCREEN_LAYOUT_SIZE = 7; - private final static int INDEX_SCREEN_RATIO = 8; - private final static int INDEX_SCREEN_ORIENTATION = 9; - private final static int INDEX_UI_MODE = 10; - private final static int INDEX_NIGHT_MODE = 11; - private final static int INDEX_PIXEL_DENSITY = 12; - private final static int INDEX_TOUCH_TYPE = 13; - private final static int INDEX_KEYBOARD_STATE = 14; - private final static int INDEX_TEXT_INPUT_METHOD = 15; - private final static int INDEX_NAVIGATION_STATE = 16; - private final static int INDEX_NAVIGATION_METHOD = 17; - private final static int INDEX_SCREEN_DIMENSION = 18; - private final static int INDEX_VERSION = 19; - private final static int INDEX_COUNT = 20; - - /** - * Creates a {@link FolderConfiguration} matching the folder segments. - * @param folderSegments The segments of the folder name. The first segments should contain - * the name of the folder - * @return a FolderConfiguration object, or null if the folder name isn't valid.. - */ - public static FolderConfiguration getConfig(String[] folderSegments) { - FolderConfiguration config = new FolderConfiguration(); - - // we are going to loop through the segments, and match them with the first - // available qualifier. If the segment doesn't match we try with the next qualifier. - // Because the order of the qualifier is fixed, we do not reset the first qualifier - // after each successful segment. - // If we run out of qualifier before processing all the segments, we fail. - - int qualifierIndex = 0; - int qualifierCount = DEFAULT_QUALIFIERS.length; - - for (int i = 1 ; i < folderSegments.length; i++) { - String seg = folderSegments[i]; - if (seg.length() > 0) { - while (qualifierIndex < qualifierCount && - DEFAULT_QUALIFIERS[qualifierIndex].checkAndSet(seg, config) == false) { - qualifierIndex++; - } - - // if we reached the end of the qualifier we didn't find a matching qualifier. - if (qualifierIndex == qualifierCount) { - return null; - } - - } else { - return null; - } - } - - return config; - } - - /** - * Returns the number of {@link ResourceQualifier} that make up a Folder configuration. - */ - public static int getQualifierCount() { - return INDEX_COUNT; - } - - /** - * Sets the config from the qualifiers of a given <var>config</var>. - * <p/>This is equivalent to <code>set(config, false)</code> - * @param config the configuration to set - * - * @see #set(FolderConfiguration, boolean) - */ - public void set(FolderConfiguration config) { - set(config, false /*nonFakeValuesOnly*/); - } - - /** - * Sets the config from the qualifiers of a given <var>config</var>. - * @param config the configuration to set - * @param nonFakeValuesOnly if set to true this ignore qualifiers for which the - * current value is a fake value. - * - * @see ResourceQualifier#hasFakeValue() - */ - public void set(FolderConfiguration config, boolean nonFakeValuesOnly) { - if (config != null) { - for (int i = 0 ; i < INDEX_COUNT ; i++) { - ResourceQualifier q = config.mQualifiers[i]; - if (nonFakeValuesOnly == false || q == null || q.hasFakeValue() == false) { - mQualifiers[i] = q; - } - } - } - } - - /** - * Reset the config. - * <p/>This makes qualifiers at all indices <code>null</code>. - */ - public void reset() { - for (int i = 0 ; i < INDEX_COUNT ; i++) { - mQualifiers[i] = null; - } - } - - /** - * Removes the qualifiers from the receiver if they are present (and valid) - * in the given configuration. - */ - public void substract(FolderConfiguration config) { - for (int i = 0 ; i < INDEX_COUNT ; i++) { - if (config.mQualifiers[i] != null && config.mQualifiers[i].isValid()) { - mQualifiers[i] = null; - } - } - } - - /** - * Adds the non-qualifiers from the given config. - * Qualifiers that are null in the given config do not change in the receiver. - */ - public void add(FolderConfiguration config) { - for (int i = 0 ; i < INDEX_COUNT ; i++) { - if (config.mQualifiers[i] != null) { - mQualifiers[i] = config.mQualifiers[i]; - } - } - } - - /** - * Returns the first invalid qualifier, or <code>null<code> if they are all valid (or if none - * exists). - */ - public ResourceQualifier getInvalidQualifier() { - for (int i = 0 ; i < INDEX_COUNT ; i++) { - if (mQualifiers[i] != null && mQualifiers[i].isValid() == false) { - return mQualifiers[i]; - } - } - - // all allocated qualifiers are valid, we return null. - return null; - } - - /** - * Returns whether the Region qualifier is valid. Region qualifier can only be present if a - * Language qualifier is present as well. - * @return true if the Region qualifier is valid. - */ - public boolean checkRegion() { - if (mQualifiers[INDEX_LANGUAGE] == null && mQualifiers[INDEX_REGION] != null) { - return false; - } - - return true; - } - - /** - * Adds a qualifier to the {@link FolderConfiguration} - * @param qualifier the {@link ResourceQualifier} to add. - */ - public void addQualifier(ResourceQualifier qualifier) { - if (qualifier instanceof CountryCodeQualifier) { - mQualifiers[INDEX_COUNTRY_CODE] = qualifier; - - } else if (qualifier instanceof NetworkCodeQualifier) { - mQualifiers[INDEX_NETWORK_CODE] = qualifier; - - } else if (qualifier instanceof LanguageQualifier) { - mQualifiers[INDEX_LANGUAGE] = qualifier; - - } else if (qualifier instanceof RegionQualifier) { - mQualifiers[INDEX_REGION] = qualifier; - - } else if (qualifier instanceof SmallestScreenWidthQualifier) { - mQualifiers[INDEX_SMALLEST_SCREEN_WIDTH] = qualifier; - - } else if (qualifier instanceof ScreenWidthQualifier) { - mQualifiers[INDEX_SCREEN_WIDTH] = qualifier; - - } else if (qualifier instanceof ScreenHeightQualifier) { - mQualifiers[INDEX_SCREEN_HEIGHT] = qualifier; - - } else if (qualifier instanceof ScreenSizeQualifier) { - mQualifiers[INDEX_SCREEN_LAYOUT_SIZE] = qualifier; - - } else if (qualifier instanceof ScreenRatioQualifier) { - mQualifiers[INDEX_SCREEN_RATIO] = qualifier; - - } else if (qualifier instanceof ScreenOrientationQualifier) { - mQualifiers[INDEX_SCREEN_ORIENTATION] = qualifier; - - } else if (qualifier instanceof UiModeQualifier) { - mQualifiers[INDEX_UI_MODE] = qualifier; - - } else if (qualifier instanceof NightModeQualifier) { - mQualifiers[INDEX_NIGHT_MODE] = qualifier; - - } else if (qualifier instanceof DensityQualifier) { - mQualifiers[INDEX_PIXEL_DENSITY] = qualifier; - - } else if (qualifier instanceof TouchScreenQualifier) { - mQualifiers[INDEX_TOUCH_TYPE] = qualifier; - - } else if (qualifier instanceof KeyboardStateQualifier) { - mQualifiers[INDEX_KEYBOARD_STATE] = qualifier; - - } else if (qualifier instanceof TextInputMethodQualifier) { - mQualifiers[INDEX_TEXT_INPUT_METHOD] = qualifier; - - } else if (qualifier instanceof NavigationStateQualifier) { - mQualifiers[INDEX_NAVIGATION_STATE] = qualifier; - - } else if (qualifier instanceof NavigationMethodQualifier) { - mQualifiers[INDEX_NAVIGATION_METHOD] = qualifier; - - } else if (qualifier instanceof ScreenDimensionQualifier) { - mQualifiers[INDEX_SCREEN_DIMENSION] = qualifier; - - } else if (qualifier instanceof VersionQualifier) { - mQualifiers[INDEX_VERSION] = qualifier; - - } - } - - /** - * Removes a given qualifier from the {@link FolderConfiguration}. - * @param qualifier the {@link ResourceQualifier} to remove. - */ - public void removeQualifier(ResourceQualifier qualifier) { - for (int i = 0 ; i < INDEX_COUNT ; i++) { - if (mQualifiers[i] == qualifier) { - mQualifiers[i] = null; - return; - } - } - } - - /** - * Returns a qualifier by its index. The total number of qualifiers can be accessed by - * {@link #getQualifierCount()}. - * @param index the index of the qualifier to return. - * @return the qualifier or null if there are none at the index. - */ - public ResourceQualifier getQualifier(int index) { - return mQualifiers[index]; - } - - public void setCountryCodeQualifier(CountryCodeQualifier qualifier) { - mQualifiers[INDEX_COUNTRY_CODE] = qualifier; - } - - public CountryCodeQualifier getCountryCodeQualifier() { - return (CountryCodeQualifier)mQualifiers[INDEX_COUNTRY_CODE]; - } - - public void setNetworkCodeQualifier(NetworkCodeQualifier qualifier) { - mQualifiers[INDEX_NETWORK_CODE] = qualifier; - } - - public NetworkCodeQualifier getNetworkCodeQualifier() { - return (NetworkCodeQualifier)mQualifiers[INDEX_NETWORK_CODE]; - } - - public void setLanguageQualifier(LanguageQualifier qualifier) { - mQualifiers[INDEX_LANGUAGE] = qualifier; - } - - public LanguageQualifier getLanguageQualifier() { - return (LanguageQualifier)mQualifiers[INDEX_LANGUAGE]; - } - - public void setRegionQualifier(RegionQualifier qualifier) { - mQualifiers[INDEX_REGION] = qualifier; - } - - public RegionQualifier getRegionQualifier() { - return (RegionQualifier)mQualifiers[INDEX_REGION]; - } - - public void setSmallestScreenWidthQualifier(SmallestScreenWidthQualifier qualifier) { - mQualifiers[INDEX_SMALLEST_SCREEN_WIDTH] = qualifier; - } - - public SmallestScreenWidthQualifier getSmallestScreenWidthQualifier() { - return (SmallestScreenWidthQualifier) mQualifiers[INDEX_SMALLEST_SCREEN_WIDTH]; - } - - public void setScreenWidthQualifier(ScreenWidthQualifier qualifier) { - mQualifiers[INDEX_SCREEN_WIDTH] = qualifier; - } - - public ScreenWidthQualifier getScreenWidthQualifier() { - return (ScreenWidthQualifier) mQualifiers[INDEX_SCREEN_WIDTH]; - } - - public void setScreenHeightQualifier(ScreenHeightQualifier qualifier) { - mQualifiers[INDEX_SCREEN_HEIGHT] = qualifier; - } - - public ScreenHeightQualifier getScreenHeightQualifier() { - return (ScreenHeightQualifier) mQualifiers[INDEX_SCREEN_HEIGHT]; - } - - public void setScreenSizeQualifier(ScreenSizeQualifier qualifier) { - mQualifiers[INDEX_SCREEN_LAYOUT_SIZE] = qualifier; - } - - public ScreenSizeQualifier getScreenSizeQualifier() { - return (ScreenSizeQualifier)mQualifiers[INDEX_SCREEN_LAYOUT_SIZE]; - } - - public void setScreenRatioQualifier(ScreenRatioQualifier qualifier) { - mQualifiers[INDEX_SCREEN_RATIO] = qualifier; - } - - public ScreenRatioQualifier getScreenRatioQualifier() { - return (ScreenRatioQualifier)mQualifiers[INDEX_SCREEN_RATIO]; - } - - public void setScreenOrientationQualifier(ScreenOrientationQualifier qualifier) { - mQualifiers[INDEX_SCREEN_ORIENTATION] = qualifier; - } - - public ScreenOrientationQualifier getScreenOrientationQualifier() { - return (ScreenOrientationQualifier)mQualifiers[INDEX_SCREEN_ORIENTATION]; - } - - public void setUiModeQualifier(UiModeQualifier qualifier) { - mQualifiers[INDEX_UI_MODE] = qualifier; - } - - public UiModeQualifier getUiModeQualifier() { - return (UiModeQualifier)mQualifiers[INDEX_UI_MODE]; - } - - public void setNightModeQualifier(NightModeQualifier qualifier) { - mQualifiers[INDEX_NIGHT_MODE] = qualifier; - } - - public NightModeQualifier getNightModeQualifier() { - return (NightModeQualifier)mQualifiers[INDEX_NIGHT_MODE]; - } - - public void setDensityQualifier(DensityQualifier qualifier) { - mQualifiers[INDEX_PIXEL_DENSITY] = qualifier; - } - - public DensityQualifier getDensityQualifier() { - return (DensityQualifier)mQualifiers[INDEX_PIXEL_DENSITY]; - } - - public void setTouchTypeQualifier(TouchScreenQualifier qualifier) { - mQualifiers[INDEX_TOUCH_TYPE] = qualifier; - } - - public TouchScreenQualifier getTouchTypeQualifier() { - return (TouchScreenQualifier)mQualifiers[INDEX_TOUCH_TYPE]; - } - - public void setKeyboardStateQualifier(KeyboardStateQualifier qualifier) { - mQualifiers[INDEX_KEYBOARD_STATE] = qualifier; - } - - public KeyboardStateQualifier getKeyboardStateQualifier() { - return (KeyboardStateQualifier)mQualifiers[INDEX_KEYBOARD_STATE]; - } - - public void setTextInputMethodQualifier(TextInputMethodQualifier qualifier) { - mQualifiers[INDEX_TEXT_INPUT_METHOD] = qualifier; - } - - public TextInputMethodQualifier getTextInputMethodQualifier() { - return (TextInputMethodQualifier)mQualifiers[INDEX_TEXT_INPUT_METHOD]; - } - - public void setNavigationStateQualifier(NavigationStateQualifier qualifier) { - mQualifiers[INDEX_NAVIGATION_STATE] = qualifier; - } - - public NavigationStateQualifier getNavigationStateQualifier() { - return (NavigationStateQualifier)mQualifiers[INDEX_NAVIGATION_STATE]; - } - - public void setNavigationMethodQualifier(NavigationMethodQualifier qualifier) { - mQualifiers[INDEX_NAVIGATION_METHOD] = qualifier; - } - - public NavigationMethodQualifier getNavigationMethodQualifier() { - return (NavigationMethodQualifier)mQualifiers[INDEX_NAVIGATION_METHOD]; - } - - public void setScreenDimensionQualifier(ScreenDimensionQualifier qualifier) { - mQualifiers[INDEX_SCREEN_DIMENSION] = qualifier; - } - - public ScreenDimensionQualifier getScreenDimensionQualifier() { - return (ScreenDimensionQualifier)mQualifiers[INDEX_SCREEN_DIMENSION]; - } - - public void setVersionQualifier(VersionQualifier qualifier) { - mQualifiers[INDEX_VERSION] = qualifier; - } - - public VersionQualifier getVersionQualifier() { - return (VersionQualifier)mQualifiers[INDEX_VERSION]; - } - - /** - * Updates the {@link SmallestScreenWidthQualifier}, {@link ScreenWidthQualifier}, and - * {@link ScreenHeightQualifier} based on the (required) values of - * {@link ScreenDimensionQualifier} {@link DensityQualifier}, and - * {@link ScreenOrientationQualifier}. - * - * Also the density cannot be {@link Density#NODPI} as it's not valid on a device. - */ - public void updateScreenWidthAndHeight() { - - ResourceQualifier sizeQ = mQualifiers[INDEX_SCREEN_DIMENSION]; - ResourceQualifier densityQ = mQualifiers[INDEX_PIXEL_DENSITY]; - ResourceQualifier orientQ = mQualifiers[INDEX_SCREEN_ORIENTATION]; - - if (sizeQ != null && densityQ != null && orientQ != null) { - Density density = ((DensityQualifier) densityQ).getValue(); - if (density == Density.NODPI) { - return; - } - - ScreenOrientation orientation = ((ScreenOrientationQualifier) orientQ).getValue(); - - int size1 = ((ScreenDimensionQualifier) sizeQ).getValue1(); - int size2 = ((ScreenDimensionQualifier) sizeQ).getValue2(); - - // make sure size1 is the biggest (should be the case, but make sure) - if (size1 < size2) { - int a = size1; - size1 = size2; - size2 = a; - } - - // compute the dp. round them up since we want -w480dp to match a 480.5dp screen - int dp1 = (int) Math.ceil(size1 * Density.DEFAULT_DENSITY / density.getDpiValue()); - int dp2 = (int) Math.ceil(size2 * Density.DEFAULT_DENSITY / density.getDpiValue()); - - setSmallestScreenWidthQualifier(new SmallestScreenWidthQualifier(dp2)); - - switch (orientation) { - case PORTRAIT: - setScreenWidthQualifier(new ScreenWidthQualifier(dp2)); - setScreenHeightQualifier(new ScreenHeightQualifier(dp1)); - break; - case LANDSCAPE: - setScreenWidthQualifier(new ScreenWidthQualifier(dp1)); - setScreenHeightQualifier(new ScreenHeightQualifier(dp2)); - break; - case SQUARE: - setScreenWidthQualifier(new ScreenWidthQualifier(dp2)); - setScreenHeightQualifier(new ScreenHeightQualifier(dp2)); - break; - } - } - } - - /** - * Returns whether an object is equals to the receiver. - */ - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (obj instanceof FolderConfiguration) { - FolderConfiguration fc = (FolderConfiguration)obj; - for (int i = 0 ; i < INDEX_COUNT ; i++) { - ResourceQualifier qualifier = mQualifiers[i]; - ResourceQualifier fcQualifier = fc.mQualifiers[i]; - if (qualifier != null) { - if (qualifier.equals(fcQualifier) == false) { - return false; - } - } else if (fcQualifier != null) { - return false; - } - } - - return true; - } - - return false; - } - - @Override - public int hashCode() { - return toString().hashCode(); - } - - /** - * Returns whether the Configuration has only default values. - */ - public boolean isDefault() { - for (ResourceQualifier irq : mQualifiers) { - if (irq != null) { - return false; - } - } - - return true; - } - - /** - * Returns the name of a folder with the configuration. - */ - public String getFolderName(ResourceFolderType folder) { - StringBuilder result = new StringBuilder(folder.getName()); - - for (ResourceQualifier qualifier : mQualifiers) { - if (qualifier != null) { - String segment = qualifier.getFolderSegment(); - if (segment != null && segment.length() > 0) { - result.append(SdkConstants.RES_QUALIFIER_SEP); - result.append(segment); - } - } - } - - return result.toString(); - } - - /** - * Returns {@link #toDisplayString()}. - */ - @Override - public String toString() { - return toDisplayString(); - } - - /** - * Returns a string valid for display purpose. - */ - public String toDisplayString() { - if (isDefault()) { - return "default"; - } - - StringBuilder result = null; - int index = 0; - ResourceQualifier qualifier = null; - - // pre- language/region qualifiers - while (index < INDEX_LANGUAGE) { - qualifier = mQualifiers[index++]; - if (qualifier != null) { - if (result == null) { - result = new StringBuilder(); - } else { - result.append(", "); //$NON-NLS-1$ - } - result.append(qualifier.getLongDisplayValue()); - - } - } - - // process the language/region qualifier in a custom way, if there are both non null. - if (mQualifiers[INDEX_LANGUAGE] != null && mQualifiers[INDEX_REGION] != null) { - String language = mQualifiers[INDEX_LANGUAGE].getLongDisplayValue(); - String region = mQualifiers[INDEX_REGION].getLongDisplayValue(); - - if (result == null) { - result = new StringBuilder(); - } else { - result.append(", "); //$NON-NLS-1$ - } - result.append(String.format("Locale %s_%s", language, region)); //$NON-NLS-1$ - - index += 2; - } - - // post language/region qualifiers. - while (index < INDEX_COUNT) { - qualifier = mQualifiers[index++]; - if (qualifier != null) { - if (result == null) { - result = new StringBuilder(); - } else { - result.append(", "); //$NON-NLS-1$ - } - result.append(qualifier.getLongDisplayValue()); - - } - } - - return result == null ? null : result.toString(); - } - - @Override - public int compareTo(FolderConfiguration folderConfig) { - // default are always at the top. - if (isDefault()) { - if (folderConfig.isDefault()) { - return 0; - } - return -1; - } - - // now we compare the qualifiers - for (int i = 0 ; i < INDEX_COUNT; i++) { - ResourceQualifier qualifier1 = mQualifiers[i]; - ResourceQualifier qualifier2 = folderConfig.mQualifiers[i]; - - if (qualifier1 == null) { - if (qualifier2 == null) { - continue; - } else { - return -1; - } - } else { - if (qualifier2 == null) { - return 1; - } else { - int result = qualifier1.compareTo(qualifier2); - - if (result == 0) { - continue; - } - - return result; - } - } - } - - // if we arrive here, all the qualifier matches - return 0; - } - - /** - * Returns the best matching {@link Configurable} for this configuration. - * - * @param configurables the list of {@link Configurable} to choose from. - * - * @return an item from the given list of {@link Configurable} or null. - * - * @see http://d.android.com/guide/topics/resources/resources-i18n.html#best-match - */ - public Configurable findMatchingConfigurable(List<? extends Configurable> configurables) { - // - // 1: eliminate resources that contradict the reference configuration - // 2: pick next qualifier type - // 3: check if any resources use this qualifier, if no, back to 2, else move on to 4. - // 4: eliminate resources that don't use this qualifier. - // 5: if more than one resource left, go back to 2. - // - // The precedence of the qualifiers is more important than the number of qualifiers that - // exactly match the device. - - // 1: eliminate resources that contradict - ArrayList<Configurable> matchingConfigurables = new ArrayList<Configurable>(); - for (int i = 0 ; i < configurables.size(); i++) { - Configurable res = configurables.get(i); - - if (res.getConfiguration().isMatchFor(this)) { - matchingConfigurables.add(res); - } - } - - // if there is only one match, just take it - if (matchingConfigurables.size() == 1) { - return matchingConfigurables.get(0); - } else if (matchingConfigurables.size() == 0) { - return null; - } - - // 2. Loop on the qualifiers, and eliminate matches - final int count = FolderConfiguration.getQualifierCount(); - for (int q = 0 ; q < count ; q++) { - // look to see if one configurable has this qualifier. - // At the same time also record the best match value for the qualifier (if applicable). - - // The reference value, to find the best match. - // Note that this qualifier could be null. In which case any qualifier found in the - // possible match, will all be considered best match. - ResourceQualifier referenceQualifier = getQualifier(q); - - boolean found = false; - ResourceQualifier bestMatch = null; // this is to store the best match. - for (Configurable configurable : matchingConfigurables) { - ResourceQualifier qualifier = configurable.getConfiguration().getQualifier(q); - if (qualifier != null) { - // set the flag. - found = true; - - // Now check for a best match. If the reference qualifier is null , - // any qualifier is a "best" match (we don't need to record all of them. - // Instead the non compatible ones are removed below) - if (referenceQualifier != null) { - if (qualifier.isBetterMatchThan(bestMatch, referenceQualifier)) { - bestMatch = qualifier; - } - } - } - } - - // 4. If a configurable has a qualifier at the current index, remove all the ones that - // do not have one, or whose qualifier value does not equal the best match found above - // unless there's no reference qualifier, in which case they are all considered - // "best" match. - if (found) { - for (int i = 0 ; i < matchingConfigurables.size(); ) { - Configurable configurable = matchingConfigurables.get(i); - ResourceQualifier qualifier = configurable.getConfiguration().getQualifier(q); - - if (qualifier == null) { - // this resources has no qualifier of this type: rejected. - matchingConfigurables.remove(configurable); - } else if (referenceQualifier != null && bestMatch != null && - bestMatch.equals(qualifier) == false) { - // there's a reference qualifier and there is a better match for it than - // this resource, so we reject it. - matchingConfigurables.remove(configurable); - } else { - // looks like we keep this resource, move on to the next one. - i++; - } - } - - // at this point we may have run out of matching resources before going - // through all the qualifiers. - if (matchingConfigurables.size() < 2) { - break; - } - } - } - - // Because we accept resources whose configuration have qualifiers where the reference - // configuration doesn't, we can end up with more than one match. In this case, we just - // take the first one. - if (matchingConfigurables.size() == 0) { - return null; - } - return matchingConfigurables.get(0); - } - - - /** - * Returns whether the configuration is a match for the given reference config. - * <p/>A match means that, for each qualifier of this config - * <ul> - * <li>The reference config has no value set - * <li>or, the qualifier of the reference config is a match. Depending on the qualifier type - * this does not mean the same exact value.</li> - * </ul> - * @param referenceConfig The reference configuration to test against. - * @return true if the configuration matches. - */ - public boolean isMatchFor(FolderConfiguration referenceConfig) { - if (referenceConfig == null) { - return false; - } - - for (int i = 0 ; i < INDEX_COUNT ; i++) { - ResourceQualifier testQualifier = mQualifiers[i]; - ResourceQualifier referenceQualifier = referenceConfig.mQualifiers[i]; - - // it's only a non match if both qualifiers are non-null, and they don't match. - if (testQualifier != null && referenceQualifier != null && - testQualifier.isMatchFor(referenceQualifier) == false) { - return false; - } - } - - return true; - } - - /** - * Returns the index of the first non null {@link ResourceQualifier} starting at index - * <var>startIndex</var> - * @param startIndex - * @return -1 if no qualifier was found. - */ - public int getHighestPriorityQualifier(int startIndex) { - for (int i = startIndex ; i < INDEX_COUNT ; i++) { - if (mQualifiers[i] != null) { - return i; - } - } - - return -1; - } - - /** - * Create default qualifiers. - * <p/>This creates qualifiers with no values for all indices. - */ - public void createDefault() { - mQualifiers[INDEX_COUNTRY_CODE] = new CountryCodeQualifier(); - mQualifiers[INDEX_NETWORK_CODE] = new NetworkCodeQualifier(); - mQualifiers[INDEX_LANGUAGE] = new LanguageQualifier(); - mQualifiers[INDEX_REGION] = new RegionQualifier(); - mQualifiers[INDEX_SMALLEST_SCREEN_WIDTH] = new SmallestScreenWidthQualifier(); - mQualifiers[INDEX_SCREEN_WIDTH] = new ScreenWidthQualifier(); - mQualifiers[INDEX_SCREEN_HEIGHT] = new ScreenHeightQualifier(); - mQualifiers[INDEX_SCREEN_LAYOUT_SIZE] = new ScreenSizeQualifier(); - mQualifiers[INDEX_SCREEN_RATIO] = new ScreenRatioQualifier(); - mQualifiers[INDEX_SCREEN_ORIENTATION] = new ScreenOrientationQualifier(); - mQualifiers[INDEX_UI_MODE] = new UiModeQualifier(); - mQualifiers[INDEX_NIGHT_MODE] = new NightModeQualifier(); - mQualifiers[INDEX_PIXEL_DENSITY] = new DensityQualifier(); - mQualifiers[INDEX_TOUCH_TYPE] = new TouchScreenQualifier(); - mQualifiers[INDEX_KEYBOARD_STATE] = new KeyboardStateQualifier(); - mQualifiers[INDEX_TEXT_INPUT_METHOD] = new TextInputMethodQualifier(); - mQualifiers[INDEX_NAVIGATION_STATE] = new NavigationStateQualifier(); - mQualifiers[INDEX_NAVIGATION_METHOD] = new NavigationMethodQualifier(); - mQualifiers[INDEX_SCREEN_DIMENSION] = new ScreenDimensionQualifier(); - mQualifiers[INDEX_VERSION] = new VersionQualifier(); - } - - /** - * Returns an array of all the non null qualifiers. - */ - public ResourceQualifier[] getQualifiers() { - int count = 0; - for (int i = 0 ; i < INDEX_COUNT ; i++) { - if (mQualifiers[i] != null) { - count++; - } - } - - ResourceQualifier[] array = new ResourceQualifier[count]; - int index = 0; - for (int i = 0 ; i < INDEX_COUNT ; i++) { - if (mQualifiers[i] != null) { - array[index++] = mQualifiers[i]; - } - } - - return array; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/KeyboardStateQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/KeyboardStateQualifier.java deleted file mode 100644 index 1397808..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/KeyboardStateQualifier.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import com.android.resources.KeyboardState; -import com.android.resources.ResourceEnum; - -/** - * Resource Qualifier for keyboard state. - */ -public final class KeyboardStateQualifier extends EnumBasedResourceQualifier { - - public static final String NAME = "Keyboard State"; - - private KeyboardState mValue = null; - - public KeyboardStateQualifier() { - // pass - } - - public KeyboardStateQualifier(KeyboardState value) { - mValue = value; - } - - public KeyboardState getValue() { - return mValue; - } - - @Override - ResourceEnum getEnumValue() { - return mValue; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return "Keyboard"; - } - - @Override - public int since() { - return 1; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - KeyboardState orientation = KeyboardState.getEnum(value); - if (orientation != null) { - KeyboardStateQualifier qualifier = new KeyboardStateQualifier(); - qualifier.mValue = orientation; - config.setKeyboardStateQualifier(qualifier); - return true; - } - - return false; - } - - @Override - public boolean isMatchFor(ResourceQualifier qualifier) { - if (qualifier instanceof KeyboardStateQualifier) { - KeyboardStateQualifier referenceQualifier = (KeyboardStateQualifier)qualifier; - - // special case where EXPOSED can be used for SOFT - if (referenceQualifier.mValue == KeyboardState.SOFT && - mValue == KeyboardState.EXPOSED) { - return true; - } - - return referenceQualifier.mValue == mValue; - } - - return false; - } - - @Override - public boolean isBetterMatchThan(ResourceQualifier compareTo, ResourceQualifier reference) { - if (compareTo == null) { - return true; - } - - KeyboardStateQualifier compareQualifier = (KeyboardStateQualifier)compareTo; - KeyboardStateQualifier referenceQualifier = (KeyboardStateQualifier)reference; - - if (referenceQualifier.mValue == KeyboardState.SOFT) { // only case where there could be a - // better qualifier - // only return true if it's a better value. - if (compareQualifier.mValue == KeyboardState.EXPOSED && mValue == KeyboardState.SOFT) { - return true; - } - } - - return false; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/LanguageQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/LanguageQualifier.java deleted file mode 100644 index 76514e2..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/LanguageQualifier.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import java.util.Locale; -import java.util.regex.Pattern; - -/** - * Resource Qualifier for Language. - */ -public final class LanguageQualifier extends ResourceQualifier { - private final static Pattern sLanguagePattern = Pattern.compile("^[a-z]{2}$"); //$NON-NLS-1$ - - public static final String FAKE_LANG_VALUE = "__"; //$NON-NLS-1$ - public static final String NAME = "Language"; - - private String mValue; - - /** - * Creates and returns a qualifier from the given folder segment. If the segment is incorrect, - * <code>null</code> is returned. - * @param segment the folder segment from which to create a qualifier. - * @return a new {@link LanguageQualifier} object or <code>null</code> - */ - public static LanguageQualifier getQualifier(String segment) { - if (sLanguagePattern.matcher(segment).matches()) { - LanguageQualifier qualifier = new LanguageQualifier(); - qualifier.mValue = segment; - - return qualifier; - } - return null; - } - - /** - * Returns the folder name segment for the given value. This is equivalent to calling - * {@link #toString()} on a {@link LanguageQualifier} object. - * @param value the value of the qualifier, as returned by {@link #getValue()}. - */ - public static String getFolderSegment(String value) { - String segment = value.toLowerCase(Locale.US); - if (sLanguagePattern.matcher(segment).matches()) { - return segment; - } - - return null; - } - - public LanguageQualifier() { - - } - - public LanguageQualifier(String value) { - mValue = value; - } - - public String getValue() { - if (mValue != null) { - return mValue; - } - - return ""; //$NON-NLS-1$ - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return NAME; - } - - @Override - public int since() { - return 1; - } - - @Override - public boolean isValid() { - return mValue != null; - } - - @Override - public boolean hasFakeValue() { - return FAKE_LANG_VALUE.equals(mValue); - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - LanguageQualifier qualifier = getQualifier(value); - if (qualifier != null) { - config.setLanguageQualifier(qualifier); - return true; - } - - return false; - } - - @Override - public boolean equals(Object qualifier) { - if (qualifier instanceof LanguageQualifier) { - if (mValue == null) { - return ((LanguageQualifier)qualifier).mValue == null; - } - return mValue.equals(((LanguageQualifier)qualifier).mValue); - } - - return false; - } - - @Override - public int hashCode() { - if (mValue != null) { - return mValue.hashCode(); - } - - return 0; - } - - /** - * Returns the string used to represent this qualifier in the folder name. - */ - @Override - public String getFolderSegment() { - if (mValue != null) { - return getFolderSegment(mValue); - } - - return ""; //$NON-NLS-1$ - } - - @Override - public String getShortDisplayValue() { - if (mValue != null) { - return mValue; - } - - return ""; //$NON-NLS-1$ - } - - @Override - public String getLongDisplayValue() { - if (mValue != null) { - return String.format("Language %s", mValue); - } - - return ""; //$NON-NLS-1$ - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/NavigationMethodQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/NavigationMethodQualifier.java deleted file mode 100644 index f40bc6c..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/NavigationMethodQualifier.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import com.android.resources.Navigation; -import com.android.resources.ResourceEnum; - -/** - * Resource Qualifier for Navigation Method. - */ -public final class NavigationMethodQualifier extends EnumBasedResourceQualifier { - - public static final String NAME = "Navigation Method"; - - private Navigation mValue; - - public NavigationMethodQualifier() { - // pass - } - - public NavigationMethodQualifier(Navigation value) { - mValue = value; - } - - public Navigation getValue() { - return mValue; - } - - @Override - ResourceEnum getEnumValue() { - return mValue; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return NAME; - } - - @Override - public int since() { - return 1; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - Navigation method = Navigation.getEnum(value); - if (method != null) { - NavigationMethodQualifier qualifier = new NavigationMethodQualifier(method); - config.setNavigationMethodQualifier(qualifier); - return true; - } - - return false; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/NavigationStateQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/NavigationStateQualifier.java deleted file mode 100644 index 91b81df..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/NavigationStateQualifier.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import com.android.resources.NavigationState; -import com.android.resources.ResourceEnum; - -/** - * Resource Qualifier for navigation state. - */ -public final class NavigationStateQualifier extends EnumBasedResourceQualifier { - - public static final String NAME = "Navigation State"; - - private NavigationState mValue = null; - - public NavigationStateQualifier() { - // pass - } - - public NavigationStateQualifier(NavigationState value) { - mValue = value; - } - - public NavigationState getValue() { - return mValue; - } - - @Override - ResourceEnum getEnumValue() { - return mValue; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return NAME; - } - - @Override - public int since() { - return 1; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - NavigationState state = NavigationState.getEnum(value); - if (state != null) { - NavigationStateQualifier qualifier = new NavigationStateQualifier(); - qualifier.mValue = state; - config.setNavigationStateQualifier(qualifier); - return true; - } - - return false; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/NetworkCodeQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/NetworkCodeQualifier.java deleted file mode 100644 index 1ef2015..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/NetworkCodeQualifier.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Resource Qualifier for Mobile Network Code Pixel Density. - */ -public final class NetworkCodeQualifier extends ResourceQualifier { - /** Default pixel density value. This means the property is not set. */ - private final static int DEFAULT_CODE = -1; - - private final static Pattern sNetworkCodePattern = Pattern.compile("^mnc(\\d{1,3})$"); //$NON-NLS-1$ - - private final int mCode; - - public final static String NAME = "Mobile Network Code"; - - /** - * Creates and returns a qualifier from the given folder segment. If the segment is incorrect, - * <code>null</code> is returned. - * @param segment the folder segment from which to create a qualifier. - * @return a new {@link CountryCodeQualifier} object or <code>null</code> - */ - public static NetworkCodeQualifier getQualifier(String segment) { - Matcher m = sNetworkCodePattern.matcher(segment); - if (m.matches()) { - String v = m.group(1); - - int code = -1; - try { - code = Integer.parseInt(v); - } catch (NumberFormatException e) { - // looks like the string we extracted wasn't a valid number. - return null; - } - - NetworkCodeQualifier qualifier = new NetworkCodeQualifier(code); - return qualifier; - } - - return null; - } - - /** - * Returns the folder name segment for the given value. This is equivalent to calling - * {@link #toString()} on a {@link NetworkCodeQualifier} object. - * @param code the value of the qualifier, as returned by {@link #getCode()}. - */ - public static String getFolderSegment(int code) { - if (code != DEFAULT_CODE && code >= 1 && code <= 999) { // code is 1-3 digit. - return String.format("mnc%1$d", code); //$NON-NLS-1$ - } - - return ""; //$NON-NLS-1$ - } - - public NetworkCodeQualifier() { - this(DEFAULT_CODE); - } - - public NetworkCodeQualifier(int code) { - mCode = code; - } - - public int getCode() { - return mCode; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return "Network Code"; - } - - @Override - public int since() { - return 1; - } - - @Override - public boolean isValid() { - return mCode != DEFAULT_CODE; - } - - @Override - public boolean hasFakeValue() { - return false; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - Matcher m = sNetworkCodePattern.matcher(value); - if (m.matches()) { - String v = m.group(1); - - int code = -1; - try { - code = Integer.parseInt(v); - } catch (NumberFormatException e) { - // looks like the string we extracted wasn't a valid number. - return false; - } - - NetworkCodeQualifier qualifier = new NetworkCodeQualifier(code); - config.setNetworkCodeQualifier(qualifier); - return true; - } - - return false; - } - - @Override - public boolean equals(Object qualifier) { - if (qualifier instanceof NetworkCodeQualifier) { - return mCode == ((NetworkCodeQualifier)qualifier).mCode; - } - - return false; - } - - @Override - public int hashCode() { - return mCode; - } - - /** - * Returns the string used to represent this qualifier in the folder name. - */ - @Override - public String getFolderSegment() { - return getFolderSegment(mCode); - } - - @Override - public String getShortDisplayValue() { - if (mCode != DEFAULT_CODE) { - return String.format("MNC %1$d", mCode); - } - - return ""; //$NON-NLS-1$ - } - - @Override - public String getLongDisplayValue() { - return getShortDisplayValue(); - } - -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/NightModeQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/NightModeQualifier.java deleted file mode 100644 index d3b6760..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/NightModeQualifier.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import com.android.resources.NightMode; -import com.android.resources.ResourceEnum; - -/** - * Resource Qualifier for Navigation Method. - */ -public final class NightModeQualifier extends EnumBasedResourceQualifier { - - public static final String NAME = "Night Mode"; - - private NightMode mValue; - - public NightModeQualifier() { - // pass - } - - public NightModeQualifier(NightMode value) { - mValue = value; - } - - public NightMode getValue() { - return mValue; - } - - @Override - ResourceEnum getEnumValue() { - return mValue; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return "Night Mode"; - } - - @Override - public int since() { - return 8; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - NightMode mode = NightMode.getEnum(value); - if (mode != null) { - NightModeQualifier qualifier = new NightModeQualifier(mode); - config.setNightModeQualifier(qualifier); - return true; - } - - return false; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/RegionQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/RegionQualifier.java deleted file mode 100644 index bd033bd..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/RegionQualifier.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Resource Qualifier for Region. - */ -public final class RegionQualifier extends ResourceQualifier { - private final static Pattern sRegionPattern = Pattern.compile("^r([A-Z]{2})$"); //$NON-NLS-1$ - - public static final String FAKE_REGION_VALUE = "__"; //$NON-NLS-1$ - public static final String NAME = "Region"; - - private String mValue; - - /** - * Creates and returns a qualifier from the given folder segment. If the segment is incorrect, - * <code>null</code> is returned. - * @param segment the folder segment from which to create a qualifier. - * @return a new {@link RegionQualifier} object or <code>null</code> - */ - public static RegionQualifier getQualifier(String segment) { - Matcher m = sRegionPattern.matcher(segment); - if (m.matches()) { - RegionQualifier qualifier = new RegionQualifier(); - qualifier.mValue = m.group(1); - - return qualifier; - } - return null; - } - - /** - * Returns the folder name segment for the given value. This is equivalent to calling - * {@link #toString()} on a {@link RegionQualifier} object. - * @param value the value of the qualifier, as returned by {@link #getValue()}. - */ - public static String getFolderSegment(String value) { - if (value != null) { - // See http://developer.android.com/reference/java/util/Locale.html#default_locale - String segment = "r" + value.toUpperCase(Locale.US); //$NON-NLS-1$ - if (sRegionPattern.matcher(segment).matches()) { - return segment; - } - } - - return ""; //$NON-NLS-1$ - } - - public RegionQualifier() { - - } - - public RegionQualifier(String value) { - mValue = value; - } - - public String getValue() { - if (mValue != null) { - return mValue; - } - - return ""; //$NON-NLS-1$ - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return NAME; - } - - @Override - public int since() { - return 1; - } - - @Override - public boolean isValid() { - return mValue != null; - } - - @Override - public boolean hasFakeValue() { - return FAKE_REGION_VALUE.equals(mValue); - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - RegionQualifier qualifier = getQualifier(value); - if (qualifier != null) { - config.setRegionQualifier(qualifier); - return true; - } - - return false; - } - - @Override - public boolean equals(Object qualifier) { - if (qualifier instanceof RegionQualifier) { - if (mValue == null) { - return ((RegionQualifier)qualifier).mValue == null; - } - return mValue.equals(((RegionQualifier)qualifier).mValue); - } - - return false; - } - - @Override - public int hashCode() { - if (mValue != null) { - return mValue.hashCode(); - } - - return 0; - } - - /** - * Returns the string used to represent this qualifier in the folder name. - */ - @Override - public String getFolderSegment() { - return getFolderSegment(mValue); - } - - @Override - public String getShortDisplayValue() { - if (mValue != null) { - return mValue; - } - - return ""; //$NON-NLS-1$ - } - - @Override - public String getLongDisplayValue() { - if (mValue != null) { - return String.format("Region %s", mValue); - } - - return ""; //$NON-NLS-1$ - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/ResourceQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/ResourceQualifier.java deleted file mode 100644 index 2997c8f..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/ResourceQualifier.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - - -/** - * Base class for resource qualifiers. - * <p/>The resource qualifier classes are designed as immutable. - */ -public abstract class ResourceQualifier implements Comparable<ResourceQualifier> { - - /** - * Returns the human readable name of the qualifier. - */ - public abstract String getName(); - - /** - * Returns a shorter human readable name for the qualifier. - * @see #getName() - */ - public abstract String getShortName(); - - /** - * Returns when this qualifier was added to Android. - */ - public abstract int since(); - - /** - * Whether this qualifier is deprecated. - */ - public boolean deprecated() { - return false; - } - - /** - * Returns whether the qualifier has a valid filter value. - */ - public abstract boolean isValid(); - - /** - * Returns whether the qualifier has a fake value. - * <p/>Fake values are used internally and should not be used as real qualifier value. - */ - public abstract boolean hasFakeValue(); - - /** - * Check if the value is valid for this qualifier, and if so sets the value - * into a Folder Configuration. - * @param value The value to check and set. Must not be null. - * @param config The folder configuration to receive the value. Must not be null. - * @return true if the value was valid and was set. - */ - public abstract boolean checkAndSet(String value, FolderConfiguration config); - - /** - * Returns a string formated to be used in a folder name. - * <p/>This is declared as abstract to force children classes to implement it. - */ - public abstract String getFolderSegment(); - - /** - * Returns whether the given qualifier is a match for the receiver. - * <p/>The default implementation returns the result of {@link #equals(Object)}. - * <p/>Children class that re-implements this must implement - * {@link #isBetterMatchThan(ResourceQualifier, ResourceQualifier)} too. - * @param qualifier the reference qualifier - * @return true if the receiver is a match. - */ - public boolean isMatchFor(ResourceQualifier qualifier) { - return equals(qualifier); - } - - /** - * Returns true if the receiver is a better match for the given <var>reference</var> than - * the given <var>compareTo</var> comparable. - * @param compareTo The {@link ResourceQualifier} to compare to. Can be null, in which - * case the method must return <code>true</code>. - * @param reference The reference qualifier value for which the match is. - * @return true if the receiver is a better match. - */ - public boolean isBetterMatchThan(ResourceQualifier compareTo, ResourceQualifier reference) { - // the default is to always return false. This gives less overhead than always returning - // true, as it would only compare same values anyway. - return false; - } - - @Override - public String toString() { - return getFolderSegment(); - } - - /** - * Returns a string formatted for display purpose. - */ - public abstract String getShortDisplayValue(); - - /** - * Returns a string formatted for display purpose. - */ - public abstract String getLongDisplayValue(); - - /** - * Returns <code>true</code> if both objects are equal. - * <p/>This is declared as abstract to force children classes to implement it. - */ - @Override - public abstract boolean equals(Object object); - - /** - * Returns a hash code value for the object. - * <p/>This is declared as abstract to force children classes to implement it. - */ - @Override - public abstract int hashCode(); - - @Override - public final int compareTo(ResourceQualifier o) { - return toString().compareTo(o.toString()); - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/ScreenDimensionQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/ScreenDimensionQualifier.java deleted file mode 100644 index dce6c68..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/ScreenDimensionQualifier.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Resource Qualifier for Screen Dimension. - */ -public final class ScreenDimensionQualifier extends ResourceQualifier { - /** Default screen size value. This means the property is not set */ - final static int DEFAULT_SIZE = -1; - - private final static Pattern sDimensionPattern = Pattern.compile( - "^(\\d+)x(\\d+)$"); //$NON-NLS-1$ - - public static final String NAME = "Screen Dimension"; - - /** Screen size 1 value. This is not size X or Y because the folder name always - * contains the biggest size first. So if the qualifier is 400x200, size 1 will always be - * 400 but that'll be X in landscape and Y in portrait. - * Default value is <code>DEFAULT_SIZE</code> */ - private int mValue1 = DEFAULT_SIZE; - - /** Screen size 2 value. This is not size X or Y because the folder name always - * contains the biggest size first. So if the qualifier is 400x200, size 2 will always be - * 200 but that'll be Y in landscape and X in portrait. - * Default value is <code>DEFAULT_SIZE</code> */ - private int mValue2 = DEFAULT_SIZE; - - public ScreenDimensionQualifier() { - // pass - } - - public ScreenDimensionQualifier(int value1, int value2) { - mValue1 = value1; - mValue2 = value2; - } - - public int getValue1() { - return mValue1; - } - - public int getValue2() { - return mValue2; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return "Dimension"; - } - - @Override - public int since() { - return 1; - } - - @Override - public boolean deprecated() { - return true; - } - - @Override - public boolean isValid() { - return mValue1 != DEFAULT_SIZE && mValue2 != DEFAULT_SIZE; - } - - @Override - public boolean hasFakeValue() { - return false; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - Matcher m = sDimensionPattern.matcher(value); - if (m.matches()) { - String d1 = m.group(1); - String d2 = m.group(2); - - ScreenDimensionQualifier qualifier = getQualifier(d1, d2); - if (qualifier != null) { - config.setScreenDimensionQualifier(qualifier); - return true; - } - } - return false; - } - - @Override - public boolean equals(Object qualifier) { - if (qualifier instanceof ScreenDimensionQualifier) { - ScreenDimensionQualifier q = (ScreenDimensionQualifier)qualifier; - return (mValue1 == q.mValue1 && mValue2 == q.mValue2); - } - - return false; - } - - @Override - public int hashCode() { - return toString().hashCode(); - } - - public static ScreenDimensionQualifier getQualifier(String size1, String size2) { - try { - int s1 = Integer.parseInt(size1); - int s2 = Integer.parseInt(size2); - - ScreenDimensionQualifier qualifier = new ScreenDimensionQualifier(); - - if (s1 > s2) { - qualifier.mValue1 = s1; - qualifier.mValue2 = s2; - } else { - qualifier.mValue1 = s2; - qualifier.mValue2 = s1; - } - - return qualifier; - } catch (NumberFormatException e) { - // looks like the string we extracted wasn't a valid number. - } - - return null; - } - - /** - * Returns the string used to represent this qualifier in the folder name. - */ - @Override - public String getFolderSegment() { - return String.format("%1$dx%2$d", mValue1, mValue2); //$NON-NLS-1$ - } - - @Override - public String getShortDisplayValue() { - if (isValid()) { - return String.format("%1$dx%2$d", mValue1, mValue2); - } - - return ""; //$NON-NLS-1$ - } - - @Override - public String getLongDisplayValue() { - if (isValid()) { - return String.format("Screen resolution %1$dx%2$d", mValue1, mValue2); - } - - return ""; //$NON-NLS-1$ - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/ScreenHeightQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/ScreenHeightQualifier.java deleted file mode 100644 index 08bba61..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/ScreenHeightQualifier.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Resource Qualifier for Screen Pixel Density. - */ -public final class ScreenHeightQualifier extends ResourceQualifier { - /** Default screen size value. This means the property is not set */ - final static int DEFAULT_SIZE = -1; - - private final static Pattern sParsePattern = Pattern.compile("^h(\\d+)dp$");//$NON-NLS-1$ - private final static String sPrintPattern = "h%1$ddp"; - - public static final String NAME = "Screen Height"; - - private int mValue = DEFAULT_SIZE; - - public ScreenHeightQualifier() { - // pass - } - - public ScreenHeightQualifier(int value) { - mValue = value; - } - - public int getValue() { - return mValue; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return NAME; - } - - @Override - public int since() { - return 13; - } - - @Override - public boolean hasFakeValue() { - return false; - } - - @Override - public boolean isValid() { - return mValue != DEFAULT_SIZE; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - Matcher m = sParsePattern.matcher(value); - if (m.matches()) { - String v = m.group(1); - - ScreenHeightQualifier qualifier = getQualifier(v); - if (qualifier != null) { - config.setScreenHeightQualifier(qualifier); - return true; - } - } - - return false; - } - - public static ScreenHeightQualifier getQualifier(String value) { - try { - int dp = Integer.parseInt(value); - - ScreenHeightQualifier qualifier = new ScreenHeightQualifier(); - qualifier.mValue = dp; - return qualifier; - - } catch (NumberFormatException e) { - } - - return null; - } - - @Override - public boolean isMatchFor(ResourceQualifier qualifier) { - // this is the match only of the current dp value is lower or equal to the - if (qualifier instanceof ScreenHeightQualifier) { - return mValue <= ((ScreenHeightQualifier) qualifier).mValue; - } - - return false; - } - - @Override - public boolean isBetterMatchThan(ResourceQualifier compareTo, ResourceQualifier reference) { - if (compareTo == null) { - return true; - } - - ScreenHeightQualifier compareQ = (ScreenHeightQualifier)compareTo; - ScreenHeightQualifier referenceQ = (ScreenHeightQualifier)reference; - - if (compareQ.mValue == referenceQ.mValue) { - // what we have is already the best possible match (exact match) - return false; - } else if (mValue == referenceQ.mValue) { - // got new exact value, this is the best! - return true; - } else { - // get the qualifier that has the width that is the closest to the reference, but not - // above. (which is guaranteed when this is called as isMatchFor is called first. - return mValue > compareQ.mValue; - } - } - - @Override - public String getFolderSegment() { - return String.format(sPrintPattern, mValue); - } - - @Override - public String getShortDisplayValue() { - if (isValid()) { - return getFolderSegment(); - } - - return ""; //$NON-NLS-1$ - } - - @Override - public String getLongDisplayValue() { - if (isValid()) { - return getFolderSegment(); - } - - return ""; //$NON-NLS-1$ - } - - - @Override - public int hashCode() { - return mValue; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - ScreenHeightQualifier other = (ScreenHeightQualifier) obj; - if (mValue != other.mValue) { - return false; - } - return true; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/ScreenOrientationQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/ScreenOrientationQualifier.java deleted file mode 100644 index 732a078..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/ScreenOrientationQualifier.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import com.android.resources.ResourceEnum; -import com.android.resources.ScreenOrientation; - -/** - * Resource Qualifier for Screen Orientation. - */ -public final class ScreenOrientationQualifier extends EnumBasedResourceQualifier { - - public static final String NAME = "Screen Orientation"; - - private ScreenOrientation mValue = null; - - public ScreenOrientationQualifier() { - } - - public ScreenOrientationQualifier(ScreenOrientation value) { - mValue = value; - } - - public ScreenOrientation getValue() { - return mValue; - } - - @Override - ResourceEnum getEnumValue() { - return mValue; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return "Orientation"; - } - - @Override - public int since() { - return 1; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - ScreenOrientation orientation = ScreenOrientation.getEnum(value); - if (orientation != null) { - ScreenOrientationQualifier qualifier = new ScreenOrientationQualifier(orientation); - config.setScreenOrientationQualifier(qualifier); - return true; - } - - return false; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/ScreenRatioQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/ScreenRatioQualifier.java deleted file mode 100644 index b45946b..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/ScreenRatioQualifier.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import com.android.resources.ResourceEnum; -import com.android.resources.ScreenRatio; - -public class ScreenRatioQualifier extends EnumBasedResourceQualifier { - - public static final String NAME = "Screen Ratio"; - - private ScreenRatio mValue = null; - - public ScreenRatioQualifier() { - } - - public ScreenRatioQualifier(ScreenRatio value) { - mValue = value; - } - - public ScreenRatio getValue() { - return mValue; - } - - @Override - ResourceEnum getEnumValue() { - return mValue; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return "Ratio"; - } - - @Override - public int since() { - return 4; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - ScreenRatio size = ScreenRatio.getEnum(value); - if (size != null) { - ScreenRatioQualifier qualifier = new ScreenRatioQualifier(size); - config.setScreenRatioQualifier(qualifier); - return true; - } - - return false; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/ScreenSizeQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/ScreenSizeQualifier.java deleted file mode 100644 index 77193a2..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/ScreenSizeQualifier.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import com.android.resources.ResourceEnum; -import com.android.resources.ScreenSize; - -/** - * Resource Qualifier for Screen Size. Size can be "small", "normal", "large" and "x-large" - */ -public class ScreenSizeQualifier extends EnumBasedResourceQualifier { - - public static final String NAME = "Screen Size"; - - private ScreenSize mValue = null; - - - public ScreenSizeQualifier() { - } - - public ScreenSizeQualifier(ScreenSize value) { - mValue = value; - } - - public ScreenSize getValue() { - return mValue; - } - - @Override - ResourceEnum getEnumValue() { - return mValue; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return "Size"; - } - - @Override - public int since() { - return 4; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - ScreenSize size = ScreenSize.getEnum(value); - if (size != null) { - ScreenSizeQualifier qualifier = new ScreenSizeQualifier(size); - config.setScreenSizeQualifier(qualifier); - return true; - } - - return false; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/ScreenWidthQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/ScreenWidthQualifier.java deleted file mode 100644 index ab9134b..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/ScreenWidthQualifier.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Resource Qualifier for Screen Pixel Density. - */ -public final class ScreenWidthQualifier extends ResourceQualifier { - /** Default screen size value. This means the property is not set */ - final static int DEFAULT_SIZE = -1; - - private final static Pattern sParsePattern = Pattern.compile("^w(\\d+)dp$"); //$NON-NLS-1$ - private final static String sPrintPattern = "w%1$ddp"; //$NON-NLS-1$ - - public static final String NAME = "Screen Width"; - - private int mValue = DEFAULT_SIZE; - - public ScreenWidthQualifier() { - // pass - } - - public ScreenWidthQualifier(int value) { - mValue = value; - } - - public int getValue() { - return mValue; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return NAME; - } - - @Override - public int since() { - return 13; - } - - @Override - public boolean hasFakeValue() { - return false; - } - - @Override - public boolean isValid() { - return mValue != DEFAULT_SIZE; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - Matcher m = sParsePattern.matcher(value); - if (m.matches()) { - String v = m.group(1); - - ScreenWidthQualifier qualifier = getQualifier(v); - if (qualifier != null) { - config.setScreenWidthQualifier(qualifier); - return true; - } - } - - return false; - } - - public static ScreenWidthQualifier getQualifier(String value) { - try { - int dp = Integer.parseInt(value); - - ScreenWidthQualifier qualifier = new ScreenWidthQualifier(); - qualifier.mValue = dp; - return qualifier; - - } catch (NumberFormatException e) { - } - - return null; - } - - @Override - public boolean isMatchFor(ResourceQualifier qualifier) { - // this is the match only of the current dp value is lower or equal to the - if (qualifier instanceof ScreenWidthQualifier) { - return mValue <= ((ScreenWidthQualifier) qualifier).mValue; - } - - return false; - } - - @Override - public boolean isBetterMatchThan(ResourceQualifier compareTo, ResourceQualifier reference) { - if (compareTo == null) { - return true; - } - - ScreenWidthQualifier compareQ = (ScreenWidthQualifier)compareTo; - ScreenWidthQualifier referenceQ = (ScreenWidthQualifier)reference; - - if (compareQ.mValue == referenceQ.mValue) { - // what we have is already the best possible match (exact match) - return false; - } else if (mValue == referenceQ.mValue) { - // got new exact value, this is the best! - return true; - } else { - // get the qualifier that has the width that is the closest to the reference, but not - // above. (which is guaranteed when this is called as isMatchFor is called first. - return mValue > compareQ.mValue; - } - } - - @Override - public String getFolderSegment() { - return String.format(sPrintPattern, mValue); - } - - @Override - public String getShortDisplayValue() { - if (isValid()) { - return getFolderSegment(); - } - - return ""; //$NON-NLS-1$ - } - - @Override - public String getLongDisplayValue() { - if (isValid()) { - return getFolderSegment(); - } - - return ""; //$NON-NLS-1$ - } - - @Override - public int hashCode() { - return mValue; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - ScreenWidthQualifier other = (ScreenWidthQualifier) obj; - if (mValue != other.mValue) { - return false; - } - return true; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/SmallestScreenWidthQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/SmallestScreenWidthQualifier.java deleted file mode 100644 index 35d1ab1..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/SmallestScreenWidthQualifier.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Resource Qualifier for Screen Pixel Density. - */ -public final class SmallestScreenWidthQualifier extends ResourceQualifier { - /** Default screen size value. This means the property is not set */ - final static int DEFAULT_SIZE = -1; - - private final static Pattern sParsePattern = Pattern.compile("^sw(\\d+)dp$"); //$NON-NLS-1$ - private final static String sPrintPattern = "sw%1$ddp"; //$NON-NLS-1$ - - public static final String NAME = "Smallest Screen Width"; - - private int mValue = DEFAULT_SIZE; - - public SmallestScreenWidthQualifier() { - // pass - } - - public SmallestScreenWidthQualifier(int value) { - mValue = value; - } - - public int getValue() { - return mValue; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return NAME; - } - - @Override - public int since() { - return 13; - } - - @Override - public boolean hasFakeValue() { - return false; - } - - @Override - public boolean isValid() { - return mValue != DEFAULT_SIZE; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - Matcher m = sParsePattern.matcher(value); - if (m.matches()) { - String v = m.group(1); - - SmallestScreenWidthQualifier qualifier = getQualifier(v); - if (qualifier != null) { - config.setSmallestScreenWidthQualifier(qualifier); - return true; - } - } - - return false; - } - - public static SmallestScreenWidthQualifier getQualifier(String value) { - try { - int dp = Integer.parseInt(value); - - SmallestScreenWidthQualifier qualifier = new SmallestScreenWidthQualifier(); - qualifier.mValue = dp; - return qualifier; - - } catch (NumberFormatException e) { - } - - return null; - } - - @Override - public boolean isMatchFor(ResourceQualifier qualifier) { - // this is the match only of the current dp value is lower or equal to the - if (qualifier instanceof SmallestScreenWidthQualifier) { - return mValue <= ((SmallestScreenWidthQualifier) qualifier).mValue; - } - - return false; - } - - @Override - public boolean isBetterMatchThan(ResourceQualifier compareTo, ResourceQualifier reference) { - if (compareTo == null) { - return true; - } - - SmallestScreenWidthQualifier compareQ = (SmallestScreenWidthQualifier)compareTo; - SmallestScreenWidthQualifier referenceQ = (SmallestScreenWidthQualifier)reference; - - if (compareQ.mValue == referenceQ.mValue) { - // what we have is already the best possible match (exact match) - return false; - } else if (mValue == referenceQ.mValue) { - // got new exact value, this is the best! - return true; - } else { - // get the qualifier that has the width that is the closest to the reference, but not - // above. (which is guaranteed when this is called as isMatchFor is called first. - return mValue > compareQ.mValue; - } - } - - @Override - public String getFolderSegment() { - return String.format(sPrintPattern, mValue); - } - - @Override - public String getShortDisplayValue() { - if (isValid()) { - return getFolderSegment(); - } - - return ""; //$NON-NLS-1$ - } - - @Override - public String getLongDisplayValue() { - if (isValid()) { - return getFolderSegment(); - } - - return ""; //$NON-NLS-1$ - } - - @Override - public int hashCode() { - return mValue; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - SmallestScreenWidthQualifier other = (SmallestScreenWidthQualifier) obj; - if (mValue != other.mValue) { - return false; - } - return true; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/TextInputMethodQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/TextInputMethodQualifier.java deleted file mode 100644 index 784d43d..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/TextInputMethodQualifier.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import com.android.resources.Keyboard; -import com.android.resources.ResourceEnum; - -/** - * Resource Qualifier for Text Input Method. - */ -public final class TextInputMethodQualifier extends EnumBasedResourceQualifier { - - public static final String NAME = "Text Input Method"; - - private Keyboard mValue; - - - public TextInputMethodQualifier() { - // pass - } - - public TextInputMethodQualifier(Keyboard value) { - mValue = value; - } - - public Keyboard getValue() { - return mValue; - } - - @Override - ResourceEnum getEnumValue() { - return mValue; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return "Text Input"; - } - - @Override - public int since() { - return 1; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - Keyboard method = Keyboard.getEnum(value); - if (method != null) { - TextInputMethodQualifier qualifier = new TextInputMethodQualifier(); - qualifier.mValue = method; - config.setTextInputMethodQualifier(qualifier); - return true; - } - - return false; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/TouchScreenQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/TouchScreenQualifier.java deleted file mode 100644 index dce9f1d..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/TouchScreenQualifier.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import com.android.resources.ResourceEnum; -import com.android.resources.TouchScreen; - - -/** - * Resource Qualifier for Touch Screen type. - */ -public final class TouchScreenQualifier extends EnumBasedResourceQualifier { - - public static final String NAME = "Touch Screen"; - - private TouchScreen mValue; - - public TouchScreenQualifier() { - // pass - } - - public TouchScreenQualifier(TouchScreen touchValue) { - mValue = touchValue; - } - - public TouchScreen getValue() { - return mValue; - } - - @Override - ResourceEnum getEnumValue() { - return mValue; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return NAME; - } - - @Override - public int since() { - return 1; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - TouchScreen type = TouchScreen.getEnum(value); - if (type != null) { - TouchScreenQualifier qualifier = new TouchScreenQualifier(); - qualifier.mValue = type; - config.setTouchTypeQualifier(qualifier); - return true; - } - - return false; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/UiModeQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/UiModeQualifier.java deleted file mode 100644 index 1e302c5..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/UiModeQualifier.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import com.android.resources.ResourceEnum; -import com.android.resources.UiMode; - -/** - * Resource Qualifier for UI Mode. - */ -public final class UiModeQualifier extends EnumBasedResourceQualifier { - - public static final String NAME = "UI Mode"; - - private UiMode mValue; - - public UiModeQualifier() { - // pass - } - - public UiModeQualifier(UiMode value) { - mValue = value; - } - - public UiMode getValue() { - return mValue; - } - - @Override - ResourceEnum getEnumValue() { - return mValue; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return NAME; - } - - @Override - public int since() { - return 8; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - UiMode mode = UiMode.getEnum(value); - if (mode != null) { - UiModeQualifier qualifier = new UiModeQualifier(mode); - config.setUiModeQualifier(qualifier); - return true; - } - - return false; - } - - @Override - public boolean isMatchFor(ResourceQualifier qualifier) { - // only normal is a match for all UI mode, because it's not an actual mode. - if (mValue == UiMode.NORMAL) { - return true; - } - - // others must be an exact match - return ((UiModeQualifier)qualifier).mValue == mValue; - } - - @Override - public boolean isBetterMatchThan(ResourceQualifier compareTo, ResourceQualifier reference) { - if (compareTo == null) { - return true; - } - - UiModeQualifier compareQualifier = (UiModeQualifier)compareTo; - UiModeQualifier referenceQualifier = (UiModeQualifier)reference; - - if (compareQualifier.getValue() == referenceQualifier.getValue()) { - // what we have is already the best possible match (exact match) - return false; - } else if (mValue == referenceQualifier.mValue) { - // got new exact value, this is the best! - return true; - } else if (mValue == UiMode.NORMAL) { - // else "normal" can be a match in case there's no exact match - return true; - } - - return false; - } -} diff --git a/ide_common/src/com/android/ide/common/resources/configuration/VersionQualifier.java b/ide_common/src/com/android/ide/common/resources/configuration/VersionQualifier.java deleted file mode 100644 index 078d4af..0000000 --- a/ide_common/src/com/android/ide/common/resources/configuration/VersionQualifier.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 - * - * 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.common.resources.configuration; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Resource Qualifier for Platform Version. - */ -public final class VersionQualifier extends ResourceQualifier { - /** Default pixel density value. This means the property is not set. */ - private final static int DEFAULT_VERSION = -1; - - private final static Pattern sVersionPattern = Pattern.compile("^v(\\d+)$");//$NON-NLS-1$ - - private int mVersion = DEFAULT_VERSION; - - public static final String NAME = "Platform Version"; - - /** - * Creates and returns a qualifier from the given folder segment. If the segment is incorrect, - * <code>null</code> is returned. - * @param segment the folder segment from which to create a qualifier. - * @return a new {@link VersionQualifier} object or <code>null</code> - */ - public static VersionQualifier getQualifier(String segment) { - Matcher m = sVersionPattern.matcher(segment); - if (m.matches()) { - String v = m.group(1); - - int code = -1; - try { - code = Integer.parseInt(v); - } catch (NumberFormatException e) { - // looks like the string we extracted wasn't a valid number. - return null; - } - - VersionQualifier qualifier = new VersionQualifier(); - qualifier.mVersion = code; - return qualifier; - } - - return null; - } - - /** - * Returns the folder name segment for the given value. This is equivalent to calling - * {@link #toString()} on a {@link VersionQualifier} object. - * @param version the value of the qualifier, as returned by {@link #getVersion()}. - */ - public static String getFolderSegment(int version) { - if (version != DEFAULT_VERSION) { - return String.format("v%1$d", version); //$NON-NLS-1$ - } - - return ""; //$NON-NLS-1$ - } - - public VersionQualifier(int apiLevel) { - mVersion = apiLevel; - } - - public VersionQualifier() { - //pass - } - - public int getVersion() { - return mVersion; - } - - @Override - public String getName() { - return NAME; - } - - @Override - public String getShortName() { - return "Version"; - } - - @Override - public int since() { - return 1; - } - - @Override - public boolean isValid() { - return mVersion != DEFAULT_VERSION; - } - - @Override - public boolean hasFakeValue() { - return false; - } - - @Override - public boolean checkAndSet(String value, FolderConfiguration config) { - VersionQualifier qualifier = getQualifier(value); - if (qualifier != null) { - config.setVersionQualifier(qualifier); - return true; - } - - return false; - } - - @Override - public boolean equals(Object qualifier) { - if (qualifier instanceof VersionQualifier) { - return mVersion == ((VersionQualifier)qualifier).mVersion; - } - - return false; - } - - @Override - public boolean isMatchFor(ResourceQualifier qualifier) { - if (qualifier instanceof VersionQualifier) { - // it is considered a match if the api level is equal or lower to the given qualifier - return mVersion <= ((VersionQualifier) qualifier).mVersion; - } - - return false; - } - - @Override - public boolean isBetterMatchThan(ResourceQualifier compareTo, ResourceQualifier reference) { - if (compareTo == null) { - return true; - } - - VersionQualifier compareQ = (VersionQualifier)compareTo; - VersionQualifier referenceQ = (VersionQualifier)reference; - - if (compareQ.mVersion == referenceQ.mVersion) { - // what we have is already the best possible match (exact match) - return false; - } else if (mVersion == referenceQ.mVersion) { - // got new exact value, this is the best! - return true; - } else { - // in all case we're going to prefer the higher version (since they have been filtered - // to not be too high - return mVersion > compareQ.mVersion; - } - } - - @Override - public int hashCode() { - return mVersion; - } - - /** - * Returns the string used to represent this qualifier in the folder name. - */ - @Override - public String getFolderSegment() { - return getFolderSegment(mVersion); - } - - @Override - public String getShortDisplayValue() { - if (mVersion != DEFAULT_VERSION) { - return String.format("API %1$d", mVersion); - } - - return ""; //$NON-NLS-1$ - } - - @Override - public String getLongDisplayValue() { - if (mVersion != DEFAULT_VERSION) { - return String.format("API Level %1$d", mVersion); - } - - return ""; //$NON-NLS-1$ - } -} |