• 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         public int compare(ResourceFile file1, ResourceFile file2) {
41             // get both FolderConfiguration and compare them
42             FolderConfiguration fc1 = file1.getFolder().getConfiguration();
43             FolderConfiguration fc2 = file2.getFolder().getConfiguration();
44 
45             return fc1.compareTo(fc2);
46         }
47     };
48 
49     private final String mName;
50 
51     /**
52      * List of files generating this ResourceItem.
53      */
54     private final List<ResourceFile> mFiles = new ArrayList<ResourceFile>();
55 
56     /**
57      * Constructs a new ResourceItem.
58      * @param name the name of the resource as it appears in the XML and R.java files.
59      */
ResourceItem(String name)60     public ResourceItem(String name) {
61         mName = name;
62     }
63 
64     /**
65      * Returns the name of the resource.
66      */
getName()67     public final String getName() {
68         return mName;
69     }
70 
71     /**
72      * Compares the {@link ResourceItem} to another.
73      * @param other the ResourceItem to be compared to.
74      */
compareTo(ResourceItem other)75     public int compareTo(ResourceItem other) {
76         return mName.compareTo(other.mName);
77     }
78 
79     /**
80      * Returns whether the resource is editable directly.
81      * <p/>
82      * This is typically the case for resources that don't have alternate versions, or resources
83      * of type {@link ResourceType#ID} that aren't declared inline.
84      */
isEditableDirectly()85     public boolean isEditableDirectly() {
86         return hasAlternates() == false;
87     }
88 
89     /**
90      * Returns whether the ID resource has been declared inline inside another resource XML file.
91      * If the resource type is not {@link ResourceType#ID}, this will always return {@code false}.
92      */
isDeclaredInline()93     public boolean isDeclaredInline() {
94         return false;
95     }
96 
97     /**
98      * Returns a {@link ResourceValue} for this item based on the given configuration.
99      * If the ResourceItem has several source files, one will be selected based on the config.
100      * @param type the type of the resource. This is necessary because ResourceItem doesn't embed
101      *     its type, but ResourceValue does.
102      * @param referenceConfig the config of the resource item.
103      * @param isFramework whether the resource is a framework value. Same as the type.
104      * @return a ResourceValue or null if none match the config.
105      */
getResourceValue(ResourceType type, FolderConfiguration referenceConfig, boolean isFramework)106     public ResourceValue getResourceValue(ResourceType type, FolderConfiguration referenceConfig,
107             boolean isFramework) {
108         // look for the best match for the given configuration
109         // the match has to be of type ResourceFile since that's what the input list contains
110         ResourceFile match = (ResourceFile) referenceConfig.findMatchingConfigurable(mFiles);
111 
112         if (match != null) {
113             // get the value of this configured resource.
114             return match.getValue(type, mName);
115         }
116 
117         return null;
118     }
119 
120     /**
121      * Adds a new source file.
122      * @param file the source file.
123      */
add(ResourceFile file)124     protected void add(ResourceFile file) {
125         mFiles.add(file);
126     }
127 
128     /**
129      * Removes a file from the list of source files.
130      * @param file the file to remove
131      */
removeFile(ResourceFile file)132     protected void removeFile(ResourceFile file) {
133         mFiles.remove(file);
134     }
135 
136     /**
137      * Returns {@code true} if the item has no source file.
138      * @return
139      */
hasNoSourceFile()140     protected boolean hasNoSourceFile() {
141         return mFiles.size() == 0;
142     }
143 
144     /**
145      * Reset the item by emptying its source file list.
146      */
reset()147     protected void reset() {
148         mFiles.clear();
149     }
150 
151     /**
152      * Returns the sorted list of {@link ResourceItem} objects for this resource item.
153      */
getSourceFileArray()154     public ResourceFile[] getSourceFileArray() {
155         ArrayList<ResourceFile> list = new ArrayList<ResourceFile>();
156         list.addAll(mFiles);
157 
158         Collections.sort(list, sComparator);
159 
160         return list.toArray(new ResourceFile[list.size()]);
161     }
162 
163     /**
164      * Returns the list of source file for this resource.
165      */
getSourceFileList()166     public List<ResourceFile> getSourceFileList() {
167         return Collections.unmodifiableList(mFiles);
168     }
169 
170     /**
171      * Returns if the resource has at least one non-default version.
172      *
173      * @see ResourceFile#getConfiguration()
174      * @see FolderConfiguration#isDefault()
175      */
hasAlternates()176     public boolean hasAlternates() {
177         for (ResourceFile file : mFiles) {
178             if (file.getFolder().getConfiguration().isDefault() == false) {
179                 return true;
180             }
181         }
182 
183         return false;
184     }
185 
186     /**
187      * Returns whether the resource has a default version, with no qualifier.
188      *
189      * @see ResourceFile#getConfiguration()
190      * @see FolderConfiguration#isDefault()
191      */
hasDefault()192     public boolean hasDefault() {
193         for (ResourceFile file : mFiles) {
194             if (file.getFolder().getConfiguration().isDefault()) {
195                 return true;
196             }
197         }
198 
199         // We only want to return false if there's no default and more than 0 items.
200         return (mFiles.size() == 0);
201     }
202 
203     /**
204      * Returns the number of alternate versions for this resource.
205      *
206      * @see ResourceFile#getConfiguration()
207      * @see FolderConfiguration#isDefault()
208      */
getAlternateCount()209     public int getAlternateCount() {
210         int count = 0;
211         for (ResourceFile file : mFiles) {
212             if (file.getFolder().getConfiguration().isDefault() == false) {
213                 count++;
214             }
215         }
216 
217         return count;
218     }
219 
220     /**
221      * Returns a formatted string usable in an XML to use for the {@link ResourceItem}.
222      * @param system Whether this is a system resource or a project resource.
223      * @return a string in the format @[type]/[name]
224      */
getXmlString(ResourceType type, boolean system)225     public String getXmlString(ResourceType type, boolean system) {
226         if (type == ResourceType.ID && isDeclaredInline()) {
227             return (system ? "@android:" : "@+") + type.getName() + "/" + mName; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
228         }
229 
230         return (system ? "@android:" : "@") + type.getName() + "/" + mName; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
231     }
232 
233     @Override
toString()234     public String toString() {
235         return "ResourceItem [mName=" + mName + ", mFiles=" + mFiles + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
236     }
237 }
238