xref: /aosp_15_r20/external/robolectric/resources/src/main/java/org/robolectric/res/Qualifiers.java (revision e6ba16074e6af37d123cb567d575f496bf0a58ee)
1 package org.robolectric.res;
2 
3 import java.nio.file.Path;
4 import java.util.regex.Matcher;
5 import java.util.regex.Pattern;
6 import org.robolectric.res.android.ConfigDescription;
7 import org.robolectric.res.android.ResTable_config;
8 
9 /**
10  * Android qualifers as defined by
11  * https://developer.android.com/guide/topics/resources/providing-resources.html
12  */
13 @SuppressWarnings("NewApi")
14 public class Qualifiers {
15   private static final Pattern DIR_QUALIFIER_PATTERN = Pattern.compile("^[^-]+(?:-([^/]*))?/?$");
16 
17   // Matches a version qualifier like "v14". Parentheses capture the numeric
18   // part for easy retrieval with Matcher.group(2).
19   private static final Pattern SCREEN_WIDTH_PATTERN = Pattern.compile("^w([0-9]+)dp");
20   private static final Pattern SMALLEST_SCREEN_WIDTH_PATTERN = Pattern.compile("^sw([0-9]+)dp");
21   private static final Pattern VERSION_QUALIFIER_PATTERN = Pattern.compile("(v)([0-9]+)$");
22   private static final Pattern ORIENTATION_QUALIFIER_PATTERN = Pattern.compile("(land|port)");
23 
24   private final String qualifiers;
25   private final ResTable_config config;
26 
parse(String qualifiers)27   public static Qualifiers parse(String qualifiers) {
28     return parse(qualifiers, true);
29   }
30 
parse(String qualifiers, boolean applyVersionForCompat)31   public static Qualifiers parse(String qualifiers, boolean applyVersionForCompat) {
32     final ResTable_config config = new ResTable_config();
33     if (!qualifiers.isEmpty()
34         && !ConfigDescription.parse(qualifiers, config, applyVersionForCompat)) {
35       throw new IllegalArgumentException(
36           "failed to parse qualifiers '"
37               + qualifiers
38               + "'. See"
39               + " https://developer.android.com/guide/topics/resources/providing-resources.html#QualifierRules"
40               + " for expected format.");
41     }
42 
43     return new Qualifiers(qualifiers, config);
44   }
45 
Qualifiers(String qualifiers, ResTable_config config)46   protected Qualifiers(String qualifiers, ResTable_config config) {
47     this.qualifiers = qualifiers;
48     this.config = config;
49   }
50 
getConfig()51   public ResTable_config getConfig() {
52     return config;
53   }
54 
55   @Override
toString()56   public String toString() {
57     return qualifiers;
58   }
59 
fromParentDir(Path parentDir)60   public static Qualifiers fromParentDir(Path parentDir) {
61     if (parentDir == null) {
62       return parse("");
63     } else {
64       String parentDirName = parentDir.getFileName().toString();
65       Matcher matcher = DIR_QUALIFIER_PATTERN.matcher(parentDirName);
66       if (!matcher.find()) {
67         throw new IllegalStateException(parentDirName);
68       }
69       String qualifiers = matcher.group(1);
70       return parse(qualifiers != null ? qualifiers : "");
71     }
72   }
73 
74   /**
75    * @deprecated Use {@link android.os.Build.VERSION#SDK_INT} instead.
76    */
77   @Deprecated
getPlatformVersion(String qualifiers)78   public static int getPlatformVersion(String qualifiers) {
79     Matcher m = VERSION_QUALIFIER_PATTERN.matcher(qualifiers);
80     if (m.find()) {
81       return Integer.parseInt(m.group(2));
82     }
83     return -1;
84   }
85 
86   /**
87    * @deprecated Use {@link android.content.res.Configuration#smallestScreenWidthDp} instead.
88    */
89   @Deprecated
getSmallestScreenWidth(String qualifiers)90   public static int getSmallestScreenWidth(String qualifiers) {
91     for (String qualifier : qualifiers.split("-", 0)) {
92       Matcher matcher = SMALLEST_SCREEN_WIDTH_PATTERN.matcher(qualifier);
93       if (matcher.find()) {
94         return Integer.parseInt(matcher.group(1));
95       }
96     }
97 
98     return -1;
99   }
100 
101   /**
102    * If the Config already has a {@code sw} qualifier, do nothing. Otherwise, add a {@code sw}
103    * qualifier for the given width.
104    *
105    * @deprecated Use {@link android.content.res.Configuration#smallestScreenWidthDp} instead.
106    */
107   @Deprecated
addSmallestScreenWidth(String qualifiers, int smallestScreenWidth)108   public static String addSmallestScreenWidth(String qualifiers, int smallestScreenWidth) {
109     int qualifiersSmallestScreenWidth = Qualifiers.getSmallestScreenWidth(qualifiers);
110     if (qualifiersSmallestScreenWidth == -1) {
111       if (qualifiers.length() > 0) {
112         qualifiers += "-";
113       }
114       qualifiers += "sw" + smallestScreenWidth + "dp";
115     }
116     return qualifiers;
117   }
118 
119   /**
120    * @deprecated Use {@link android.content.res.Configuration#screenWidthDp} instead.
121    */
122   @Deprecated
getScreenWidth(String qualifiers)123   public static int getScreenWidth(String qualifiers) {
124     for (String qualifier : qualifiers.split("-", 0)) {
125       Matcher matcher = SCREEN_WIDTH_PATTERN.matcher(qualifier);
126       if (matcher.find()) {
127         return Integer.parseInt(matcher.group(1));
128       }
129     }
130 
131     return -1;
132   }
133 
134   /**
135    * @deprecated Use {@link android.content.res.Configuration#screenWidthDp} instead.
136    */
137   @Deprecated
addScreenWidth(String qualifiers, int screenWidth)138   public static String addScreenWidth(String qualifiers, int screenWidth) {
139     int qualifiersScreenWidth = Qualifiers.getScreenWidth(qualifiers);
140     if (qualifiersScreenWidth == -1) {
141       if (qualifiers.length() > 0) {
142         qualifiers += "-";
143       }
144       qualifiers += "w" + screenWidth + "dp";
145     }
146     return qualifiers;
147   }
148 
149   /**
150    * @deprecated Use {@link android.content.res.Configuration#orientation} instead.
151    */
152   @Deprecated
getOrientation(String qualifiers)153   public static String getOrientation(String qualifiers) {
154     for (String qualifier : qualifiers.split("-", 0)) {
155       Matcher matcher = ORIENTATION_QUALIFIER_PATTERN.matcher(qualifier);
156       if (matcher.find()) {
157         return matcher.group(1);
158       }
159     }
160     return null;
161   }
162 }
163