001: /*
002: * Copyright (c) 2002-2006 by OpenSymphony
003: * All rights reserved.
004: */
005: package com.opensymphony.webwork.quickstart;
006:
007: import com.opensymphony.webwork.util.classloader.CompilingClassLoader;
008: import com.thoughtworks.xstream.XStream;
009: import com.thoughtworks.xstream.io.xml.DomDriver;
010:
011: import java.io.File;
012: import java.io.FileReader;
013: import java.io.FileNotFoundException;
014: import java.net.URL;
015: import java.net.URLClassLoader;
016: import java.net.MalformedURLException;
017: import java.util.*;
018: import java.lang.reflect.Method;
019: import java.lang.reflect.InvocationTargetException;
020:
021: /**
022: * The QuickStart main program.
023: *
024: * @author plightbo
025: */
026: public class QuickStart {
027: public static void main(String[] args)
028: throws FileNotFoundException, MalformedURLException,
029: ClassNotFoundException, NoSuchMethodException,
030: IllegalAccessException, InvocationTargetException {
031: if (args.length != 3 && args.length != 0) {
032: System.err
033: .println("QuickStart must be either invoked with three arguments or no arguments:");
034: System.err.println("[contextPath] [webapp] [sources]");
035: System.err.println("");
036: System.err.println("Ex: java -jar webwork.jar \\");
037: System.err
038: .println(" quickstart /sandbox sandbox/src/webapp sandbox/src/java");
039: System.err.println("");
040: System.err.println("OR");
041: System.err.println("");
042: System.err.println("Ex: java -jar webwork.jar quickstart");
043: System.err
044: .println(" Where a 'quickstart.xml' file exists in your working directory");
045: return;
046: }
047:
048: Configuration c;
049: if (args.length == 0) {
050: XStream xstream = new XStream(new DomDriver());
051: xstream.alias("configuration", Configuration.class);
052: xstream.alias("extendsConfig", String.class);
053: xstream.alias("port", int.class);
054: xstream.alias("context", String.class);
055: xstream.alias("dir", String.class);
056: xstream.alias("path", String.class);
057: xstream.alias("webDir", Mapping.class);
058: File config = new File("quickstart.xml");
059: if (!config.exists()) {
060: // uh oh, time to stop
061: System.err.println("Could not find quickstart.xml!");
062: System.err
063: .println("Tip: quickstart.xml must exist in your working directory");
064: System.err.println("");
065: System.err
066: .println("Alternatively, if you your deployment is simple, try launching");
067: System.err
068: .println("QuickStart using the simple command line options rather than");
069: System.err
070: .println("Relying on quickstart.xml existing");
071: return;
072: }
073:
074: c = (Configuration) xstream.fromXML(new FileReader(config));
075: c.resolveDirs(config.getParent());
076: c.resolveExtensions(config.getParent(), xstream);
077: } else {
078: c = new Configuration();
079: c.setContext(args[0]);
080: c.setPort(new Integer(8080));
081: ArrayList webDirs = new ArrayList();
082: webDirs.add(new Mapping("/", args[1]));
083: c.setWebDirs(webDirs);
084: ArrayList sources = new ArrayList();
085: sources.add(args[2]);
086: c.setSources(sources);
087: ArrayList classDirs = new ArrayList();
088: classDirs.add(args[1] + "/WEB-INF/classes");
089: classDirs.add(args[2]);
090: c.setClassDirs(classDirs);
091: ArrayList libs = new ArrayList();
092: libs.add("lib");
093: c.setLibs(libs);
094:
095: c.resolveDirs(new File(".").getParent());
096: }
097:
098: // validate the configuration
099: if (c.validate()) {
100: return;
101: }
102:
103: // explain what is being executed
104: System.out
105: .println("Launching Jetty with the following configuration:");
106: System.out.println("Jars/Directory of jars:");
107: for (Iterator iterator = c.getLibs().iterator(); iterator
108: .hasNext();) {
109: String s = (String) iterator.next();
110: System.out.println(" " + s);
111: }
112: System.out.println("Directories of classes:");
113: for (Iterator iterator = c.getClassDirs().iterator(); iterator
114: .hasNext();) {
115: String s = (String) iterator.next();
116: System.out.println(" " + s);
117: }
118: if (c.getSources() != null) {
119: System.out.println("Sources:");
120: for (Iterator iterator = c.getSources().iterator(); iterator
121: .hasNext();) {
122: String s = (String) iterator.next();
123: System.out.println(" " + s);
124: }
125: }
126: System.out.println("WebApp directories:");
127: for (Iterator iterator = c.getMappings().entrySet().iterator(); iterator
128: .hasNext();) {
129: Map.Entry entry = (Map.Entry) iterator.next();
130: System.out.println(entry.getKey() + " -> "
131: + entry.getValue());
132: }
133:
134: // prepare the classloader
135: List libs = c.getLibs();
136: List classDirs = c.getClassDirs();
137: ClassLoader parent = new MultiDirClassLoader((String[]) libs
138: .toArray(new String[libs.size()]), (String[]) classDirs
139: .toArray(new String[classDirs.size()]), Thread
140: .currentThread().getContextClassLoader());
141:
142: if (c.getSources() != null) {
143: for (Iterator iterator = c.getSources().iterator(); iterator
144: .hasNext();) {
145: String source = (String) iterator.next();
146: File file = new File(source);
147: CompilingClassLoader ccl = new CompilingClassLoader(
148: parent, file);
149: ccl.start();
150: parent = ccl;
151: }
152: }
153: URLClassLoader url = new MyURLClassLoader(parent);
154: Thread.currentThread().setContextClassLoader(url);
155:
156: Class clazz = url
157: .loadClass("com.opensymphony.webwork.quickstart.JettyServer");
158: Method method = clazz.getDeclaredMethod("startServer",
159: new Class[] { int.class, String.class, List.class,
160: Map.class, String.class });
161: method
162: .invoke(null, new Object[] { c.port, c.getContext(),
163: c.getPathPriority(), c.getMappings(),
164: c.getResolver() });
165:
166: System.out.println("");
167: System.out
168: .println("********************************************************");
169: System.out.println("Quick-started at http://localhost:"
170: + c.getPort() + c.getContext());
171: System.out
172: .println("You may now edit your Java source files and web files.");
173: System.out
174: .println("********************************************************");
175: }
176:
177: static class MyURLClassLoader extends URLClassLoader {
178: private ClassLoader parent;
179:
180: public MyURLClassLoader(ClassLoader parent) {
181: super (new URL[0], parent);
182: this .parent = parent;
183: }
184:
185: public Class loadClass(String name, boolean resolve)
186: throws ClassNotFoundException {
187: if (name.startsWith("org.xml.")
188: || name.startsWith("org.w3c.")
189: || name.startsWith("java.")
190: || name.startsWith("javax.")
191: || name.startsWith("sun.")
192: || name.startsWith("com.sun.")) {
193: return super .loadClass(name, resolve);
194: }
195:
196: ClassLoader parent = getParent();
197: // First, check if the class has already been loaded
198: Class c = findLoadedClass(name);
199: if (c == null) {
200: try {
201: c = findClass(name);
202: } catch (Throwable t) {
203: // If still not found, only then ask the parent
204: c = parent.loadClass(name);
205: }
206: }
207: if (resolve) {
208: resolveClass(c);
209: }
210:
211: return c;
212: }
213:
214: public URL getResource(String name) {
215: URL url = findResource(name);
216: if (url == null && parent != null) {
217: url = parent.getResource(name);
218: }
219:
220: return url;
221: }
222: }
223: }
|