001: /*
002: * Copyright (c) 2002-2006 by OpenSymphony
003: * All rights reserved.
004: */
005: package com.opensymphony.webwork.quickstart;
006:
007: import com.thoughtworks.xstream.XStream;
008: import org.apache.commons.collections.MultiHashMap;
009: import org.w3c.dom.Document;
010: import org.w3c.dom.NodeList;
011: import org.w3c.dom.Element;
012: import org.xml.sax.SAXException;
013:
014: import javax.xml.parsers.DocumentBuilderFactory;
015: import javax.xml.parsers.DocumentBuilder;
016: import javax.xml.parsers.ParserConfigurationException;
017: import java.io.*;
018: import java.util.ArrayList;
019: import java.util.Iterator;
020: import java.util.List;
021: import java.util.Map;
022:
023: /**
024: * Configuration for the QuickStart program.
025: * @author patrick
026: */
027: public class Configuration implements Serializable {
028: String ideaConfig;
029: String extendsConfig;
030: String resolver;
031: Integer port;
032: String context;
033: List libs;
034: List classDirs;
035: List sources;
036: List webDirs;
037: Map mappings;
038: List pathPriority;
039:
040: public String getIdeaConfig() {
041: return ideaConfig;
042: }
043:
044: public void setIdeaConfig(String ideaConfig) {
045: this .ideaConfig = ideaConfig;
046: }
047:
048: public String getExtendsConfig() {
049: return extendsConfig;
050: }
051:
052: public void setExtendsConfig(String extendsConfig) {
053: this .extendsConfig = extendsConfig;
054: }
055:
056: public String getResolver() {
057: return resolver;
058: }
059:
060: public void setResolver(String resolver) {
061: this .resolver = resolver;
062: }
063:
064: public List getLibs() {
065: return libs;
066: }
067:
068: public void setLibs(List libs) {
069: this .libs = libs;
070: }
071:
072: public List getClassDirs() {
073: return classDirs;
074: }
075:
076: public void setClassDirs(List classDirs) {
077: this .classDirs = classDirs;
078: }
079:
080: public List getSources() {
081: return sources;
082: }
083:
084: public void setSources(List sources) {
085: this .sources = sources;
086: }
087:
088: public Map getMappings() {
089: return mappings;
090: }
091:
092: public List getPathPriority() {
093: return pathPriority;
094: }
095:
096: public List getWebDirs() {
097: return webDirs;
098: }
099:
100: public void setWebDirs(List webDirs) {
101: this .webDirs = webDirs;
102: }
103:
104: public Integer getPort() {
105: return port;
106: }
107:
108: public void setPort(Integer port) {
109: this .port = port;
110: }
111:
112: public String getContext() {
113: return context;
114: }
115:
116: public void setContext(String context) {
117: this .context = context;
118: }
119:
120: public void resolveDirs(String wd) {
121: if (ideaConfig != null) {
122: String full = resolveDir(this .ideaConfig, wd);
123:
124: try {
125: DocumentBuilder db = DocumentBuilderFactory
126: .newInstance().newDocumentBuilder();
127: Document doc = db.parse(full);
128: NodeList components = doc.getElementsByTagName("root");
129: List jars = new ArrayList();
130: for (int i = 0; i < components.getLength(); i++) {
131: Element e = (Element) components.item(i);
132: String value = e.getAttribute("url");
133: if (value != null && value.startsWith("jar://")
134: && value.endsWith(".jar!/")) {
135: value = value.substring(6, value.length() - 2);
136: if (value.startsWith("$MODULE_DIR$")) {
137: value = value.substring(13);
138: }
139: jars.add(value);
140: }
141: }
142:
143: if (this .libs != null) {
144: this .libs.addAll(jars);
145: } else {
146: this .libs = jars;
147: }
148: } catch (Exception e) {
149: e.printStackTrace();
150: }
151: }
152: resolve(this .libs, wd);
153: resolve(this .classDirs, wd);
154: resolve(this .sources, wd);
155:
156: // now resolve the web dirs
157: for (Iterator iterator = webDirs.iterator(); iterator.hasNext();) {
158: Mapping mapping = (Mapping) iterator.next();
159: String path = mapping.getPath();
160: String dir = mapping.getDir();
161: dir = resolveDir(dir, wd);
162:
163: // if the ${dir}/WEB-INF/classes dir exists and isn't already added to the classDirs, let's do it
164: // ... but make sure we put it at the front (to obey the class loading behaviors)
165: File classDir = new File(dir, "WEB-INF/classes");
166: if (classDir.exists()) {
167: String fullClassDir = getFullPath(classDir);
168: if (this .classDirs == null) {
169: this .classDirs = new ArrayList();
170: }
171:
172: if (!classDirs.contains(fullClassDir)) {
173: classDirs.add(0, fullClassDir);
174: }
175: }
176:
177: if (this .mappings == null) {
178: this .mappings = new MultiHashMap();
179: this .pathPriority = new ArrayList();
180: }
181:
182: if (!this .pathPriority.contains(path)) {
183: this .pathPriority.add(path);
184: }
185: this .mappings.put(path, dir);
186: }
187: }
188:
189: private void resolve(List list, String wd) {
190: if (list != null) {
191: for (int i = 0; i < list.size(); i++) {
192: String s = (String) list.get(i);
193: list.set(i, resolveDir(s, wd));
194: }
195: }
196: }
197:
198: private String resolveDir(String dir, String wd) {
199: File file = new File(wd, dir);
200: if (!file.exists() && new File(dir).exists()) {
201: file = new File(dir);
202: }
203:
204: return getFullPath(file);
205: }
206:
207: private String getFullPath(File file) {
208: try {
209: return file.getCanonicalPath();
210: } catch (IOException e) {
211: return file.getAbsolutePath();
212: }
213: }
214:
215: public void resolveExtensions(String wd, XStream xstream)
216: throws FileNotFoundException {
217: if (extendsConfig != null) {
218: File config = new File(wd, extendsConfig);
219: Configuration c = (Configuration) xstream
220: .fromXML(new FileReader(config));
221: c.resolveDirs(config.getParent());
222: c.resolveExtensions(config.getParent(), xstream);
223:
224: // now copy over the props
225: if (c.getResolver() != null) {
226: this .resolver = c.getResolver();
227: }
228:
229: if (port == null) {
230: this .port = c.getPort();
231: }
232:
233: if (c.getContext() != null) {
234: this .context = c.getContext();
235: }
236:
237: if (c.getLibs() != null) {
238: if (this .libs != null) {
239: this .libs.addAll(c.getLibs());
240: } else {
241: this .libs = c.getLibs();
242: }
243: }
244:
245: if (c.getClassDirs() != null) {
246: if (this .classDirs != null) {
247: this .classDirs.addAll(c.getClassDirs());
248: } else {
249: this .classDirs = c.getClassDirs();
250: }
251: }
252:
253: if (c.getSources() != null) {
254: if (this .sources != null) {
255: this .sources.addAll(c.getSources());
256: } else {
257: this .sources = c.getSources();
258: }
259: }
260:
261: for (Iterator iterator = c.getMappings().entrySet()
262: .iterator(); iterator.hasNext();) {
263: Map.Entry entry = (Map.Entry) iterator.next();
264: List list = (List) this .mappings.get(entry.getKey());
265: if (list != null) {
266: list.addAll((List) entry.getValue());
267: } else {
268: this .mappings.put(entry.getKey(), (List) entry
269: .getValue());
270: }
271: }
272:
273: // add only new paths
274: for (Iterator iterator = c.getPathPriority().iterator(); iterator
275: .hasNext();) {
276: String path = (String) iterator.next();
277: if (!this .pathPriority.contains(path)) {
278: this .pathPriority.add(path);
279: }
280: }
281: }
282: }
283:
284: public boolean validate() {
285: boolean error = false;
286:
287: if (port == null) {
288: System.out.println("Port must be greater than 0");
289: error = true;
290: }
291:
292: if (!context.startsWith("/")) {
293: System.out.println("Context must start with /");
294: error = true;
295: }
296:
297: if (verifyList("Library", libs, false)) {
298: error = true;
299: }
300:
301: if (verifyList("ClassDir", classDirs, false)) {
302: error = true;
303: }
304:
305: if (verifyList("Sources", sources, true)) {
306: error = true;
307: }
308:
309: if (verifyMap("WebApp", mappings)) {
310: error = true;
311: }
312:
313: return error;
314: }
315:
316: private boolean verifyMap(String name, Map map) {
317: boolean error = false;
318: if (map == null || map.size() == 0) {
319: System.out.println(name + " must be specified");
320: return true;
321: }
322:
323: for (Iterator iterator = map.entrySet().iterator(); iterator
324: .hasNext();) {
325: Map.Entry entry = (Map.Entry) iterator.next();
326: List list = (List) entry.getValue();
327: verifyList(name, list, false);
328: }
329:
330: return error;
331: }
332:
333: private boolean verifyList(String name, List list,
334: boolean allowEmpty) {
335: boolean error = false;
336: if (!allowEmpty) {
337: if (list == null || list.size() == 0) {
338: System.out.println(name + " must be specified");
339: return true;
340: }
341: }
342:
343: if (list != null) {
344: for (Iterator iterator = list.iterator(); iterator
345: .hasNext();) {
346: String s = (String) iterator.next();
347: if (!new File(s).exists()) {
348: System.out.println(name + " doesn't exist: " + s);
349: error = true;
350: }
351: }
352: }
353:
354: return error;
355: }
356: }
|