1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.struts2.quickstart;
19
20 import java.io.File;
21 import java.io.FileNotFoundException;
22 import java.io.FileReader;
23 import java.io.IOException;
24 import java.io.Serializable;
25 import java.util.ArrayList;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Map;
29
30 import javax.xml.parsers.DocumentBuilder;
31 import javax.xml.parsers.DocumentBuilderFactory;
32
33 import org.apache.commons.collections.MultiHashMap;
34 import org.w3c.dom.Document;
35 import org.w3c.dom.Element;
36 import org.w3c.dom.NodeList;
37
38 import com.thoughtworks.xstream.XStream;
39
40 /***
41 * Configuration for the QuickStart program.
42 */
43 public class Configuration implements Serializable {
44
45 private static final long serialVersionUID = 9159115401614443449L;
46
47 String ideaConfig;
48 String extendsConfig;
49 String resolver;
50 Integer port;
51 String context;
52 List libs;
53 List classDirs;
54 List sources;
55 List webDirs;
56 Map mappings;
57 List pathPriority;
58
59 public String getIdeaConfig() {
60 return ideaConfig;
61 }
62
63 public void setIdeaConfig(String ideaConfig) {
64 this.ideaConfig = ideaConfig;
65 }
66
67 public String getExtendsConfig() {
68 return extendsConfig;
69 }
70
71 public void setExtendsConfig(String extendsConfig) {
72 this.extendsConfig = extendsConfig;
73 }
74
75 public String getResolver() {
76 return resolver;
77 }
78
79 public void setResolver(String resolver) {
80 this.resolver = resolver;
81 }
82
83 public List getLibs() {
84 return libs;
85 }
86
87 public void setLibs(List libs) {
88 this.libs = libs;
89 }
90
91 public List getClassDirs() {
92 return classDirs;
93 }
94
95 public void setClassDirs(List classDirs) {
96 this.classDirs = classDirs;
97 }
98
99 public List getSources() {
100 return sources;
101 }
102
103 public void setSources(List sources) {
104 this.sources = sources;
105 }
106
107 public Map getMappings() {
108 return mappings;
109 }
110
111 public List getPathPriority() {
112 return pathPriority;
113 }
114
115 public List getWebDirs() {
116 return webDirs;
117 }
118
119 public void setWebDirs(List webDirs) {
120 this.webDirs = webDirs;
121 }
122
123 public Integer getPort() {
124 return port;
125 }
126
127 public void setPort(Integer port) {
128 this.port = port;
129 }
130
131 public String getContext() {
132 return context;
133 }
134
135 public void setContext(String context) {
136 this.context = context;
137 }
138
139 public void resolveDirs(String wd) {
140 if (ideaConfig != null) {
141 String[] paths = ideaConfig.split(",");
142 for (String path : paths) {
143 String full = resolveDir(path, wd);
144
145 try {
146 DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
147 Document doc = db.parse(full);
148 NodeList components = doc.getElementsByTagName("root");
149 List jars = new ArrayList();
150 for (int i = 0; i < components.getLength(); i++) {
151 Element e = (Element) components.item(i);
152 String value = e.getAttribute("url");
153 if (value != null && value.startsWith("jar://") && value.endsWith(".jar!/")) {
154 value = value.substring(6, value.length() - 2);
155 if (value.startsWith("$MODULE_DIR$")) {
156 value = value.substring(13);
157 }
158 jars.add(value);
159 }
160 }
161
162 if (this.libs != null) {
163 this.libs.addAll(jars);
164 } else {
165 this.libs = jars;
166 }
167 } catch (Exception e) {
168 e.printStackTrace();
169 }
170 }
171 }
172 resolve(this.libs, wd);
173 resolve(this.classDirs, wd);
174 resolve(this.sources, wd);
175
176
177 for (Iterator iterator = webDirs.iterator(); iterator.hasNext();) {
178 Mapping mapping = (Mapping) iterator.next();
179 String path = mapping.getPath();
180 String dir = mapping.getDir();
181 dir = resolveDir(dir, wd);
182
183
184
185 File classDir = new File(dir, "WEB-INF/classes");
186 if (classDir.exists()) {
187 String fullClassDir = getFullPath(classDir);
188 if (this.classDirs == null) {
189 this.classDirs = new ArrayList();
190 }
191
192 if (!classDirs.contains(fullClassDir)) {
193 classDirs.add(0, fullClassDir);
194 }
195 }
196
197 if (this.mappings == null) {
198 this.mappings = new MultiHashMap();
199 this.pathPriority = new ArrayList();
200 }
201
202 if (!this.pathPriority.contains(path)) {
203 this.pathPriority.add(path);
204 }
205 this.mappings.put(path, dir);
206 }
207 }
208
209 private void resolve(List list, String wd) {
210 if (list != null) {
211 for (int i = 0; i < list.size(); i++) {
212 String s = (String) list.get(i);
213 list.set(i, resolveDir(s, wd));
214 }
215 }
216 }
217
218 private String resolveDir(String dir, String wd) {
219 File file = new File(wd, dir);
220 if (!file.exists() && new File(dir).exists()) {
221 file = new File(dir);
222 }
223
224 return getFullPath(file);
225 }
226
227 private String getFullPath(File file) {
228 try {
229 return file.getCanonicalPath();
230 } catch (IOException e) {
231 return file.getAbsolutePath();
232 }
233 }
234
235 public void resolveExtensions(String wd, XStream xstream) throws FileNotFoundException {
236 if (extendsConfig != null) {
237 File config = new File(wd, extendsConfig);
238 Configuration c = (Configuration) xstream.fromXML(new FileReader(config));
239 c.resolveDirs(config.getParent());
240 c.resolveExtensions(config.getParent(), xstream);
241
242
243 if (c.getResolver() != null) {
244 this.resolver = c.getResolver();
245 }
246
247 if (port == null) {
248 this.port = c.getPort();
249 }
250
251 if (c.getContext() != null) {
252 this.context = c.getContext();
253 }
254
255 if (c.getLibs() != null) {
256 if (this.libs != null) {
257 this.libs.addAll(c.getLibs());
258 } else {
259 this.libs = c.getLibs();
260 }
261 }
262
263 if (c.getClassDirs() != null) {
264 if (this.classDirs != null) {
265 this.classDirs.addAll(c.getClassDirs());
266 } else {
267 this.classDirs = c.getClassDirs();
268 }
269 }
270
271 if (c.getSources() != null) {
272 if (this.sources != null) {
273 this.sources.addAll(c.getSources());
274 } else {
275 this.sources = c.getSources();
276 }
277 }
278
279 for (Iterator iterator = c.getMappings().entrySet().iterator(); iterator.hasNext();) {
280 Map.Entry entry = (Map.Entry) iterator.next();
281 List list = (List) this.mappings.get(entry.getKey());
282 if (list != null) {
283 list.addAll((List) entry.getValue());
284 } else {
285 this.mappings.put(entry.getKey(), (List) entry.getValue());
286 }
287 }
288
289
290 for (Iterator iterator = c.getPathPriority().iterator(); iterator.hasNext();) {
291 String path = (String) iterator.next();
292 if (!this.pathPriority.contains(path)) {
293 this.pathPriority.add(path);
294 }
295 }
296 }
297 }
298
299 public boolean validate() {
300 boolean error = false;
301
302 if (port == null) {
303 System.out.println("Port must be greater than 0");
304 error = true;
305 }
306
307 if (!context.startsWith("/")) {
308 System.out.println("Context must start with /");
309 error = true;
310 }
311
312
313 if (verifyList("Library", libs, false)) {
314 error = true;
315 }
316
317 if (verifyList("ClassDir", classDirs, false)) {
318 error = true;
319 }
320
321 if (verifyList("Sources", sources, true)) {
322 error = true;
323 }
324
325 if (verifyMap("WebApp", mappings)) {
326 error = true;
327 }
328
329 return error;
330 }
331
332 private boolean verifyMap(String name, Map map) {
333 boolean error = false;
334 if (map == null || map.size() == 0) {
335 System.out.println(name + " must be specified");
336 return true;
337 }
338
339 for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
340 Map.Entry entry = (Map.Entry) iterator.next();
341 List list = (List) entry.getValue();
342 verifyList(name, list, false);
343 }
344
345 return error;
346 }
347
348 private boolean verifyList(String name, List list, boolean allowEmpty) {
349 boolean error = false;
350 if (!allowEmpty) {
351 if (list == null || list.size() == 0) {
352 System.out.println(name + " must be specified");
353 return true;
354 }
355 }
356
357 if (list != null) {
358 for (Iterator iterator = list.iterator(); iterator.hasNext();) {
359 String s = (String) iterator.next();
360 if (!new File(s).exists()) {
361 System.out.println(name + " doesn't exist: " + s);
362 error = true;
363 }
364 }
365 }
366
367 return error;
368 }
369 }