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
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
158
159
160
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 }