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