KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > startup > ExpandWar


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18
19 package org.apache.catalina.startup;
20
21 import java.io.BufferedOutputStream JavaDoc;
22 import java.io.File JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.FileOutputStream JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.net.JarURLConnection JavaDoc;
28 import java.net.URL JavaDoc;
29 import java.nio.channels.FileChannel JavaDoc;
30 import java.util.Enumeration JavaDoc;
31 import java.util.jar.JarEntry JavaDoc;
32 import java.util.jar.JarFile JavaDoc;
33
34 import org.apache.catalina.Host;
35 import org.apache.catalina.util.StringManager;
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38
39 /**
40  * Expand out a WAR in a Host's appBase.
41  *
42  * @author Craig R. McClanahan
43  * @author Remy Maucherat
44  * @author Glenn L. Nielsen
45  * @version $Revision: 467222 $
46  */

47
48 public class ExpandWar {
49
50     private static Log log = LogFactory.getLog(ExpandWar.class);
51
52     /**
53      * The string resources for this package.
54      */

55     protected static final StringManager sm =
56         StringManager.getManager(Constants.Package);
57
58
59     /**
60      * Expand the WAR file found at the specified URL into an unpacked
61      * directory structure, and return the absolute pathname to the expanded
62      * directory.
63      *
64      * @param host Host war is being installed for
65      * @param war URL of the web application archive to be expanded
66      * (must start with "jar:")
67      *
68      * @exception IllegalArgumentException if this is not a "jar:" URL
69      * @exception IOException if an input/output error was encountered
70      * during expansion
71      */

72     public static String JavaDoc expand(Host host, URL JavaDoc war)
73         throws IOException JavaDoc {
74
75         // Calculate the directory name of the expanded directory
76
if (host.getLogger().isDebugEnabled()) {
77             host.getLogger().debug("expand(" + war.toString() + ")");
78         }
79         String JavaDoc pathname = war.toString().replace('\\', '/');
80         if (pathname.endsWith("!/")) {
81             pathname = pathname.substring(0, pathname.length() - 2);
82         }
83         int period = pathname.lastIndexOf('.');
84         if (period >= pathname.length() - 4)
85             pathname = pathname.substring(0, period);
86         int slash = pathname.lastIndexOf('/');
87         if (slash >= 0) {
88             pathname = pathname.substring(slash + 1);
89         }
90         if (host.getLogger().isDebugEnabled()) {
91             host.getLogger().debug(" Proposed directory name: " + pathname);
92         }
93         return expand(host, war, pathname);
94
95     }
96
97
98     /**
99      * Expand the WAR file found at the specified URL into an unpacked
100      * directory structure, and return the absolute pathname to the expanded
101      * directory.
102      *
103      * @param host Host war is being installed for
104      * @param war URL of the web application archive to be expanded
105      * (must start with "jar:")
106      * @param pathname Context path name for web application
107      *
108      * @exception IllegalArgumentException if this is not a "jar:" URL
109      * @exception IOException if an input/output error was encountered
110      * during expansion
111      */

112     public static String JavaDoc expand(Host host, URL JavaDoc war, String JavaDoc pathname)
113         throws IOException JavaDoc {
114
115         // Make sure that there is no such directory already existing
116
File JavaDoc appBase = new File JavaDoc(host.getAppBase());
117         if (!appBase.isAbsolute()) {
118             appBase = new File JavaDoc(System.getProperty("catalina.base"),
119                                host.getAppBase());
120         }
121         if (!appBase.exists() || !appBase.isDirectory()) {
122             throw new IOException JavaDoc
123                 (sm.getString("hostConfig.appBase",
124                               appBase.getAbsolutePath()));
125         }
126         File JavaDoc docBase = new File JavaDoc(appBase, pathname);
127         if (docBase.exists()) {
128             // War file is already installed
129
return (docBase.getAbsolutePath());
130         }
131
132         // Create the new document base directory
133
docBase.mkdir();
134
135         // Expand the WAR into the new document base directory
136
JarURLConnection JavaDoc juc = (JarURLConnection JavaDoc) war.openConnection();
137         juc.setUseCaches(false);
138         JarFile JavaDoc jarFile = null;
139         InputStream JavaDoc input = null;
140         try {
141             jarFile = juc.getJarFile();
142             Enumeration JavaDoc jarEntries = jarFile.entries();
143             while (jarEntries.hasMoreElements()) {
144                 JarEntry JavaDoc jarEntry = (JarEntry JavaDoc) jarEntries.nextElement();
145                 String JavaDoc name = jarEntry.getName();
146                 int last = name.lastIndexOf('/');
147                 if (last >= 0) {
148                     File JavaDoc parent = new File JavaDoc(docBase,
149                                            name.substring(0, last));
150                     parent.mkdirs();
151                 }
152                 if (name.endsWith("/")) {
153                     continue;
154                 }
155                 input = jarFile.getInputStream(jarEntry);
156
157                 // Bugzilla 33636
158
File JavaDoc expandedFile = expand(input, docBase, name);
159                 long lastModified = jarEntry.getTime();
160                 if ((lastModified != -1) && (lastModified != 0) && (expandedFile != null)) {
161                     expandedFile.setLastModified(lastModified);
162                 }
163
164                 input.close();
165                 input = null;
166             }
167         } catch (IOException JavaDoc e) {
168             // If something went wrong, delete expanded dir to keep things
169
// clean
170
deleteDir(docBase);
171             throw e;
172         } finally {
173             if (input != null) {
174                 try {
175                     input.close();
176                 } catch (Throwable JavaDoc t) {
177                     ;
178                 }
179                 input = null;
180             }
181             if (jarFile != null) {
182                 try {
183                     jarFile.close();
184                 } catch (Throwable JavaDoc t) {
185                     ;
186                 }
187                 jarFile = null;
188             }
189         }
190
191         // Return the absolute path to our new document base directory
192
return (docBase.getAbsolutePath());
193
194     }
195
196
197     /**
198      * Copy the specified file or directory to the destination.
199      *
200      * @param src File object representing the source
201      * @param dest File object representing the destination
202      */

203     public static boolean copy(File JavaDoc src, File JavaDoc dest) {
204         
205         boolean result = true;
206         
207         String JavaDoc files[] = null;
208         if (src.isDirectory()) {
209             files = src.list();
210             result = dest.mkdir();
211         } else {
212             files = new String JavaDoc[1];
213             files[0] = "";
214         }
215         if (files == null) {
216             files = new String JavaDoc[0];
217         }
218         for (int i = 0; (i < files.length) && result; i++) {
219             File JavaDoc fileSrc = new File JavaDoc(src, files[i]);
220             File JavaDoc fileDest = new File JavaDoc(dest, files[i]);
221             if (fileSrc.isDirectory()) {
222                 result = copy(fileSrc, fileDest);
223             } else {
224                 FileChannel JavaDoc ic = null;
225                 FileChannel JavaDoc oc = null;
226                 try {
227                     ic = (new FileInputStream JavaDoc(fileSrc)).getChannel();
228                     oc = (new FileOutputStream JavaDoc(fileDest)).getChannel();
229                     ic.transferTo(0, ic.size(), oc);
230                 } catch (IOException JavaDoc e) {
231                     log.error(sm.getString
232                             ("expandWar.copy", fileSrc, fileDest), e);
233                     result = false;
234                 } finally {
235                     if (ic != null) {
236                         try {
237                             ic.close();
238                         } catch (IOException JavaDoc e) {
239                         }
240                     }
241                     if (oc != null) {
242                         try {
243                             oc.close();
244                         } catch (IOException JavaDoc e) {
245                         }
246                     }
247                 }
248             }
249         }
250         return result;
251         
252     }
253     
254     
255     /**
256      * Delete the specified directory, including all of its contents and
257      * subdirectories recursively.
258      *
259      * @param dir File object representing the directory to be deleted
260      */

261     public static boolean delete(File JavaDoc dir) {
262         if (dir.isDirectory()) {
263             return deleteDir(dir);
264         } else {
265             return dir.delete();
266         }
267     }
268     
269     
270     /**
271      * Delete the specified directory, including all of its contents and
272      * subdirectories recursively.
273      *
274      * @param dir File object representing the directory to be deleted
275      */

276     public static boolean deleteDir(File JavaDoc dir) {
277
278         String JavaDoc files[] = dir.list();
279         if (files == null) {
280             files = new String JavaDoc[0];
281         }
282         for (int i = 0; i < files.length; i++) {
283             File JavaDoc file = new File JavaDoc(dir, files[i]);
284             if (file.isDirectory()) {
285                 deleteDir(file);
286             } else {
287                 file.delete();
288             }
289         }
290         return dir.delete();
291
292     }
293
294
295     /**
296      * Expand the specified input stream into the specified directory, creating
297      * a file named from the specified relative path.
298      *
299      * @param input InputStream to be copied
300      * @param docBase Document base directory into which we are expanding
301      * @param name Relative pathname of the file to be created
302      * @return A handle to the expanded File
303      *
304      * @exception IOException if an input/output error occurs
305      */

306     protected static File JavaDoc expand(InputStream JavaDoc input, File JavaDoc docBase, String JavaDoc name)
307         throws IOException JavaDoc {
308
309         File JavaDoc file = new File JavaDoc(docBase, name);
310         BufferedOutputStream JavaDoc output = null;
311         try {
312             output =
313                 new BufferedOutputStream JavaDoc(new FileOutputStream JavaDoc(file));
314             byte buffer[] = new byte[2048];
315             while (true) {
316                 int n = input.read(buffer);
317                 if (n <= 0)
318                     break;
319                 output.write(buffer, 0, n);
320             }
321         } finally {
322             if (output != null) {
323                 try {
324                     output.close();
325                 } catch (IOException JavaDoc e) {
326                     // Ignore
327
}
328             }
329         }
330
331         return file;
332     }
333
334
335 }
336
Popular Tags