• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.ide.common.resources;
18 
19 import com.android.ide.common.rendering.api.ResourceValue;
20 import com.android.ide.common.resources.configuration.FolderConfiguration;
21 import com.android.resources.ResourceType;
22 
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Comparator;
26 import java.util.List;
27 
28 /**
29  * An android resource.
30  *
31  * This is a representation of the resource, not of its value(s). It gives access to all
32  * the source files that generate this particular resource which then can be used to access
33  * the actual value(s).
34  *
35  * @see ResourceFile#getResources(ResourceType, ResourceRepository)
36  */
37 public class ResourceItem implements Comparable<ResourceItem> {
38 
39     private final static Comparator<ResourceFile> sComparator = new Comparator<ResourceFile>() {
40         @Override
41         public int compare(ResourceFile file1, ResourceFile file2) {
42             // get both FolderConfiguration and compare them
43             FolderConfiguration fc1 = file1.getFolder().getConfiguration();
44             FolderConfiguration fc2 = file2.getFolder().getConfiguration();
45 
46             return fc1.compareTo(fc2);
47         }
48     };
49 
50     private final String mName;
51 
52     /**
53      * List of files generating this ResourceItem.
54      */
55     private final List<ResourceFile> mFiles = new ArrayList<ResourceFile>();
56 
57     /**
58      * Constructs a new ResourceItem.
59      * @param name the name of the resource as it appears in the XML and R.java files.
60      */
ResourceItem(String name)61     public ResourceItem(String name) {
62         mName = name;
63     }
64 
65     /**
66      * Returns the name of the resource.
67      */
getName()68     public final String getName() {
69         return mName;
70     }
71 
72     /**
73      * Compares the {@link ResourceItem} to another.
74      * @param other the ResourceItem to be compared to.
75      */
76     @Override
compareTo(ResourceItem other)77     public int compareTo(ResourceItem other) {
78         return mName.compareTo(other.mName);
79     }
80 
81     /**
82      * Returns whether the resource is editable directly.
83      * <p/>
84      * This is typically the case for resources that don't have alternate versions, or resources
85      * of type {@link ResourceType#ID} that aren't declared inline.
86      */
isEditableDirectly()87     public boolean isEditableDirectly() {
88         return hasAlternates() == false;
89     }
90 
91     /**
92      * Returns whether the ID resource has been declared inline inside another resource XML file.
93      * If the resource type is not {@link ResourceType#ID}, this will always return {@code false}.
94      */
isDeclaredInline()95     public boolean isDeclaredInline() {
96         return false;
97     }
98 
99     /**
100      * Returns a {@link ResourceValue} for this item based on the given configuration.
101      * If the ResourceItem has several source files, one will be selected based on the config.
102      * @param type the type of the resource. This is necessary because ResourceItem doesn't embed
103      *     its type, but ResourceValue does.
104      * @param referenceConfig the config of the resource item.
105      * @param isFramework whether the resource is a framework value. Same as the type.
106      * @return a ResourceValue or null if none match the config.
107      */
getResourceValue(ResourceType type, FolderConfiguration referenceConfig, boolean isFramework)108     public ResourceValue getResourceValue(ResourceType type, FolderConfiguration referenceConfig,
109             boolean isFramework) {
110         // look for the best match for the given configuration
111         // the match has to be of type ResourceFile since that's what the input list contains
112         ResourceFile match = (ResourceFile) referenceConfig.findMatchingConfigurable(mFiles);
113 
114         if (match != null) {
115             // get the value of this configured resource.
116             return match.getValue(type, mName);
117         }
118 
119         return null;
120     }
121 
122     /**
123      * Adds a new source file.
124      * @param file the source file.
125      */
add(ResourceFile file)126     protected void add(ResourceFile file) {
127         mFiles.add(file);
128     }
129 
130     /**
131      * Removes a file from the list of source files.
132      * @param file the file to remove
133      */
removeFile(ResourceFile file)134     protected void removeFile(ResourceFile file) {
135         mFiles.remove(file);
136     }
137 
138     /**
139      * Returns {@code true} if the item has no source file.
140      * @return
141      */
hasNoSourceFile()142     protected boolean hasNoSourceFile() {
143         return mFiles.size() == 0;
144     }
145 
146     /**
147      * Reset the item by emptying its source file list.
148      */
reset()149     protected void reset() {
150         mFiles.clear();
151     }
152 
153     /**
154      * Returns the sorted list of {@link ResourceItem} objects for this resource item.
155      */
getSourceFileArray()156     public ResourceFile[] getSourceFileArray() {
157         ArrayList<ResourceFile> list = new ArrayList<ResourceFile>();
158         list.addAll(mFiles);
159 
160         Collections.sort(list, sComparator);
161 
162         return list.toArray(new ResourceFile[list.size()]);
163     }
164 
165     /**
166      * Returns the list of source file for this resource.
167      */
getSourceFileList()168     public List<ResourceFile> getSourceFileList() {
169         return Collections.unmodifiableList(mFiles);
170     }
171 
172     /**
173      * Returns if the resource has at least one non-default version.
174      *
175      * @see ResourceFile#getConfiguration()
176      * @see FolderConfiguration#isDefault()
177      */
hasAlternates()178     public boolean hasAlternates() {
179         for (ResourceFile file : mFiles) {
180             if (file.getFolder().getConfiguration().isDefault() == false) {
181                 return true;
182             }
183         }
184 
185         return false;
186     }
187 
188     /**
189      * Returns whether the resource has a default version, with no qualifier.
190      *
191      * @see ResourceFile#getConfiguration()
192      * @see FolderConfiguration#isDefault()
193      */
hasDefault()194     public boolean hasDefault() {
195         for (ResourceFile file : mFiles) {
196             if (file.getFolder().getConfiguration().isDefault()) {
197                 return true;
198             }
199         }
200 
201         // We only want to return false if there's no default and more than 0 items.
202         return (mFiles.size() == 0);
203     }
204 
205     /**
206      * Returns the number of alternate versions for this resource.
207      *
208      * @see ResourceFile#getConfiguration()
209      * @see FolderConfiguration#isDefault()
210      */
getAlternateCount()211     public int getAlternateCount() {
212         int count = 0;
213         for (ResourceFile file : mFiles) {
214             if (file.getFolder().getConfiguration().isDefault() == false) {
215                 count++;
216             }
217         }
218 
219         return count;
220     }
221 
222     /**
223      * Returns a formatted string usable in an XML to use for the {@link ResourceItem}.
224      * @param system Whether this is a system resource or a project resource.
225      * @return a string in the format @[type]/[name]
226      */
getXmlString(ResourceType type, boolean system)227     public String getXmlString(ResourceType type, boolean system) {
228         if (type == ResourceType.ID && isDeclaredInline()) {
229             return (system ? "@android:" : "@+") + type.getName() + "/" + mName; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
230         }
231 
232         return (system ? "@android:" : "@") + type.getName() + "/" + mName; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
233     }
234 
235     @Override
toString()236     public String toString() {
237         return "ResourceItem [mName=" + mName + ", mFiles=" + mFiles + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
238     }
239 }
240