| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.openjpa.lib.util; |
| |
| import java.io.BufferedInputStream; |
| import java.io.BufferedOutputStream; |
| import java.io.BufferedWriter; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.io.OutputStreamWriter; |
| import java.io.PrintWriter; |
| import java.io.Writer; |
| import java.net.URL; |
| import java.net.URLDecoder; |
| import java.security.AccessController; |
| import java.security.PrivilegedActionException; |
| |
| /** |
| * Utility operations on files. |
| * |
| * @author Abe White |
| */ |
| public class Files { |
| |
| /** |
| * Backup the given file to a new file called <file-name>~. If |
| * the file does not exist or a backup could not be created, returns null. |
| */ |
| public static File backup(File file, boolean copy) { |
| if (file == null || !AccessController.doPrivileged( |
| J2DoPrivHelper.existsAction(file))) |
| return null; |
| |
| // create new file object copy so we don't modify the original |
| String aPath = AccessController.doPrivileged( |
| J2DoPrivHelper.getAbsolutePathAction(file)); |
| File clone = new File(aPath); |
| File bk = new File(aPath + "~"); |
| if (!AccessController.doPrivileged( |
| J2DoPrivHelper.renameToAction(clone, bk))) |
| return null; |
| if (copy) { |
| try { |
| copy(bk, file); |
| } catch (IOException ioe) { |
| throw new RuntimeException(ioe); |
| } |
| } |
| return bk; |
| } |
| |
| /** |
| * Revert the given backup file to the original location. If the given |
| * file's name does not end in '~', the '~' is appended before proceeding. |
| * If the backup file does not exist or could not be reverted, returns null. |
| */ |
| public static File revert(File backup, boolean copy) { |
| if (backup == null) |
| return null; |
| if (!backup.getName().endsWith("~")) |
| backup = new File(backup.getPath() + "~"); |
| if (!AccessController.doPrivileged( |
| J2DoPrivHelper.existsAction(backup))) |
| return null; |
| |
| // create new file object copy so we don't modify the original |
| String path = AccessController.doPrivileged( |
| J2DoPrivHelper.getAbsolutePathAction(backup)); |
| File clone = new File(path); |
| File orig = new File(path.substring(0, path.length() - 1)); |
| if (!AccessController.doPrivileged( |
| J2DoPrivHelper.renameToAction(clone, orig))) |
| return null; |
| if (copy) { |
| try { |
| copy(orig, backup); |
| } catch (IOException ioe) { |
| throw new RuntimeException(ioe); |
| } |
| } |
| return orig; |
| } |
| |
| /** |
| * Return the source file for the given class, or null if the |
| * source is not in the CLASSPATH. |
| */ |
| public static File getSourceFile(Class cls) { |
| return getClassFile(cls, ".java"); |
| } |
| |
| /** |
| * Return the class file of the given class, or null if the |
| * class is in a jar. |
| */ |
| public static File getClassFile(Class cls) { |
| return getClassFile(cls, ".class"); |
| } |
| |
| /** |
| * Return the file for the class resource with the given extension. |
| */ |
| private static File getClassFile(Class cls, String ext) { |
| String name = ClassUtil.getClassName(cls); |
| |
| // if it's an inner class, use the parent class name |
| int innerIdx = name.indexOf('$'); |
| if (innerIdx != -1) |
| name = name.substring(0, innerIdx); |
| |
| URL rsrc = AccessController.doPrivileged( |
| J2DoPrivHelper.getResourceAction(cls, name + ext)); |
| if (rsrc != null && rsrc.getProtocol().equals("file")) |
| return new File(URLDecoder.decode(rsrc.getFile())); |
| return null; |
| } |
| |
| /** |
| * Return the file for the given package. If the given base directory |
| * matches the given package structure, it will be used as-is. If not, |
| * the package structure will be added beneath the base directory. If |
| * the base directory is null, the current working directory will be |
| * used as the base. |
| */ |
| public static File getPackageFile(File base, String pkg, boolean mkdirs) { |
| if (base == null) |
| base = new File(AccessController.doPrivileged( |
| J2DoPrivHelper.getPropertyAction("user.dir"))); |
| if (StringUtil.isEmpty(pkg)) { |
| if (mkdirs && !AccessController.doPrivileged( |
| J2DoPrivHelper.existsAction(base))) |
| AccessController.doPrivileged( |
| J2DoPrivHelper.mkdirsAction(base)); |
| return base; |
| } |
| |
| pkg = pkg.replace('.', File.separatorChar); |
| File file = null; |
| try { |
| if ((AccessController.doPrivileged( |
| J2DoPrivHelper.getCanonicalPathAction(base))).endsWith(pkg)) |
| file = base; |
| else |
| file = new File(base, pkg); |
| } catch (PrivilegedActionException pae) { |
| throw new RuntimeException( |
| (IOException) pae.getException()); |
| } catch (IOException ioe) { |
| throw new RuntimeException(ioe); |
| } |
| |
| if (mkdirs && !AccessController.doPrivileged( |
| J2DoPrivHelper.existsAction(file))) |
| AccessController.doPrivileged(J2DoPrivHelper.mkdirsAction(file)); |
| return file; |
| } |
| |
| /** |
| * Check the given string for a matching file. The string is first |
| * tested to see if it is an existing file path. If it does not |
| * represent an existing file, it is checked as a resource name of a |
| * file. If no resource exists, then it is interpreted as a path |
| * to a file that does not exist yet. |
| * |
| * @param name the file path or resource name |
| * @param loader a class loader to use in resource lookup, or null |
| * to use the thread's context loader |
| */ |
| public static File getFile(String name, ClassLoader loader) { |
| if (name == null) |
| return null; |
| |
| File file = new File(name); |
| if (AccessController.doPrivileged( |
| J2DoPrivHelper.existsAction(file))) |
| return file; |
| |
| if (loader == null) |
| loader = AccessController.doPrivileged( |
| J2DoPrivHelper.getContextClassLoaderAction()); |
| URL url = AccessController.doPrivileged( |
| J2DoPrivHelper.getResourceAction(loader, name)); |
| if (url != null) { |
| String urlFile = url.getFile(); |
| if (urlFile != null) { |
| File rsrc = new File(URLDecoder.decode(urlFile)); |
| if (AccessController.doPrivileged( |
| J2DoPrivHelper.existsAction(rsrc))) |
| return rsrc; |
| } |
| } |
| |
| // go back to original non-existant file path |
| return file; |
| } |
| |
| /** |
| * Return a writer to the stream(stdout or stderr) or file named by the |
| * given string. |
| * |
| * @see #getFile |
| */ |
| public static Writer getWriter(String file, ClassLoader loader) |
| throws IOException { |
| if (file == null) |
| return null; |
| if ("stdout".equals(file)) |
| return new PrintWriter(System.out); |
| if ("stderr".equals(file)) |
| return new PrintWriter(System.err); |
| try { |
| return new FileWriter(getFile(file, loader)); |
| } catch (IOException ioe) { |
| throw new RuntimeException(ioe); |
| } |
| } |
| |
| /** |
| * Return a writer to the stream(stdout or stderr) or file named by the |
| * given string set to the provided charset encoding. |
| * |
| * @see #getOutputStream |
| */ |
| public static Writer getWriter(String file, ClassLoader loader, String enc) |
| throws IOException { |
| if (file == null) |
| return null; |
| if (enc == null) { |
| // call the non-encoded version of the method |
| return getWriter(file, loader); |
| } |
| |
| try { |
| if ("stdout".equals(file)) |
| return new PrintWriter(new OutputStreamWriter(System.out, enc)); |
| else if ("stderr".equals(file)) |
| return new PrintWriter(new OutputStreamWriter(System.err, enc)); |
| else |
| return new BufferedWriter(new OutputStreamWriter(getOutputStream(file, loader), enc)); |
| } catch (IOException ioe) { |
| throw new RuntimeException(ioe); |
| } |
| } |
| |
| /** |
| * Return an output stream to the stream(stdout or stderr) or file named |
| * by the given string. |
| * |
| * @see #getFile |
| */ |
| public static OutputStream getOutputStream(String file, |
| ClassLoader loader) { |
| if (file == null) |
| return null; |
| if ("stdout".equals(file)) |
| return System.out; |
| if ("stderr".equals(file)) |
| return System.err; |
| try { |
| return AccessController.doPrivileged( |
| J2DoPrivHelper.newFileOutputStreamAction( |
| getFile(file, loader))); |
| } catch (PrivilegedActionException pae) { |
| throw new RuntimeException(pae.getException()); |
| } catch (IOException ioe) { |
| throw new RuntimeException(ioe); |
| } |
| } |
| |
| /** |
| * Copy a file. Return false if <code>from</code> does not exist. |
| */ |
| public static boolean copy(File from, File to) throws IOException { |
| if (from == null || to == null || |
| !AccessController.doPrivileged( |
| J2DoPrivHelper.existsAction(from))) |
| return false; |
| |
| FileInputStream in = null; |
| FileOutputStream out = null; |
| try { |
| in = AccessController.doPrivileged( |
| J2DoPrivHelper.newFileInputStreamAction(from)); |
| BufferedInputStream inbuf = new BufferedInputStream(in); |
| out = AccessController.doPrivileged( |
| J2DoPrivHelper.newFileOutputStreamAction(to)); |
| BufferedOutputStream outbuf = new BufferedOutputStream(out); |
| for (int b; (b = inbuf.read()) != -1; outbuf.write(b)) ; |
| outbuf.flush(); |
| return true; |
| } catch (PrivilegedActionException pae) { |
| throw (FileNotFoundException) pae.getException(); |
| } finally { |
| if (in != null) |
| try { |
| in.close(); |
| } catch (Exception e) { |
| } |
| if (out != null) |
| try { |
| out.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| } |