View Javadoc
1   package com.atlassian.plugin.elements;
2   
3   import com.atlassian.plugin.loaders.LoaderUtils;
4   import org.dom4j.Element;
5   
6   import java.util.Collections;
7   import java.util.Map;
8   import java.util.regex.Pattern;
9   
10  public class ResourceDescriptor {
11      private final String type;
12      private final String name;
13      private final String location;
14      private final String contentType;
15  
16      private final Pattern pattern;
17      private final String content;
18      private final Map<String, String> params;
19      private final ResourceLocation ourLocation;
20  
21      public ResourceDescriptor(final Element element) {
22          type = element.attributeValue("type");
23          final String name = element.attributeValue("name");
24          final String namePattern = element.attributeValue("namePattern");
25          if (name == null && namePattern == null) {
26              throw new RuntimeException("resource descriptor needs one of 'name' and 'namePattern' attributes.");
27          }
28  
29          if (name != null && namePattern != null) {
30              throw new RuntimeException("resource descriptor can have only one of 'name' and 'namePattern' attributes.");
31          }
32  
33          this.name = name;
34  
35          location = element.attributeValue("location");
36  
37          if (namePattern != null && location == null) {
38              throw new RuntimeException("resource descriptor must have the 'location' attribute specified when the 'namePattern' attribute is used");
39          }
40  
41          if (namePattern != null && !location.endsWith("/")) {
42              throw new RuntimeException("when 'namePattern' is specified, 'location' must be a directory (ending in '/')");
43          }
44          params = LoaderUtils.getParams(element);
45  
46          if (element.getTextTrim() != null && !"".equals(element.getTextTrim())) {
47              content = element.getTextTrim();
48          } else {
49              content = null;
50          }
51  
52          contentType = getParameter("content-type");
53  
54          if (namePattern != null) {
55              pattern = Pattern.compile(namePattern);
56              ourLocation = null;
57          } else {
58              ourLocation = new ResourceLocation(location, name, type, contentType, content, params);
59              pattern = null;
60          }
61      }
62  
63      public String getType() {
64          return type;
65      }
66  
67      /**
68       * This may throw an exception if one of the deprecated methods is used on a ResourceDescriptor which has been given a namePattern
69       */
70      public String getName() {
71          if (name == null) {
72              throw new RuntimeException("tried to get name from ResourceDescriptor with null name and namePattern = " + pattern);
73          }
74          return name;
75      }
76  
77      public String getLocation() {
78          return location;
79      }
80  
81      public String getContent() {
82          return content;
83      }
84  
85      public boolean doesTypeAndNameMatch(final String type, final String name) {
86          if ((type != null) && type.equalsIgnoreCase(this.type)) {
87              if (pattern != null) {
88                  return pattern.matcher(name).matches();
89              } else {
90                  return (name != null) && name.equalsIgnoreCase(this.name);
91              }
92          } else {
93              return false;
94          }
95      }
96  
97      public Map<String, String> getParameters() {
98          return Collections.unmodifiableMap(params);
99      }
100 
101     public String getParameter(final String key) {
102         return params.get(key);
103     }
104 
105     @Override
106     public boolean equals(final Object o) {
107         if (this == o) {
108             return true;
109         }
110         if (!(o instanceof ResourceDescriptor)) {
111             return false;
112         }
113 
114         final ResourceDescriptor resourceDescriptor = (ResourceDescriptor) o;
115 
116         if (name != null) {
117             if (!name.equals(resourceDescriptor.name)) {
118                 return false;
119             }
120         } else if (pattern != null) {
121             if (resourceDescriptor.pattern == null) {
122                 return false;
123             }
124             if (!pattern.toString().equals(resourceDescriptor.pattern.toString())) {
125                 return false;
126             }
127         }
128 
129         if (type == null) {
130             if (resourceDescriptor.type != null) {
131                 return false;
132             }
133         } else {
134             if (!type.equals(resourceDescriptor.type)) {
135                 return false;
136             }
137         }
138 
139         return true;
140     }
141 
142     @Override
143     public int hashCode() {
144         int result = 0;
145         if (type != null) {
146             result = type.hashCode();
147         }
148         if (name != null) {
149             result = 29 * result + name.hashCode();
150         } else if (pattern != null) {
151             result = 29 * result + pattern.hashCode();
152         }
153         return result;
154     }
155 
156     /**
157      * Used for resource descriptors that specify multiple resources, via {@link #pattern}.
158      *
159      * @return the location of an individual resource with the name if it matches the pattern,
160      * otherwise the location for the actual resource descriptor.
161      */
162     public ResourceLocation getResourceLocationForName(final String name) {
163 
164         if (pattern != null) {
165             if (pattern.matcher(name).matches()) {
166                 return new ResourceLocation(getLocation(), name, type, contentType, content, params);
167             } else {
168                 throw new RuntimeException("This descriptor does not provide resources named " + name);
169             }
170         } else {
171             return ourLocation;
172         }
173     }
174 }