001 /**
002 *
003 * Copyright 2005 The Apache Software Foundation
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.geronimo.system.configuration;
018
019 import java.io.File;
020 import java.io.FileInputStream;
021 import java.io.FileOutputStream;
022 import java.io.IOException;
023 import java.io.InputStream;
024 import java.io.OutputStream;
025 import java.io.OutputStreamWriter;
026 import java.io.PrintWriter;
027 import java.io.FileWriter;
028 import java.io.Writer;
029 import java.net.URI;
030 import java.util.Collection;
031 import java.util.Collections;
032 import java.util.Iterator;
033 import java.util.LinkedList;
034 import java.util.Arrays;
035 import java.util.jar.JarOutputStream;
036 import java.util.jar.Manifest;
037 import java.util.zip.ZipEntry;
038
039 import org.apache.geronimo.kernel.config.ConfigurationData;
040 import org.apache.geronimo.kernel.config.ConfigurationUtil;
041
042 /**
043 * @version $Rev: 410723 $ $Date: 2006-05-31 20:16:46 -0700 (Wed, 31 May 2006) $
044 */
045 public final class ExecutableConfigurationUtil {
046 private static final String META_INF = "META-INF";
047 private static final String CONFIG_SER = "config.ser";
048 private static final String CONFIG_INFO = "config.info";
049 private static final String META_INF_STARTUP_JAR = META_INF + "/startup-jar";
050 private static final String META_INF_CONFIG_SER = META_INF + "/" + CONFIG_SER;
051 private static final String META_INF_CONFIG_SER_SHA1 = META_INF_CONFIG_SER + ".sha1";
052 private static final String META_INF_CONFIG_INFO = META_INF + "/" + CONFIG_INFO;
053
054 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});
055
056 private ExecutableConfigurationUtil() {
057 }
058
059 public static void createExecutableConfiguration(ConfigurationData configurationData, Manifest manifest, File destinationFile) throws IOException {
060 File configurationDir = configurationData.getConfigurationDir();
061
062 // ensure parent directories have been created
063 File parent = destinationFile.getParentFile();
064 if (parent != null && !parent.exists()) parent.mkdirs();
065
066 FileOutputStream fos = null;
067 JarOutputStream out = null;
068 try {
069 byte[] buffer = new byte[4096];
070
071 fos = new FileOutputStream(destinationFile, false);
072
073 if (manifest != null) {
074 out = new JarOutputStream(fos, manifest);
075
076 // add the startup file which allows us to locate the startup directory
077 out.putNextEntry(new ZipEntry(META_INF_STARTUP_JAR));
078 // intentionally empty ZipEntry
079 out.closeEntry();
080 } else {
081 out = new JarOutputStream(fos);
082 }
083
084 // write the configurationData
085 ExecutableConfigurationUtil.writeConfiguration(configurationData, out);
086
087 URI baseURI = configurationDir.getAbsoluteFile().toURI();
088 Collection files = listRecursiveFiles(configurationDir);
089 for (Iterator iterator = files.iterator(); iterator.hasNext();) {
090 File file = (File) iterator.next();
091 String relativePath = baseURI.relativize(file.toURI()).getPath();
092 if (!EXCLUDED.contains(relativePath)) {
093 InputStream in = new FileInputStream(file);
094 try {
095 out.putNextEntry(new ZipEntry(relativePath));
096 try {
097 int count;
098 while ((count = in.read(buffer)) > 0) {
099 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 }