This project has retired. For details please refer to its
Attic page.
001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 package org.apache.oozie.util;
019
020 import java.io.IOException;
021 import java.io.InputStream;
022 import java.io.InputStreamReader;
023 import java.io.OutputStream;
024 import java.io.Reader;
025 import java.io.Writer;
026 import java.io.File;
027 import java.io.FileInputStream;
028 import java.io.FileOutputStream;
029 import java.util.zip.ZipOutputStream;
030 import java.util.zip.ZipEntry;
031 import java.util.jar.JarOutputStream;
032 import java.util.jar.Manifest;
033
034 /**
035 * IO Utility methods.
036 */
037 public abstract class IOUtils {
038
039 /**
040 * Delete recursively a local directory.
041 *
042 * @param file directory to delete.
043 * @throws IOException thrown if the directory could not be deleted.
044 */
045 public static void delete(File file) throws IOException {
046 ParamChecker.notNull(file, "file");
047 if (file.getAbsolutePath().length() < 5) {
048 throw new RuntimeException(XLog.format("Path[{0}] is too short, not deleting", file.getAbsolutePath()));
049 }
050 if (file.exists()) {
051 if (file.isDirectory()) {
052 File[] children = file.listFiles();
053 if (children != null) {
054 for (File child : children) {
055 delete(child);
056 }
057 }
058 }
059 if (!file.delete()) {
060 throw new RuntimeException(XLog.format("Could not delete path[{0}]", file.getAbsolutePath()));
061 }
062 }
063 }
064
065 /**
066 * Return a reader as string. <p/>
067 *
068 * @param reader reader to read into a string.
069 * @param maxLen max content length allowed, if -1 there is no limit.
070 * @return the reader content.
071 * @throws IOException thrown if the resource could not be read.
072 */
073 public static String getReaderAsString(Reader reader, int maxLen) throws IOException {
074 ParamChecker.notNull(reader, "reader");
075 StringBuffer sb = new StringBuffer();
076 char[] buffer = new char[2048];
077 int read;
078 int count = 0;
079 while ((read = reader.read(buffer)) > -1) {
080 count += read;
081 if (maxLen > -1 && count > maxLen) {
082 throw new IllegalArgumentException(XLog.format("stream exceeds limit [{0}]", maxLen));
083 }
084 sb.append(buffer, 0, read);
085 }
086 reader.close();
087 return sb.toString();
088 }
089
090
091 /**
092 * Return a classpath resource as a stream. <p/>
093 *
094 * @param path classpath for the resource.
095 * @param maxLen max content length allowed.
096 * @return the stream for the resource.
097 * @throws IOException thrown if the resource could not be read.
098 */
099 public static InputStream getResourceAsStream(String path, int maxLen) throws IOException {
100 ParamChecker.notEmpty(path, "path");
101 InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
102 if (is == null) {
103 throw new IllegalArgumentException(XLog.format("resource [{0}] not found", path));
104 }
105 return is;
106 }
107
108 /**
109 * Return a classpath resource as a reader. <p/> It is assumed that the resource is a text resource.
110 *
111 * @param path classpath for the resource.
112 * @param maxLen max content length allowed.
113 * @return the reader for the resource.
114 * @throws IOException thrown if the resource could not be read.
115 */
116 public static Reader getResourceAsReader(String path, int maxLen) throws IOException {
117 return new InputStreamReader(getResourceAsStream(path, maxLen));
118 }
119
120 /**
121 * Return a classpath resource as string. <p/> It is assumed that the resource is a text resource.
122 *
123 * @param path classpath for the resource.
124 * @param maxLen max content length allowed.
125 * @return the resource content.
126 * @throws IOException thrown if the resource could not be read.
127 */
128 public static String getResourceAsString(String path, int maxLen) throws IOException {
129 ParamChecker.notEmpty(path, "path");
130 InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
131 if (is == null) {
132 throw new IllegalArgumentException(XLog.format("resource [{0}] not found", path));
133 }
134 Reader reader = new InputStreamReader(is);
135 return getReaderAsString(reader, maxLen);
136 }
137
138 /**
139 * Copies an inputstream into an output stream.
140 *
141 * @param is inputstream to copy from.
142 * @param os outputstream to copy to.
143 * @throws IOException thrown if the copy failed.
144 */
145 public static void copyStream(InputStream is, OutputStream os) throws IOException {
146 ParamChecker.notNull(is, "is");
147 ParamChecker.notNull(os, "os");
148 byte[] buffer = new byte[4096];
149 int read;
150 while ((read = is.read(buffer)) > -1) {
151 os.write(buffer, 0, read);
152 }
153 os.close();
154 is.close();
155 }
156
157 /**
158 * Copies an char input stream into an char output stream.
159 *
160 * @param reader reader to copy from.
161 * @param writer writer to copy to.
162 * @throws IOException thrown if the copy failed.
163 */
164 public static void copyCharStream(Reader reader, Writer writer) throws IOException {
165 ParamChecker.notNull(reader, "reader");
166 ParamChecker.notNull(writer, "writer");
167 char[] buffer = new char[4096];
168 int read;
169 while ((read = reader.read(buffer)) > -1) {
170 writer.write(buffer, 0, read);
171 }
172 writer.close();
173 reader.close();
174 }
175
176 /**
177 * Zips a local directory, recursively, into a ZIP stream.
178 *
179 * @param dir directory to ZIP.
180 * @param relativePath basePath in the ZIP for the files, normally "/".
181 * @param zos the ZIP output stream to ZIP the directory.
182 * @throws java.io.IOException thrown if the directory could not be zipped.
183 */
184 public static void zipDir(File dir, String relativePath, ZipOutputStream zos) throws IOException {
185 zipDir(dir, relativePath, zos, true);
186 zos.close();
187 }
188
189 private static void zipDir(File dir, String relativePath, ZipOutputStream zos, boolean start) throws IOException {
190 String[] dirList = dir.list();
191 for (String aDirList : dirList) {
192 File f = new File(dir, aDirList);
193 if (!f.isHidden()) {
194 if (f.isDirectory()) {
195 if (!start) {
196 ZipEntry dirEntry = new ZipEntry(relativePath + f.getName() + "/");
197 zos.putNextEntry(dirEntry);
198 zos.closeEntry();
199 }
200 String filePath = f.getPath();
201 File file = new File(filePath);
202 zipDir(file, relativePath + f.getName() + "/", zos, false);
203 }
204 else {
205 ZipEntry anEntry = new ZipEntry(relativePath + f.getName());
206 zos.putNextEntry(anEntry);
207 InputStream is = new FileInputStream(f);
208 byte[] arr = new byte[4096];
209 int read = is.read(arr);
210 while (read > -1) {
211 zos.write(arr, 0, read);
212 read = is.read(arr);
213 }
214 is.close();
215 zos.closeEntry();
216 }
217 }
218 }
219 }
220
221 /**
222 * Creates a JAR file with the specified classes.
223 *
224 * @param baseDir local directory to create the JAR file, the staging 'classes' directory is created in there.
225 * @param jarName JAR file name, including extesion.
226 * @param classes classes to add to the JAR.
227 * @return an absolute File to the created JAR file.
228 * @throws java.io.IOException thrown if the JAR file could not be created.
229 */
230 public static File createJar(File baseDir, String jarName, Class... classes) throws IOException {
231 File classesDir = new File(baseDir, "classes");
232 for (Class clazz : classes) {
233 String classPath = clazz.getName().replace(".", "/") + ".class";
234 String classFileName = classPath;
235 if (classPath.lastIndexOf("/") > -1) {
236 classFileName = classPath.substring(classPath.lastIndexOf("/") + 1);
237 }
238 String packagePath = new File(classPath).getParent();
239 File dir = new File(classesDir, packagePath);
240 if (!dir.exists()) {
241 if (!dir.mkdirs()) {
242 throw new IOException(XLog.format("could not create dir [{0}]", dir));
243 }
244 }
245 InputStream is = getResourceAsStream(classPath, -1);
246 OutputStream os = new FileOutputStream(new File(dir, classFileName));
247 copyStream(is, os);
248 }
249 File jar = new File(baseDir, jarName);
250 File jarDir = jar.getParentFile();
251 if (!jarDir.exists()) {
252 if (!jarDir.mkdirs()) {
253 throw new IOException(XLog.format("could not create dir [{0}]", jarDir));
254 }
255 }
256 JarOutputStream zos = new JarOutputStream(new FileOutputStream(jar), new Manifest());
257 zipDir(classesDir, "", zos);
258 return jar;
259 }
260 }