1 /*
2 * Redistribution and use of this software and associated documentation
3 * ("Software"), with or without modification, are permitted provided
4 * that the following conditions are met:
5 *
6 * 1. Redistributions of source code must retain copyright
7 * statements and notices. Redistributions must also contain a
8 * copy of this document.
9 *
10 * 2. Redistributions in binary form must reproduce the
11 * above copyright notice, this list of conditions and the
12 * following disclaimer in the documentation and/or other
13 * materials provided with the distribution.
14 *
15 * 3. The name "Exolab" must not be used to endorse or promote
16 * products derived from this Software without prior written
17 * permission of Intalio, Inc. For written permission,
18 * please contact info@exolab.org.
19 *
20 * 4. Products derived from this Software may not be called "Exolab"
21 * nor may "Exolab" appear in their names without prior written
22 * permission of Intalio, Inc. Exolab is a registered
23 * trademark of Intalio, Inc.
24 *
25 * 5. Due credit should be given to the Exolab Project
26 * (http://www.exolab.org/).
27 *
28 * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32 * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 * OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Copyright 2002 (C) Intalio, Inc. All Rights Reserved.
42 *
43 * $Id: FileServices.java 6787 2007-01-29 06:00:49Z ekuns $
44 */
45 package org.castor.xmlctf.util;
46
47 import java.io.File;
48 import java.io.FileInputStream;
49 import java.io.FileOutputStream;
50 import java.io.IOException;
51 import java.io.InputStream;
52 import java.io.OutputStream;
53 import java.util.Enumeration;
54 import java.util.jar.JarFile;
55 import java.util.zip.ZipEntry;
56
57 /**
58 * This class is a set of tools for manipulating files needed by the CTF.
59 *
60 * @author <a href="mailto:blandin@intalio.com">Arnaud Blandin</a>
61 * @version $Revision: 6787 $ $Date: 2005-03-05 06:42:06 -0700 (Sat, 05 Mar 2005) $
62 */
63 public final class FileServices {
64
65 /** The string for a CVS subdirectory. */
66 public static final String CVS = "CVS";
67 /** The string for a Subversion subdirectory. */
68 public static final String SVN = ".svn";
69 /** The string for an extension for a XSD file. */
70 public static final String XSD = ".xsd";
71 /** The string for an extension for a XML file. */
72 public static final String XML = ".xml";
73 /** The string for an extension for a Java file. */
74 public static final String JAVA = ".java";
75 /** The string for an extension for a JAR file. */
76 public static final String JAR = ".jar";
77
78 /** Buffer size used for copying files. */
79 private static final int BUF_SIZE = 16 * 1024;
80
81 /**
82 * No-arg constructor. Private as we're a utility class.
83 */
84 private FileServices() {
85 // Nothing to do
86 }
87
88 /**
89 * Copy all the needed documents (java, xsd, xml file) of given file (jar or
90 * directory) to a specified directory.
91 *
92 * @param file the file that contains the entries to copy
93 * @param root the destination directory to copy files to
94 * @throws IOException if an error occurs while copying files
95 */
96 public static void copySupportFiles(final File file, final File root) throws IOException {
97 if (file == null) {
98 throw new IllegalArgumentException("The Entry file is null");
99 }
100 if (root == null) {
101 throw new IllegalArgumentException("The destination directory is null");
102 }
103
104 if (file.isDirectory()) {
105 copySupportFilesForDirectory(file, root);
106 } else if (file.getName().endsWith(JAR)) {
107 copySupportFilesForJarFile(file, root);
108 } else {
109 //ignore other file type
110 }
111 }
112
113 /**
114 * Unzips support files out of the JAR to our output directory. See
115 * {@link #isSupportFile(String)} for the definition of support file. This
116 * method does not totally unzip the JAR file. It only extracts certain
117 * important files out of the JAR.
118 *
119 * @param file the file that contains the entries to copy
120 * @param root the destination directory to copy files to
121 * @throws IOException if an error occurs while copying files
122 */
123 private static void copySupportFilesForJarFile(final File file, final File root)
124 throws IOException {
125 JarFile jar = new JarFile(file);
126 for (Enumeration e = jar.entries(); e.hasMoreElements(); ) {
127 ZipEntry entry = (ZipEntry) e.nextElement();
128 if (isSupportFile(entry.getName())) {
129 InputStream src = jar.getInputStream(entry);
130 File out = new File(root, entry.getName());
131 out.getParentFile().mkdirs();
132 copy(src, new FileOutputStream(out));
133 src.close();
134 }
135 }
136 }
137
138 /**
139 * Copies support files from one directory to our output directory,
140 * recursing into other directories. See {@link #isSupportFile(String)} for
141 * the definition of support file.
142 *
143 * @param file the file that contains the entries to copy
144 * @param root the destination directory to copy files to
145 * @throws IOException if an error occurs while copying files
146 */
147 private static void copySupportFilesForDirectory(final File file, final File root)
148 throws IOException {
149 File[] entries = file.listFiles();
150 for (int i = 0; i < entries.length; i++) {
151 File tempEntry = entries[i];
152 if (isSupportFile(tempEntry.getName())) {
153 File out = new File(root, tempEntry.getName());
154 out.getParentFile().mkdir();
155 FileOutputStream dest = new FileOutputStream(out);
156
157 InputStream src = new FileInputStream(tempEntry);
158 copy(src, dest);
159 src.close();
160 dest.close();
161 } else if (tempEntry.isDirectory()) {
162 File out = new File(root, tempEntry.getName());
163 out.mkdir();
164 copySupportFiles(tempEntry, out);
165 }
166 }
167 }
168
169 /**
170 * Copies an InputStream into a OutputStream.
171 *
172 * @param src Source input stream
173 * @param dest Destination output stream
174 * @throws IOException if an error occurs while copying files
175 */
176 private static void copy(final InputStream src, final OutputStream dest) throws IOException {
177 byte[] buf = new byte[BUF_SIZE];
178 int read;
179 while (true) {
180 read = src.read(buf, 0, BUF_SIZE);
181 if (read == -1) {
182 break;
183 }
184 dest.write(buf, 0, read);
185 }
186 }
187
188 /**
189 * Return true if the file is a support file for the test. A support file is
190 * a schema or a java file.
191 *
192 * @param name File name to check to see if it represents a support file
193 * @return true if the file is a support file for the test.
194 */
195 private static boolean isSupportFile(final String name) {
196 return name.endsWith(XSD) || name.endsWith(JAVA) || name.endsWith(XML);
197 }
198
199 /**
200 * Return true if the file provided is a special source control management
201 * directory that we want to ignore.
202 * @param name Name of a directory
203 * @return true if the file provided is an SCM directory
204 */
205 public static boolean isScmDirectory(final String name) {
206 return name.endsWith(FileServices.CVS) || name.equals(FileServices.SVN);
207 }
208
209 }