View Javadoc

1   /*
2    * $Id: Configuration.java 454251 2006-10-09 02:10:57Z husted $
3    *
4    * Copyright 2006 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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         // now resolve the web dirs
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             // if the ${dir}/WEB-INF/classes dir exists and isn't already added to the classDirs, let's do it
184             // ... but make sure we put it at the front (to obey the class loading behaviors)
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             // now copy over the props
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             // add only new paths
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 }