001: /* tjws - WebApp.java
002: * Copyright (C) 1999-2007 Dmitriy Rogatkin. All rights reserved.
003: * Redistribution and use in source and binary forms, with or without
004: * modification, are permitted provided that the following conditions
005: * are met:
006: * 1. Redistributions of source code must retain the above copyright
007: * notice, this list of conditions and the following disclaimer.
008: * 2. Redistributions in binary form must reproduce the above copyright
009: * notice, this list of conditions and the following disclaimer in the
010: * documentation and/or other materials provided with the distribution.
011: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
012: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
013: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
014: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
015: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
016: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
017: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
018: * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
019: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
020: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
021: * SUCH DAMAGE.
022: *
023: * Visit http://tjws.sourceforge.net to get the latest infromation
024: * about Rogatkin's products.
025: * $Id: WebApp.java,v 1.11 2007/04/12 05:24:51 rogatkin Exp $
026: * Created on Jun 12, 2006
027: * @author dmitriy
028: */
029: package rogatkin.web;
030:
031: import java.io.BufferedReader;
032: import java.io.File;
033: import java.io.FileInputStream;
034: import java.io.FileOutputStream;
035: import java.io.IOException;
036: import java.io.InputStream;
037: import java.io.InputStreamReader;
038: import java.io.OutputStream;
039: import java.io.UnsupportedEncodingException;
040: import java.lang.reflect.Method;
041: import java.net.URL;
042: import java.net.URLConnection;
043:
044: import Acme.Utils;
045: import Acme.Serve.Main;
046: import Acme.Serve.Serve;
047:
048: public class WebApp extends Main {
049:
050: public static final String RUN_DESCRIPTOR = "rundescriptor";
051:
052: /**
053: * @param args,
054: * 1st specifies .war file location others can match standard If no parameters specifies it considered as all in one and takes run descriptor
055: * from /app/rundescriptor
056: * <p>
057: * rundescriptor file has multiple lines, 1st define command line argument<br>
058: * following define names of .wars in /app/
059: */
060: public static void main(String[] args) {
061: File deployDir;
062: if (System.getProperty("tjws.webappdir") == null) {
063: deployDir = getDeployDirectory("tjws-web-apps");
064: if (deployDir == null) {
065: System.exit(1); // message already printed
066: return;
067: }
068: deployDir.deleteOnExit(); // TODO make it more consistent and provide directory deletion in on exit hook
069: System.setProperty("tjws.webappdir", deployDir.getPath());
070: } else
071: deployDir = new File(System.getProperty("tjws.webappdir"));
072: ServiceController ctrl = null;
073: try {
074: ctrl = (ServiceController) Class.forName(
075: "rogatkin.web.SysTrayControl").newInstance();
076: } catch (Exception ex) {
077: // ex.printStackTrace();
078: }
079: if (args.length > 0) {
080: System.out.printf("Launching %s...%n", args[0]);
081: File warFile = new File(args[0]);
082: try {
083: copyWar(warFile, deployDir);
084: } catch (IOException ioe) {
085: System.err
086: .printf(
087: "Can't copy war %s file to the deployment directory %s exception %s%n",
088: warFile, deployDir, ioe);
089: System.exit(2);
090: }
091: String[] newArgs = new String[args.length - 1];
092: System.arraycopy(args, 1, newArgs, 0, newArgs.length);
093: if (ctrl != null) {
094: newArgs = ctrl.massageSettings(newArgs);
095: ctrl.attachServe(getStopMethod(), warFile.getName()
096: .substring(0, warFile.getName().length() - 4));
097: }
098: Main.main(newArgs);
099: } else {
100: BufferedReader br = null;
101: try {
102: br = new BufferedReader(new InputStreamReader(Thread
103: .currentThread().getContextClassLoader()
104: .getResourceAsStream(RUN_DESCRIPTOR), "utf-8"));
105: } catch (NullPointerException npe) {
106: System.err
107: .printf(
108: "No .war file argument provided and there is no '%s' descriptor for embedded app in the jar packaging%n",
109: RUN_DESCRIPTOR);
110: System.exit(-2);
111: return;
112: } catch (UnsupportedEncodingException e) {
113: System.err.printf("Unexpectable %s%n", e);
114: System.exit(-3);
115: return;
116: }
117: URL warUrl = null;
118: try {
119: // read clp
120: String parameters = br.readLine();
121: // can be loop if more than one war
122: String warName;
123: warUrl = Thread.currentThread().getContextClassLoader()
124: .getResource(warName = br.readLine());
125: copyWar(warUrl, deployDir);
126: if (ctrl != null) {
127: ctrl.attachServe(getStopMethod(), warName
128: .substring(0, warName.length() - 4));
129: Main.main(ctrl.massageSettings(Utils.splitStr(
130: parameters, "\"")));
131: } else
132: Main.main(Utils.splitStr(parameters, "\""));
133: } catch (IOException e) {
134: System.err
135: .printf(
136: "Can't copy war %s file to the deployment directory %s exception %s%n",
137: warUrl, deployDir, e);
138: System.exit(2);
139: }
140: }
141: }
142:
143: private static Method getStopMethod() {
144: try {
145: return Main.class.getDeclaredMethod("stop");
146: } catch (SecurityException e) {
147: } catch (NoSuchMethodException e) {
148: }
149: return null;
150: }
151:
152: public static File getDeployDirectory(String key) {
153: String dirName = System.getProperty("java.io.tmpdir");
154: if (dirName == null) {
155: dirName = System.getProperty("user.home");
156: if (dirName == null)
157: dirName = ".";
158: }
159: File result = new File(dirName, key);
160: try {
161: result = result.getCanonicalFile();
162: result.mkdirs(); // no check because can be existen
163: return result;
164: } catch (IOException e) {
165: System.err.printf(
166: "Can't create a deployment directory: %s %s%n", e,
167: result);
168: }
169: return null;
170: }
171:
172: public static void copyWar(File sourceWar, File deploymentDir)
173: throws IOException {
174: File targetWar = new File(deploymentDir, sourceWar.getName());
175: if (targetWar.exists()
176: && targetWar.lastModified() >= sourceWar.lastModified())
177: return;
178: OutputStream os = null;
179: InputStream is = null;
180: try {
181: Utils.copyStream(is = new FileInputStream(sourceWar),
182: os = new FileOutputStream(targetWar), -1);
183: } finally {
184: try {
185: os.close();
186: } catch (Exception e) {
187: }
188: try {
189: is.close();
190: } catch (Exception e) {
191: }
192: }
193: targetWar.setLastModified(sourceWar.lastModified());
194: }
195:
196: public static void copyWar(URL sourceWar, File deploymentDir)
197: throws IOException {
198: File targetWar = new File(deploymentDir, new File(sourceWar
199: .getFile()).getName());
200: URLConnection uc = sourceWar.openConnection();
201: if (targetWar.exists()
202: && targetWar.lastModified() >= uc.getLastModified())
203: return;
204: OutputStream os = null;
205: InputStream is = null;
206: try {
207: Utils.copyStream(is = uc.getInputStream(),
208: os = new FileOutputStream(targetWar), -1);
209: } finally {
210: try {
211: os.close();
212: } catch (Exception e) {
213: }
214: try {
215: is.close();
216: } catch (Exception e) {
217: }
218: }
219: targetWar.setLastModified(uc.getLastModified());
220: }
221:
222: public static interface ServiceController {
223: void attachServe(Method stop, String contextPath);
224:
225: String[] massageSettings(String[] args);
226: }
227: }
|