• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.res;
2 
3 import java.io.File;
4 import java.util.regex.Matcher;
5 import java.util.regex.Pattern;
6 import javax.annotation.Nonnull;
7 
8 public class ResName {
9   public static final String ID_TYPE = "id";
10 
11   private static final Pattern FQN_PATTERN = Pattern.compile("^([^:]*):([^/]+)/(.+)$");
12   private static final int NAMESPACE = 1;
13   private static final int TYPE = 2;
14   private static final int NAME = 3;
15 
16   public final @Nonnull String packageName;
17   public final @Nonnull String type;
18   public final @Nonnull String name;
19 
20   public final int hashCode;
21 
ResName(@onnull String packageName, @Nonnull String type, @Nonnull String name)22   public ResName(@Nonnull String packageName, @Nonnull String type, @Nonnull String name) {
23     this.packageName = packageName;
24     this.type = type.trim();
25     this.name = name.indexOf('.') != -1 ? name.replace('.', '_').trim() : name.trim();
26 
27     hashCode = computeHashCode();
28   }
29 
ResName(@onnull String fullyQualifiedName)30   public ResName(@Nonnull String fullyQualifiedName) {
31     Matcher matcher = FQN_PATTERN.matcher(fullyQualifiedName.trim());
32     if (!matcher.find()) {
33       throw new IllegalStateException("\"" + fullyQualifiedName + "\" is not fully qualified");
34     }
35     packageName = matcher.group(NAMESPACE);
36     type = matcher.group(TYPE).trim();
37     String nameStr = matcher.group(NAME);
38     name = nameStr.indexOf('.') != -1 ? nameStr.replace('.', '_') : nameStr;
39 
40     hashCode = computeHashCode();
41     if (packageName.equals("xmlns")) throw new IllegalStateException("\"" + fullyQualifiedName + "\" unexpected");
42   }
43 
44   /**
45    * @return null if the resource could not be qualified.
46    */
qualifyResourceName(@onnull String possiblyQualifiedResourceName, String defaultPackageName, String defaultType)47   public static String qualifyResourceName(@Nonnull String possiblyQualifiedResourceName, String defaultPackageName, String defaultType) {
48     ResName resName = qualifyResName(possiblyQualifiedResourceName, defaultPackageName, defaultType);
49     return resName != null ? resName.getFullyQualifiedName() : null;
50   }
51 
qualifyResName(@onnull String possiblyQualifiedResourceName, ResName defaults)52   public static ResName qualifyResName(@Nonnull String possiblyQualifiedResourceName, ResName defaults) {
53     return qualifyResName(possiblyQualifiedResourceName, defaults.packageName, defaults.type);
54   }
55 
qualifyResName(@onnull String possiblyQualifiedResourceName, String defaultPackageName, String defaultType)56   public static ResName qualifyResName(@Nonnull String possiblyQualifiedResourceName, String defaultPackageName, String defaultType) {
57     int indexOfColon = possiblyQualifiedResourceName.indexOf(':');
58     int indexOfSlash = possiblyQualifiedResourceName.indexOf('/');
59     String type = null;
60     String packageName = null;
61     String name = possiblyQualifiedResourceName;
62     if (indexOfColon > indexOfSlash) {
63       if (indexOfSlash > 0) {
64         type = possiblyQualifiedResourceName.substring(0, indexOfSlash);
65       }
66       packageName = possiblyQualifiedResourceName.substring(indexOfSlash + 1, indexOfColon);
67       name =  possiblyQualifiedResourceName.substring(indexOfColon + 1);
68     } else if (indexOfSlash > indexOfColon) {
69       if (indexOfColon > 0) {
70         packageName = possiblyQualifiedResourceName.substring(0, indexOfColon);
71       }
72       type = possiblyQualifiedResourceName.substring(indexOfColon + 1, indexOfSlash);
73       name = possiblyQualifiedResourceName.substring(indexOfSlash + 1);
74     }
75 
76     if ((type == null && defaultType == null) || (packageName == null && defaultPackageName == null)) {
77       return null;
78     }
79 
80     return new ResName(packageName == null ? defaultPackageName : packageName,
81         type == null ? defaultType : type,
82         name);
83   }
84 
qualifyResName(String possiblyQualifiedResourceName, String contextPackageName)85   public static String qualifyResName(String possiblyQualifiedResourceName, String contextPackageName) {
86     if (possiblyQualifiedResourceName == null) {
87       return null;
88     }
89 
90     if (AttributeResource.isNull(possiblyQualifiedResourceName)) {
91       return null;
92     }
93 
94     // Was not able to fully qualify the resource name
95     String fullyQualifiedResourceName = qualifyResourceName(possiblyQualifiedResourceName, contextPackageName, null);
96     if (fullyQualifiedResourceName == null) {
97       return null;
98     }
99 
100     return fullyQualifiedResourceName.replaceAll("[@+]", "");
101   }
102 
qualifyFromFilePath(@onnull final String packageName, @Nonnull final String filePath)103   public static ResName qualifyFromFilePath(@Nonnull final String packageName, @Nonnull final String filePath) {
104     final FileFsFile filePathFile = new FileFsFile(new File(filePath));
105     final String type = filePathFile.getParent().getName().split("-")[0];
106     final String name = filePathFile.getBaseName();
107 
108     return new ResName(packageName, type, name);
109   }
110 
111   @Override
equals(Object o)112   public boolean equals(Object o) {
113     if (this == o) return true;
114     if (o == null || getClass() != o.getClass()) return false;
115 
116     ResName resName = (ResName) o;
117 
118     if (hashCode() != resName.hashCode()) return false;
119 
120     if (!packageName.equals(resName.packageName)) return false;
121     if (!type.equals(resName.type)) return false;
122     if (!name.equals(resName.name)) return false;
123 
124     return true;
125   }
126 
127   @Override
hashCode()128   public int hashCode() {
129     return hashCode;
130   }
131 
132   @Override
toString()133   public String toString() {
134     return "ResName{" + getFullyQualifiedName() + "}";
135   }
136 
getFullyQualifiedName()137   public String getFullyQualifiedName() {
138     return packageName + ":" + type + "/" + name;
139   }
140 
getNamespaceUri()141   public String getNamespaceUri() {
142     return "http://schemas.android.com/apk/res/" + packageName;
143   }
144 
withPackageName(String packageName)145   public ResName withPackageName(String packageName) {
146     if (packageName.equals(this.packageName)) return this;
147     return new ResName(packageName, type, name);
148   }
149 
mustBe(String expectedType)150   public void mustBe(String expectedType) {
151     if (!type.equals(expectedType)) {
152       throw new RuntimeException("expected " + getFullyQualifiedName() + " to be a " + expectedType + ", is a " + type);
153     }
154   }
155 
computeHashCode()156   private int computeHashCode() {
157     int result = packageName.hashCode();
158     result = 31 * result + type.hashCode();
159     result = 31 * result + name.hashCode();
160     return result;
161   }
162 }
163