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 }