• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
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.eclipse.adt.internal.resources.configurations;
18 
19 import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType;
20 
21 
22 /**
23  * Represents the configuration for Resource Folders. All the properties have a default
24  * value which means that the property is not set.
25  */
26 public final class FolderConfiguration implements Comparable<FolderConfiguration> {
27     public final static String QUALIFIER_SEP = "-"; //$NON-NLS-1$
28 
29     private final ResourceQualifier[] mQualifiers = new ResourceQualifier[INDEX_COUNT];
30 
31     private final static int INDEX_COUNTRY_CODE       = 0;
32     private final static int INDEX_NETWORK_CODE       = 1;
33     private final static int INDEX_LANGUAGE           = 2;
34     private final static int INDEX_REGION             = 3;
35     private final static int INDEX_SCREEN_SIZE        = 4;
36     private final static int INDEX_SCREEN_RATIO       = 5;
37     private final static int INDEX_SCREEN_ORIENTATION = 6;
38     private final static int INDEX_DOCK_MODE          = 7;
39     private final static int INDEX_NIGHT_MODE         = 8;
40     private final static int INDEX_PIXEL_DENSITY      = 9;
41     private final static int INDEX_TOUCH_TYPE         = 10;
42     private final static int INDEX_KEYBOARD_STATE     = 11;
43     private final static int INDEX_TEXT_INPUT_METHOD  = 12;
44     private final static int INDEX_NAVIGATION_STATE   = 14;
45     private final static int INDEX_NAVIGATION_METHOD  = 15;
46     private final static int INDEX_SCREEN_DIMENSION   = 16;
47     private final static int INDEX_VERSION            = 17;
48     private final static int INDEX_COUNT              = 18;
49 
50     /**
51      * Returns the number of {@link ResourceQualifier} that make up a Folder configuration.
52      */
getQualifierCount()53     public static int getQualifierCount() {
54         return INDEX_COUNT;
55     }
56 
57     /**
58      * Sets the config from the qualifiers of a given <var>config</var>.
59      * <p/>This is equivalent to <code>set(config, false)</code>
60      * @param config the configuration to set
61      *
62      * @see #set(FolderConfiguration, boolean)
63      */
set(FolderConfiguration config)64     public void set(FolderConfiguration config) {
65         set(config, false /*nonFakeValuesOnly*/);
66     }
67 
68     /**
69      * Sets the config from the qualifiers of a given <var>config</var>.
70      * @param config the configuration to set
71      * @param nonFakeValuesOnly if set to true this ignore qualifiers for which the
72      * current value is a fake value.
73      *
74      * @see ResourceQualifier#hasFakeValue()
75      */
set(FolderConfiguration config, boolean nonFakeValuesOnly)76     public void set(FolderConfiguration config, boolean nonFakeValuesOnly) {
77         if (config != null) {
78             for (int i = 0 ; i < INDEX_COUNT ; i++) {
79                 ResourceQualifier q = config.mQualifiers[i];
80                 if (nonFakeValuesOnly == false || q == null || q.hasFakeValue() == false) {
81                     mQualifiers[i] = q;
82                 }
83             }
84         }
85     }
86 
87     /**
88      * Removes the qualifiers from the receiver if they are present (and valid)
89      * in the given configuration.
90      */
substract(FolderConfiguration config)91     public void substract(FolderConfiguration config) {
92         for (int i = 0 ; i < INDEX_COUNT ; i++) {
93             if (config.mQualifiers[i] != null && config.mQualifiers[i].isValid()) {
94                 mQualifiers[i] = null;
95             }
96         }
97     }
98 
99     /**
100      * Returns the first invalid qualifier, or <code>null<code> if they are all valid (or if none
101      * exists).
102      */
getInvalidQualifier()103     public ResourceQualifier getInvalidQualifier() {
104         for (int i = 0 ; i < INDEX_COUNT ; i++) {
105             if (mQualifiers[i] != null && mQualifiers[i].isValid() == false) {
106                 return mQualifiers[i];
107             }
108         }
109 
110         // all allocated qualifiers are valid, we return null.
111         return null;
112     }
113 
114     /**
115      * Returns whether the Region qualifier is valid. Region qualifier can only be present if a
116      * Language qualifier is present as well.
117      * @return true if the Region qualifier is valid.
118      */
checkRegion()119     public boolean checkRegion() {
120         if (mQualifiers[INDEX_LANGUAGE] == null && mQualifiers[INDEX_REGION] != null) {
121             return false;
122         }
123 
124         return true;
125     }
126 
127     /**
128      * Adds a qualifier to the {@link FolderConfiguration}
129      * @param qualifier the {@link ResourceQualifier} to add.
130      */
addQualifier(ResourceQualifier qualifier)131     public void addQualifier(ResourceQualifier qualifier) {
132         if (qualifier instanceof CountryCodeQualifier) {
133             mQualifiers[INDEX_COUNTRY_CODE] = qualifier;
134         } else if (qualifier instanceof NetworkCodeQualifier) {
135             mQualifiers[INDEX_NETWORK_CODE] = qualifier;
136         } else if (qualifier instanceof LanguageQualifier) {
137             mQualifiers[INDEX_LANGUAGE] = qualifier;
138         } else if (qualifier instanceof RegionQualifier) {
139             mQualifiers[INDEX_REGION] = qualifier;
140         } else if (qualifier instanceof ScreenSizeQualifier) {
141             mQualifiers[INDEX_SCREEN_SIZE] = qualifier;
142         } else if (qualifier instanceof ScreenRatioQualifier) {
143             mQualifiers[INDEX_SCREEN_RATIO] = qualifier;
144         } else if (qualifier instanceof ScreenOrientationQualifier) {
145             mQualifiers[INDEX_SCREEN_ORIENTATION] = qualifier;
146         } else if (qualifier instanceof DockModeQualifier) {
147             mQualifiers[INDEX_DOCK_MODE] = qualifier;
148         } else if (qualifier instanceof NightModeQualifier) {
149             mQualifiers[INDEX_NIGHT_MODE] = qualifier;
150         } else if (qualifier instanceof PixelDensityQualifier) {
151             mQualifiers[INDEX_PIXEL_DENSITY] = qualifier;
152         } else if (qualifier instanceof TouchScreenQualifier) {
153             mQualifiers[INDEX_TOUCH_TYPE] = qualifier;
154         } else if (qualifier instanceof KeyboardStateQualifier) {
155             mQualifiers[INDEX_KEYBOARD_STATE] = qualifier;
156         } else if (qualifier instanceof TextInputMethodQualifier) {
157             mQualifiers[INDEX_TEXT_INPUT_METHOD] = qualifier;
158         } else if (qualifier instanceof NavigationStateQualifier) {
159             mQualifiers[INDEX_NAVIGATION_STATE] = qualifier;
160         } else if (qualifier instanceof NavigationMethodQualifier) {
161             mQualifiers[INDEX_NAVIGATION_METHOD] = qualifier;
162         } else if (qualifier instanceof ScreenDimensionQualifier) {
163             mQualifiers[INDEX_SCREEN_DIMENSION] = qualifier;
164         } else if (qualifier instanceof VersionQualifier) {
165             mQualifiers[INDEX_VERSION] = qualifier;
166         }
167     }
168 
169     /**
170      * Removes a given qualifier from the {@link FolderConfiguration}.
171      * @param qualifier the {@link ResourceQualifier} to remove.
172      */
removeQualifier(ResourceQualifier qualifier)173     public void removeQualifier(ResourceQualifier qualifier) {
174         for (int i = 0 ; i < INDEX_COUNT ; i++) {
175             if (mQualifiers[i] == qualifier) {
176                 mQualifiers[i] = null;
177                 return;
178             }
179         }
180     }
181 
182     /**
183      * Returns a qualifier by its index. The total number of qualifiers can be accessed by
184      * {@link #getQualifierCount()}.
185      * @param index the index of the qualifier to return.
186      * @return the qualifier or null if there are none at the index.
187      */
getQualifier(int index)188     public ResourceQualifier getQualifier(int index) {
189         return mQualifiers[index];
190     }
191 
setCountryCodeQualifier(CountryCodeQualifier qualifier)192     public void setCountryCodeQualifier(CountryCodeQualifier qualifier) {
193         mQualifiers[INDEX_COUNTRY_CODE] = qualifier;
194     }
195 
getCountryCodeQualifier()196     public CountryCodeQualifier getCountryCodeQualifier() {
197         return (CountryCodeQualifier)mQualifiers[INDEX_COUNTRY_CODE];
198     }
199 
setNetworkCodeQualifier(NetworkCodeQualifier qualifier)200     public void setNetworkCodeQualifier(NetworkCodeQualifier qualifier) {
201         mQualifiers[INDEX_NETWORK_CODE] = qualifier;
202     }
203 
getNetworkCodeQualifier()204     public NetworkCodeQualifier getNetworkCodeQualifier() {
205         return (NetworkCodeQualifier)mQualifiers[INDEX_NETWORK_CODE];
206     }
207 
setLanguageQualifier(LanguageQualifier qualifier)208     public void setLanguageQualifier(LanguageQualifier qualifier) {
209         mQualifiers[INDEX_LANGUAGE] = qualifier;
210     }
211 
getLanguageQualifier()212     public LanguageQualifier getLanguageQualifier() {
213         return (LanguageQualifier)mQualifiers[INDEX_LANGUAGE];
214     }
215 
setRegionQualifier(RegionQualifier qualifier)216     public void setRegionQualifier(RegionQualifier qualifier) {
217         mQualifiers[INDEX_REGION] = qualifier;
218     }
219 
getRegionQualifier()220     public RegionQualifier getRegionQualifier() {
221         return (RegionQualifier)mQualifiers[INDEX_REGION];
222     }
223 
setScreenSizeQualifier(ScreenSizeQualifier qualifier)224     public void setScreenSizeQualifier(ScreenSizeQualifier qualifier) {
225         mQualifiers[INDEX_SCREEN_SIZE] = qualifier;
226     }
227 
getScreenSizeQualifier()228     public ScreenSizeQualifier getScreenSizeQualifier() {
229         return (ScreenSizeQualifier)mQualifiers[INDEX_SCREEN_SIZE];
230     }
231 
setScreenRatioQualifier(ScreenRatioQualifier qualifier)232     public void setScreenRatioQualifier(ScreenRatioQualifier qualifier) {
233         mQualifiers[INDEX_SCREEN_RATIO] = qualifier;
234     }
235 
getScreenRatioQualifier()236     public ScreenRatioQualifier getScreenRatioQualifier() {
237         return (ScreenRatioQualifier)mQualifiers[INDEX_SCREEN_RATIO];
238     }
239 
setScreenOrientationQualifier(ScreenOrientationQualifier qualifier)240     public void setScreenOrientationQualifier(ScreenOrientationQualifier qualifier) {
241         mQualifiers[INDEX_SCREEN_ORIENTATION] = qualifier;
242     }
243 
getScreenOrientationQualifier()244     public ScreenOrientationQualifier getScreenOrientationQualifier() {
245         return (ScreenOrientationQualifier)mQualifiers[INDEX_SCREEN_ORIENTATION];
246     }
247 
setDockModeQualifier(DockModeQualifier qualifier)248     public void setDockModeQualifier(DockModeQualifier qualifier) {
249         mQualifiers[INDEX_DOCK_MODE] = qualifier;
250     }
251 
getDockModeQualifier()252     public DockModeQualifier getDockModeQualifier() {
253         return (DockModeQualifier)mQualifiers[INDEX_DOCK_MODE];
254     }
255 
setNightModeQualifier(NightModeQualifier qualifier)256     public void setNightModeQualifier(NightModeQualifier qualifier) {
257         mQualifiers[INDEX_NIGHT_MODE] = qualifier;
258     }
259 
getNightModeQualifier()260     public NightModeQualifier getNightModeQualifier() {
261         return (NightModeQualifier)mQualifiers[INDEX_NIGHT_MODE];
262     }
263 
setPixelDensityQualifier(PixelDensityQualifier qualifier)264     public void setPixelDensityQualifier(PixelDensityQualifier qualifier) {
265         mQualifiers[INDEX_PIXEL_DENSITY] = qualifier;
266     }
267 
getPixelDensityQualifier()268     public PixelDensityQualifier getPixelDensityQualifier() {
269         return (PixelDensityQualifier)mQualifiers[INDEX_PIXEL_DENSITY];
270     }
271 
setTouchTypeQualifier(TouchScreenQualifier qualifier)272     public void setTouchTypeQualifier(TouchScreenQualifier qualifier) {
273         mQualifiers[INDEX_TOUCH_TYPE] = qualifier;
274     }
275 
getTouchTypeQualifier()276     public TouchScreenQualifier getTouchTypeQualifier() {
277         return (TouchScreenQualifier)mQualifiers[INDEX_TOUCH_TYPE];
278     }
279 
setKeyboardStateQualifier(KeyboardStateQualifier qualifier)280     public void setKeyboardStateQualifier(KeyboardStateQualifier qualifier) {
281         mQualifiers[INDEX_KEYBOARD_STATE] = qualifier;
282     }
283 
getKeyboardStateQualifier()284     public KeyboardStateQualifier getKeyboardStateQualifier() {
285         return (KeyboardStateQualifier)mQualifiers[INDEX_KEYBOARD_STATE];
286     }
287 
setTextInputMethodQualifier(TextInputMethodQualifier qualifier)288     public void setTextInputMethodQualifier(TextInputMethodQualifier qualifier) {
289         mQualifiers[INDEX_TEXT_INPUT_METHOD] = qualifier;
290     }
291 
getTextInputMethodQualifier()292     public TextInputMethodQualifier getTextInputMethodQualifier() {
293         return (TextInputMethodQualifier)mQualifiers[INDEX_TEXT_INPUT_METHOD];
294     }
295 
setNavigationStateQualifier(NavigationStateQualifier qualifier)296     public void setNavigationStateQualifier(NavigationStateQualifier qualifier) {
297         mQualifiers[INDEX_NAVIGATION_STATE] = qualifier;
298     }
299 
getNavigationStateQualifier()300     public NavigationStateQualifier getNavigationStateQualifier() {
301         return (NavigationStateQualifier)mQualifiers[INDEX_NAVIGATION_STATE];
302     }
303 
setNavigationMethodQualifier(NavigationMethodQualifier qualifier)304     public void setNavigationMethodQualifier(NavigationMethodQualifier qualifier) {
305         mQualifiers[INDEX_NAVIGATION_METHOD] = qualifier;
306     }
307 
getNavigationMethodQualifier()308     public NavigationMethodQualifier getNavigationMethodQualifier() {
309         return (NavigationMethodQualifier)mQualifiers[INDEX_NAVIGATION_METHOD];
310     }
311 
setScreenDimensionQualifier(ScreenDimensionQualifier qualifier)312     public void setScreenDimensionQualifier(ScreenDimensionQualifier qualifier) {
313         mQualifiers[INDEX_SCREEN_DIMENSION] = qualifier;
314     }
315 
getScreenDimensionQualifier()316     public ScreenDimensionQualifier getScreenDimensionQualifier() {
317         return (ScreenDimensionQualifier)mQualifiers[INDEX_SCREEN_DIMENSION];
318     }
319 
setVersionQualifier(VersionQualifier qualifier)320     public void setVersionQualifier(VersionQualifier qualifier) {
321         mQualifiers[INDEX_VERSION] = qualifier;
322     }
323 
getVersionQualifier()324     public VersionQualifier getVersionQualifier() {
325         return (VersionQualifier)mQualifiers[INDEX_VERSION];
326     }
327 
328     /**
329      * Returns whether an object is equals to the receiver.
330      */
331     @Override
equals(Object obj)332     public boolean equals(Object obj) {
333         if (obj == this) {
334             return true;
335         }
336 
337         if (obj instanceof FolderConfiguration) {
338             FolderConfiguration fc = (FolderConfiguration)obj;
339             for (int i = 0 ; i < INDEX_COUNT ; i++) {
340                 ResourceQualifier qualifier = mQualifiers[i];
341                 ResourceQualifier fcQualifier = fc.mQualifiers[i];
342                 if (qualifier != null) {
343                     if (qualifier.equals(fcQualifier) == false) {
344                         return false;
345                     }
346                 } else if (fcQualifier != null) {
347                     return false;
348                 }
349             }
350 
351             return true;
352         }
353 
354         return false;
355     }
356 
357     @Override
hashCode()358     public int hashCode() {
359         return toString().hashCode();
360     }
361 
362     /**
363      * Returns whether the Configuration has only default values.
364      */
isDefault()365     public boolean isDefault() {
366         for (ResourceQualifier irq : mQualifiers) {
367             if (irq != null) {
368                 return false;
369             }
370         }
371 
372         return true;
373     }
374 
375     /**
376      * Returns the name of a folder with the configuration.
377      */
getFolderName(ResourceFolderType folder)378     public String getFolderName(ResourceFolderType folder) {
379         StringBuilder result = new StringBuilder(folder.getName());
380 
381         for (ResourceQualifier qualifier : mQualifiers) {
382             if (qualifier != null) {
383                 String segment = qualifier.getFolderSegment();
384                 if (segment != null && segment.length() > 0) {
385                     result.append(QUALIFIER_SEP);
386                     result.append(segment);
387                 }
388             }
389         }
390 
391         return result.toString();
392     }
393 
394     /**
395      * Returns {@link #toDisplayString()}.
396      */
397     @Override
toString()398     public String toString() {
399         return toDisplayString();
400     }
401 
402     /**
403      * Returns a string valid for display purpose.
404      */
toDisplayString()405     public String toDisplayString() {
406         if (isDefault()) {
407             return "default";
408         }
409 
410         StringBuilder result = null;
411         int index = 0;
412         ResourceQualifier qualifier = null;
413 
414         // pre- language/region qualifiers
415         while (index < INDEX_LANGUAGE) {
416             qualifier = mQualifiers[index++];
417             if (qualifier != null) {
418                 if (result == null) {
419                     result = new StringBuilder();
420                 } else {
421                     result.append(", "); //$NON-NLS-1$
422                 }
423                 result.append(qualifier.getLongDisplayValue());
424 
425             }
426         }
427 
428         // process the language/region qualifier in a custom way, if there are both non null.
429         if (mQualifiers[INDEX_LANGUAGE] != null && mQualifiers[INDEX_REGION] != null) {
430             String language = mQualifiers[INDEX_LANGUAGE].getLongDisplayValue();
431             String region = mQualifiers[INDEX_REGION].getLongDisplayValue();
432 
433             if (result == null) {
434                 result = new StringBuilder();
435             } else {
436                 result.append(", "); //$NON-NLS-1$
437             }
438             result.append(String.format("Locale %s_%s", language, region)); //$NON-NLS-1$
439 
440             index += 2;
441         }
442 
443         // post language/region qualifiers.
444         while (index < INDEX_COUNT) {
445             qualifier = mQualifiers[index++];
446             if (qualifier != null) {
447                 if (result == null) {
448                     result = new StringBuilder();
449                 } else {
450                     result.append(", "); //$NON-NLS-1$
451                 }
452                 result.append(qualifier.getLongDisplayValue());
453 
454             }
455         }
456 
457         return result == null ? null : result.toString();
458     }
459 
compareTo(FolderConfiguration folderConfig)460     public int compareTo(FolderConfiguration folderConfig) {
461         // default are always at the top.
462         if (isDefault()) {
463             if (folderConfig.isDefault()) {
464                 return 0;
465             }
466             return -1;
467         }
468 
469         // now we compare the qualifiers
470         for (int i = 0 ; i < INDEX_COUNT; i++) {
471             ResourceQualifier qualifier1 = mQualifiers[i];
472             ResourceQualifier qualifier2 = folderConfig.mQualifiers[i];
473 
474             if (qualifier1 == null) {
475                 if (qualifier2 == null) {
476                     continue;
477                 } else {
478                     return -1;
479                 }
480             } else {
481                 if (qualifier2 == null) {
482                     return 1;
483                 } else {
484                     int result = qualifier1.compareTo(qualifier2);
485 
486                     if (result == 0) {
487                         continue;
488                     }
489 
490                     return result;
491                 }
492             }
493         }
494 
495         // if we arrive here, all the qualifier matches
496         return 0;
497     }
498 
499     /**
500      * Returns whether the configuration is a match for the given reference config.
501      * <p/>A match means that, for each qualifier of this config
502      * <ul>
503      * <li>The reference config has no value set
504      * <li>or, the qualifier of the reference config is a match. Depending on the qualifier type
505      * this does not mean the same exact value.</li>
506      * </ul>
507      * @param referenceConfig The reference configuration to test against.
508      * @return true if the configuration matches.
509      */
isMatchFor(FolderConfiguration referenceConfig)510     public boolean isMatchFor(FolderConfiguration referenceConfig) {
511         for (int i = 0 ; i < INDEX_COUNT ; i++) {
512             ResourceQualifier testQualifier = mQualifiers[i];
513             ResourceQualifier referenceQualifier = referenceConfig.mQualifiers[i];
514 
515             // it's only a non match if both qualifiers are non-null, and they don't match.
516             if (testQualifier != null && referenceQualifier != null &&
517                         testQualifier.isMatchFor(referenceQualifier) == false) {
518                 return false;
519             }
520         }
521         return true;
522     }
523 
524     /**
525      * Returns the index of the first non null {@link ResourceQualifier} starting at index
526      * <var>startIndex</var>
527      * @param startIndex
528      * @return -1 if no qualifier was found.
529      */
getHighestPriorityQualifier(int startIndex)530     public int getHighestPriorityQualifier(int startIndex) {
531         for (int i = startIndex ; i < INDEX_COUNT ; i++) {
532             if (mQualifiers[i] != null) {
533                 return i;
534             }
535         }
536 
537         return -1;
538     }
539 
540     /**
541      * Create default qualifiers.
542      */
createDefault()543     public void createDefault() {
544         mQualifiers[INDEX_COUNTRY_CODE] = new CountryCodeQualifier();
545         mQualifiers[INDEX_NETWORK_CODE] = new NetworkCodeQualifier();
546         mQualifiers[INDEX_LANGUAGE] = new LanguageQualifier();
547         mQualifiers[INDEX_REGION] = new RegionQualifier();
548         mQualifiers[INDEX_SCREEN_SIZE] = new ScreenSizeQualifier();
549         mQualifiers[INDEX_SCREEN_RATIO] = new ScreenRatioQualifier();
550         mQualifiers[INDEX_SCREEN_ORIENTATION] = new ScreenOrientationQualifier();
551         mQualifiers[INDEX_DOCK_MODE] = new DockModeQualifier();
552         mQualifiers[INDEX_NIGHT_MODE] = new NightModeQualifier();
553         mQualifiers[INDEX_PIXEL_DENSITY] = new PixelDensityQualifier();
554         mQualifiers[INDEX_TOUCH_TYPE] = new TouchScreenQualifier();
555         mQualifiers[INDEX_KEYBOARD_STATE] = new KeyboardStateQualifier();
556         mQualifiers[INDEX_TEXT_INPUT_METHOD] = new TextInputMethodQualifier();
557         mQualifiers[INDEX_NAVIGATION_STATE] = new NavigationStateQualifier();
558         mQualifiers[INDEX_NAVIGATION_METHOD] = new NavigationMethodQualifier();
559         mQualifiers[INDEX_SCREEN_DIMENSION] = new ScreenDimensionQualifier();
560         mQualifiers[INDEX_VERSION] = new VersionQualifier();
561     }
562 
563     /**
564      * Returns an array of all the non null qualifiers.
565      */
getQualifiers()566     public ResourceQualifier[] getQualifiers() {
567         int count = 0;
568         for (int i = 0 ; i < INDEX_COUNT ; i++) {
569             if (mQualifiers[i] != null) {
570                 count++;
571             }
572         }
573 
574         ResourceQualifier[] array = new ResourceQualifier[count];
575         int index = 0;
576         for (int i = 0 ; i < INDEX_COUNT ; i++) {
577             if (mQualifiers[i] != null) {
578                 array[index++] = mQualifiers[i];
579             }
580         }
581 
582         return array;
583     }
584 }
585