001: /* tjws - WarRoller.java
002: * Copyright (C) 2004-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 DAMAGES
016: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
017: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
018: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
019: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
020: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
021: *
022: * $Id: WarRoller.java,v 1.6 2006/12/31 18:20:19 rogatkin Exp $
023: * Created on Dec 13, 2004
024: */
025: package rogatkin.web;
026:
027: import java.io.File;
028: import java.io.FileFilter;
029: import java.io.FileOutputStream;
030: import java.io.IOException;
031: import java.io.InputStream;
032: import java.io.OutputStream;
033: import java.util.Enumeration;
034: import java.util.zip.ZipEntry;
035: import java.util.zip.ZipException;
036: import java.util.zip.ZipFile;
037:
038: import javax.servlet.ServletException;
039:
040: import Acme.Utils;
041: import Acme.Serve.Serve;
042: import Acme.Serve.WarDeployer;
043:
044: public class WarRoller implements WarDeployer {
045:
046: /**
047: * if deplpy mode scan for all wars in war directory (app deployment dir) for each war look in corresponding place of deploy directory figure difference,
048: * like any file in war exists and no corresponding file in deploy directory or it's older if difference positive, then delete target deploy directory
049: * unpack war fi run mode process all WEB-INF/web.xml and build app descriptor, including context name, servlet names, servlet urls, class parameters
050: * process every app descriptor as standard servlet connection proc dispatch for every context name assigned an app dispatcher, it uses the rest to find
051: * servlet and do resource mapping
052: *
053: */
054:
055: public void deploy(File warDir, final File deployTarDir) {
056: //
057: // by list
058: if (warDir.listFiles(new FileFilter() {
059: public boolean accept(File pathname) {
060: if (pathname.isFile()
061: && pathname.getName().toLowerCase().endsWith(
062: ".war")) {
063: deployWar(pathname, deployTarDir);
064: return true;
065: }
066: return false;
067: }
068: }).length == 0)
069: server.log("No .war packaged web apps found.");
070: if (deployTarDir.listFiles(new FileFilter() {
071: public boolean accept(File file) {
072: if (file.isDirectory())
073: try {
074: attachApp(WebAppServlet.create(file, file
075: .getName(), server));
076: return true;
077: } catch (ServletException se) {
078: server.log("Creation of a web app "
079: + file.getName() + " failed due "
080: + se.getRootCause(), se.getRootCause());
081: }
082: return false;
083: }
084: }).length == 0)
085: server.log("No web apps have been deployed.");
086: }
087:
088: public void deployWar(File warFile, File deployTarDir) {
089: String context = warFile.getName();
090: assert context.toLowerCase().endsWith(".war");
091: context = context.substring(0, context.length() - 4);
092: server.log("Deploying " + context);
093: ZipFile zipFile = null;
094: File deployDir = new File(deployTarDir, context);
095: try {
096: // some overhead didn't check that doesn't exist
097: if (assureDir(deployDir) == false) {
098: server.log("Can't reach deployment dir " + deployDir);
099: return;
100: }
101: zipFile = new ZipFile(warFile);
102: Enumeration<? extends ZipEntry> entries = zipFile.entries();
103: while (entries.hasMoreElements()) {
104: ZipEntry ze = entries.nextElement();
105: String en = ze.getName();
106: if (File.separatorChar == '/')
107: en = en.replace('\\', File.separatorChar);
108: File outFile = new File(deployDir, en);
109: if (ze.isDirectory()) {
110: outFile.mkdirs();
111: } else {
112: OutputStream os = null;
113: InputStream is = null;
114: File parentFile = outFile.getParentFile();
115: if (parentFile.exists() == false)
116: parentFile.mkdirs();
117: if (outFile.exists()
118: && outFile.lastModified() >= ze.getTime()) {
119: continue;
120: }
121: try {
122: os = new FileOutputStream(outFile);
123: is = zipFile.getInputStream(ze);
124: copyStream(is, os);
125: outFile.setLastModified(ze.getTime());
126: } catch (IOException ioe2) {
127: server.log("problem in extracting " + en + " "
128: + ioe2);
129: } finally {
130: try {
131: os.close();
132: } catch (Exception e2) {
133:
134: }
135: try {
136: is.close();
137: } catch (Exception e2) {
138:
139: }
140: }
141: }
142: }
143: } catch (ZipException ze) {
144: server.log("Invalid .war format");
145: } catch (IOException ioe) {
146: server.log("Can't read " + warFile + "/ " + ioe);
147: } finally {
148: try {
149: zipFile.close();
150: zipFile = null;
151: } catch (Exception e) {
152:
153: }
154: }
155: }
156:
157: public void attachApp(WebAppServlet appServlet) {
158: server.addServlet(appServlet.contextPath, appServlet);
159: }
160:
161: public void deploy(Serve server) {
162: this .server = server;
163: String webapp_dir = System.getProperty("tjws.webappdir");
164: if (webapp_dir == null)
165: webapp_dir = System.getProperty("user.dir")
166: + File.separator + "webapps";
167: File file_webapp = new File(webapp_dir);
168: if (assureDir(file_webapp) == false) {
169: server.log("Web app " + file_webapp
170: + " isn't a directory, deployment impossible.");
171: return;
172: }
173: File file_deployDir = new File(file_webapp, "~web-apps~");
174: if (assureDir(file_deployDir) == false) {
175: server.log("Target deployment " + file_deployDir
176: + " isn't a directory, deployment impossible.");
177: return;
178: }
179: deploy(file_webapp, file_deployDir);
180: }
181:
182: protected boolean assureDir(File fileDir) {
183: if (fileDir.exists() == false)
184: fileDir.mkdirs();
185: if (fileDir.isDirectory() == false) {
186: return false;
187: }
188: return true;
189: }
190:
191: static void copyStream(InputStream is, OutputStream os)
192: throws IOException {
193: Utils.copyStream(is, os, -1);
194: }
195:
196: protected Serve server;
197: }
|