View Javadoc

1   /**
2    *
3    * Copyright 2005 The Apache Software Foundation
4    *
5    *  Licensed under the Apache License, Version 2.0 (the "License");
6    *  you may not use this file except in compliance with the License.
7    *  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  package org.apache.geronimo.system.configuration;
18  
19  import java.io.File;
20  import java.io.FileInputStream;
21  import java.io.FileOutputStream;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.OutputStream;
25  import java.io.OutputStreamWriter;
26  import java.io.PrintWriter;
27  import java.io.FileWriter;
28  import java.io.Writer;
29  import java.net.URI;
30  import java.util.Collection;
31  import java.util.Collections;
32  import java.util.Iterator;
33  import java.util.LinkedList;
34  import java.util.Arrays;
35  import java.util.jar.JarOutputStream;
36  import java.util.jar.Manifest;
37  import java.util.zip.ZipEntry;
38  
39  import org.apache.geronimo.kernel.config.ConfigurationData;
40  import org.apache.geronimo.kernel.config.ConfigurationUtil;
41  
42  /**
43   * @version $Rev: 410723 $ $Date: 2006-05-31 20:16:46 -0700 (Wed, 31 May 2006) $
44   */
45  public final class ExecutableConfigurationUtil {
46      private static final String META_INF = "META-INF";
47      private static final String CONFIG_SER = "config.ser";
48      private static final String CONFIG_INFO = "config.info";
49      private static final String META_INF_STARTUP_JAR = META_INF + "/startup-jar";
50      private static final String META_INF_CONFIG_SER = META_INF + "/" + CONFIG_SER;
51      private static final String META_INF_CONFIG_SER_SHA1 = META_INF_CONFIG_SER + ".sha1";
52      private static final String META_INF_CONFIG_INFO = META_INF + "/" + CONFIG_INFO;
53  
54      private static final Collection EXCLUDED = Arrays.asList(new String[] {META_INF_STARTUP_JAR, META_INF_CONFIG_SER, META_INF_CONFIG_SER_SHA1, META_INF_CONFIG_INFO});
55  
56      private ExecutableConfigurationUtil() {
57      }
58  
59      public static void createExecutableConfiguration(ConfigurationData configurationData, Manifest manifest, File destinationFile) throws IOException {
60          File configurationDir = configurationData.getConfigurationDir();
61          
62          // ensure parent directories have been created
63          File parent = destinationFile.getParentFile();
64          if (parent != null && !parent.exists()) parent.mkdirs();
65          
66          FileOutputStream fos = null;
67          JarOutputStream out = null;
68          try {
69              byte[] buffer = new byte[4096];
70  
71              fos = new FileOutputStream(destinationFile, false);
72              
73              if (manifest != null) {
74                  out = new JarOutputStream(fos, manifest); 
75  
76                  // add the startup file which allows us to locate the startup directory
77                  out.putNextEntry(new ZipEntry(META_INF_STARTUP_JAR));
78                  // intentionally empty ZipEntry
79                  out.closeEntry();
80              } else {
81                  out = new JarOutputStream(fos);
82              }
83  
84              // write the configurationData
85              ExecutableConfigurationUtil.writeConfiguration(configurationData, out);
86  
87              URI baseURI = configurationDir.getAbsoluteFile().toURI();
88              Collection files = listRecursiveFiles(configurationDir);
89              for (Iterator iterator = files.iterator(); iterator.hasNext();) {
90                  File file = (File) iterator.next();
91                  String relativePath = baseURI.relativize(file.toURI()).getPath();
92                  if (!EXCLUDED.contains(relativePath)) {
93                      InputStream in = new FileInputStream(file);
94                      try {
95                          out.putNextEntry(new ZipEntry(relativePath));
96                          try {
97                              int count;
98                              while ((count = in.read(buffer)) > 0) {
99                                  out.write(buffer, 0, count);
100                             }
101                         } finally {
102                             out.closeEntry();
103                         }
104                     } finally {
105                         close(in);
106                     }
107                 }
108             }
109         } finally {
110             close(out);
111             close(fos); // do this in case JarOutputStream contructor threw an exception
112         }
113     }
114 
115     public static void writeConfiguration(ConfigurationData configurationData, JarOutputStream out) throws IOException {
116         // save the persisted form in the source directory
117         out.putNextEntry(new ZipEntry(META_INF_CONFIG_SER));
118         ConfigurationStoreUtil.ChecksumOutputStream sumOut = null;
119         try {
120             sumOut = new ConfigurationStoreUtil.ChecksumOutputStream(out);
121             ConfigurationUtil.writeConfigurationData(configurationData, sumOut);
122         } finally {
123             out.closeEntry();
124         }
125 
126         // write the checksum file
127         out.putNextEntry(new ZipEntry(META_INF_CONFIG_SER_SHA1));
128         try {
129             OutputStreamWriter writer = new OutputStreamWriter(out);
130             writer.write(sumOut.getChecksum());
131             writer.flush();
132         } finally {
133             out.closeEntry();
134         }
135 
136         // write the info file
137         out.putNextEntry(new ZipEntry(META_INF_CONFIG_INFO));
138         try {
139             PrintWriter writer = new PrintWriter(new OutputStreamWriter(out));
140             ConfigurationUtil.writeConfigInfo(writer, configurationData);
141             writer.flush();
142         } finally {
143             out.closeEntry();
144         }
145     }
146 
147     public static void writeConfiguration(ConfigurationData configurationData, File source) throws IOException {
148         // save the persisted form in the source directory
149         File metaInf = new File(source, META_INF);
150         metaInf.mkdirs();
151         File configSer = new File(metaInf, CONFIG_SER);
152 
153         OutputStream out = new FileOutputStream(configSer);
154         try {
155             ConfigurationUtil.writeConfigurationData(configurationData, out);
156         } finally {
157             flush(out);
158             close(out);
159         }
160 
161         // write the check sum file
162         ConfigurationStoreUtil.writeChecksumFor(configSer);
163 
164         // write the info file
165         PrintWriter writer = null;
166         try {
167             writer = new PrintWriter(new FileWriter(new File(metaInf, CONFIG_INFO)));
168             ConfigurationUtil.writeConfigInfo(writer, configurationData);
169         } finally {
170             flush(writer);
171             close(writer);
172         }
173     }
174 
175     private static Collection listRecursiveFiles(File file) {
176         LinkedList list = new LinkedList();
177         listRecursiveFiles(file, list);
178         return Collections.unmodifiableCollection(list);
179     }
180 
181     private static void listRecursiveFiles(File file, Collection collection) {
182         File[] files = file.listFiles();
183         if (null == files) {
184             return;
185         }
186         for (int i = 0; i < files.length; i++) {
187             if (files[i].isDirectory()) {
188                 listRecursiveFiles(files[i], collection);
189             } else {
190                 collection.add(files[i]);
191             }
192         }
193     }
194 
195     private static void flush(OutputStream thing) {
196         if (thing != null) {
197             try {
198                 thing.flush();
199             } catch (Exception ignored) {
200             }
201         }
202     }
203 
204     private static void flush(Writer thing) {
205         if (thing != null) {
206             try {
207                 thing.flush();
208             } catch (Exception ignored) {
209             }
210         }
211     }
212 
213     private static void close(InputStream thing) {
214         if (thing != null) {
215             try {
216                 thing.close();
217             } catch (Exception ignored) {
218             }
219         }
220     }
221 
222     private static void close(OutputStream thing) {
223         if (thing != null) {
224             try {
225                 thing.close();
226             } catch (Exception ignored) {
227             }
228         }
229     }
230 
231     private static void close(Writer thing) {
232         if (thing != null) {
233             try {
234                 thing.close();
235             } catch (Exception ignored) {
236             }
237         }
238     }
239 }