Package org.xmlBlaster.util

Source Code of org.xmlBlaster.util.FileLocator

/*------------------------------------------------------------------------------
Name:      FileLocator.java
Project:   xmlBlaster.org
Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
------------------------------------------------------------------------------*/

package org.xmlBlaster.util;

import org.xmlBlaster.util.Global;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.Vector;
import org.xmlBlaster.util.def.ErrorCode;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.net.MalformedURLException;
import java.net.URL;


public class FileLocator
{
   private final static String ME = "FileLocator";
   private Global glob;
   private static Logger log = Logger.getLogger(FileLocator.class.getName());

   /**
    * Constructor. It does nothing but initializing the log and assigning the global.
    */
   public FileLocator(Global glob) {
      this.glob = glob;

   }

   /**
    * Searches in the given path for the specified filename. If the file has not been found in the given
    * path, then null is returned. Otherwise the complete (absolute) path of the file is returned.
    *
    * @param path the path on which to search for the given file.
    * @param filename the name of the file to search. NOTE: if it is an absolute filename, then the path
    *        is ignored and a warning is written to the log.
    * @throws XmlBlasterException with error code resource.configuration if either the file has been found
    *         but it can not be read, or if it is a directory. Note that if there are several files in the
    *         given path and the first one found is either read protected or is a directory, then the second
    *         is taken and no exception is thrown.
    */
   public final String findFile(String[] path, String filename) throws XmlBlasterException {
      File file = new File(filename);
      if (file.isAbsolute()) {
         log.warning("the filename '" + filename + "' is absolute, I will ignore the given search path '" + path + "'");
         if (file.exists()) {
            if (file.isDirectory()) {
               throw new XmlBlasterException(this.glob, ErrorCode.RESOURCE_CONFIGURATION, ME + ".findFile", "the given name '" + file.getAbsolutePath() + "' is a directory");
            }
            if (!file.canRead()) {
               throw new XmlBlasterException(this.glob, ErrorCode.RESOURCE_CONFIGURATION, ME + ".findFile", "don't have the rights to read the file '" + file.getAbsolutePath() + "'");
            }
            return file.getAbsolutePath();
         }
      }

      XmlBlasterException ex = null;
      for (int i=0; i< path.length; i++) {
         File tmp = new File(path[i], filename);
         if (tmp.exists()) {
            if (tmp.isDirectory()) {
               ex = new XmlBlasterException(this.glob, ErrorCode.RESOURCE_CONFIGURATION, ME + ".findFile", "the given name '" + tmp.getAbsolutePath() + "' is a directory");
            }
            else {
               if (!tmp.canRead()) {
                  ex = new XmlBlasterException(this.glob, ErrorCode.RESOURCE_CONFIGURATION, ME + ".findFile", "don't have the rights to read the file '" + tmp.getAbsolutePath() + "'");
               }
               else return tmp.getAbsolutePath();
            }
         }
      }
      if (ex != null) throw ex;
      return null;
   }

   /**
    * Parses the given Path into an array of String. If the input path was null, null is returned. If the
    * input path was empty null is returned. Otherwise all path are returned. If the separator is null,
    * null is returned.
    */
   public final String[] parsePath(String pathAsString, String separator) {
      if (pathAsString == null || separator == null) return null;
      if (pathAsString.trim().length() < 1) return null;

      StringTokenizer tokenizer = new StringTokenizer(pathAsString, separator);
      int size = tokenizer.countTokens();
      String[] ret = new String[size];
      for (int i=0; i < ret.length; i++) {
         ret[i] = tokenizer.nextToken();
      }
      return ret;
   }

   /**
    * finds the file in the given path. The separator for the path is given explicitly.
    */
    public final String findFile(String path, String separator, String filename)
       throws XmlBlasterException {
       String[] parsedPath = parsePath(path, separator);
       return findFile(parsedPath, filename);
    }

    /**
     * finds the file in the given path. The path separator is implicitly set to ':'.
     */
    public final String findFile(String path, String filename)
       throws XmlBlasterException {
       return findFile(path, ":", filename);
    }

    public final String[] createXmlBlasterSearchPath() {
       Vector vec = new Vector();
       vec.add(".");
       String projectHome = System.getProperty("PROJECT_HOME");
       if (projectHome != null && projectHome.length() > 0 ) vec.add(projectHome);
       String home = System.getProperty("user.home");
       if (home != null && home.length() > 0 ) vec.add(home);
       String javaExtDirs = System.getProperty("java.ext.dirs");
       if (javaExtDirs != null && javaExtDirs.length() > 0 ) vec.add(javaExtDirs);
       String javaHome = System.getProperty("java.home");
       if (javaHome != null && javaHome.length() > 0 vec.add(javaHome);

       String[] ret = (String[])vec.toArray(new String[vec.size()]);
       return ret;
    }


   /**
    * checks if the file exists in the given path (only one path).
    * @param path the path in which the file should reside. If it is null, then
    *        filename will be considered an absolute filename.
    * @param filename the name of the file to lookup
    * @return URL the URL for the given file or null if no file found.
    */
   private final URL findFileInSinglePath(String path, String filename) {
      if (log.isLoggable(Level.FINER)) log.finer("findFileInSinglePath with path='" +
         path + "' and filename='" + filename + "'");
      File file = null;
      if (path != null) file = new File(path, filename);
      else file = new File(filename);
      if (file.exists()) {
         if (file.isDirectory()) {
            log.warning("findFileInSinglePath: the given name '" + file.getAbsolutePath() + "' is not a file, it is a directory");
            return null;
         }
         if (!file.canRead()) {
            log.warning("findFileInSinglePath: don't have the rights to read the file '" + file.getAbsolutePath() + "'");
            return null;
         }
         try {
            return file.toURL();
         }
         catch (java.net.MalformedURLException ex) {
            log.warning("findFileInSinglePath: path='" + path + "', filename='" + filename + " exception: " + ex.getMessage());
            return null;
         }
      }
      return null;
   }

   public String read(URL url) throws XmlBlasterException {
      if (url == null)
         throw new XmlBlasterException(Global.instance(), ErrorCode.RESOURCE_CONFIGURATION, ME, "read() invoked with url==null");
      try {
         InputStreamReader reader = new InputStreamReader(url.openStream());
         BufferedReader br = new BufferedReader(reader);
         StringBuffer buf = new StringBuffer(2048);
         String line = "";
     
         while((line = br.readLine()) != null)
            buf.append(line).append("\n");
         return buf.toString();
      }
      catch (IOException e) {
         throw new XmlBlasterException(Global.instance(), ErrorCode.RESOURCE_CONFIGURATION, ME+": "+url.toString(), e.toString());
      }
   }


   /**
    * tries to find a file according to the xmlBlaster Strategy.
    * The strategy is:
    * <ul>
    *   <li>given value of the specified property</li>
    *   <li>Locations with schema like http://www.xmlBlaster.org/empty.html</li>
    *   <li>user.dir</li>
    *   <li>full name (complete with path)</li>
    *   <li>PROJECT_HOME global property</li>
    *   <li>user.home</li>
    *   <li>classpath</li>
    *   <li>java.ext.dirs</li>
    *   <li>java.home</li>
    * </ul>
    * @paran propertyName The key to look into Global, can be null. For example
    *        <tt>URL url = locator.findFileInXmlBlasterSearchPath("pluginsFile", "/tmp/xmlBlasterPlugins.xml");
    *        if (url != null) String file = url.getFile();</tt>
    *        looks for the key "pluginsFile" in global scope, if found the file of the keys value is chosen, else
    *        the above lookup applies.
    *  @param filename
    *  @return URL the URLfrom which to read the content or null if
    *          the file/resource has not been found. Note that we return the
    *          url instead of the filename since it could be a resource and
    *          therefore it could not be opened as a normal file.
    * @see <a href="http://www.xmlblaster.org/xmlBlaster/doc/requirements/util.property.html">The util.property requirement</a>
    */
   public final URL findFileInXmlBlasterSearchPath(String propertyName, String filename) {
      String path = null;
      URL ret = null;

      String urlStr = filename;
      if (propertyName != null) {
         path = this.glob.getProperty().get(propertyName, (String)null);
         if (path != null) {
            if (log.isLoggable(Level.FINE)) log.fine("findFileInXmlBlasterSearchPath: the path: '" + path + "' and the filename to search: '" + filename + "'");
   //         ret = findFileInSinglePath(path, filename);
            ret = findFileInSinglePath(null, path);
            if (ret != null) return ret;
            urlStr = path;
         }
      }
     
      if (urlStr != null) {
         int schema = urlStr.indexOf("://"); // http:// or file:// or ftp://
         if (schema != -1 || urlStr.startsWith("file:")) {
            try {
               return new URL(urlStr);
            } catch (MalformedURLException e) {
               log.warning("The given filename is an invalid url: " + toString());
            }
            if (urlStr.startsWith("file:") && urlStr.length() < 6 ||
                 urlStr.length() < schema+3)
               return null;
           
            filename = (schema != -1) ? urlStr.substring(schema+3) : urlStr.substring(5);
         }
      }
     
      if (filename == null) return null;

      // user.dir
      path = System.getProperty("user.dir", ".");
      ret = findFileInSinglePath(path, filename);
      if (ret != null) return ret;

      // full name (complete with path)
      ret = findFileInSinglePath(null, filename);
      if (ret != null) return ret;

      // PROJECT_HOME global property
      path = this.glob.getProperty().get("PROJECT_HOME", (String)null);
      if (path != null) {
         ret = findFileInSinglePath(path, filename);
         if (ret != null) return ret;
      }

      // user.home
      path = System.getProperty("user.home", (String)null);
      if (path != null) {
         ret = findFileInSinglePath(path, filename);
         if (ret != null) return ret;
      }

      // classpath
      try {
         URL url = this.glob.getClassLoaderFactory().getXmlBlasterClassLoader().getResource(filename);
         if (url != null) return url;
      }
      catch (XmlBlasterException ex) {
         log.warning("findFileInXmlBlasterSearchPath: " + ex.getMessage());
      }

      // java.ext.dirs
      path = System.getProperty("java.ext.dirs", (String)null);
      if (path != null) {
         ret = findFileInSinglePath(path, filename);
         if (ret != null) return ret;
      }

      // java.home
      path = System.getProperty("java.home", (String)null);
      if (path != null) {
         return findFileInSinglePath(path, filename);
      }
      return null;
    }


   /**
    * Read a file into <code>byte[]</code>.
    * <br><b>Example:</b><br>
    *    <code>byte[] data=FileLocator.readFile("/tmp", "hello.txt");</code>
    *
    * @param      parent Path to the file, can be null
    * @param      fileName  Name of file
    * @return     data from the file
    * @exception  XmlBlasterException
    *             if the file is not readable or any error occurred while reading the file.
    */
   public static final byte[] readFile(String parent, String fileName)
      throws XmlBlasterException
   {
      File f = (parent==null) ? new File(fileName) : new File(parent, fileName);
      return readFile(f);
   }
  
   public static final byte[] readFile(File f)
      throws XmlBlasterException
   {
      byte[] fileBlob = null;
      String fileName = f.getAbsolutePath();
      if (!f.exists()) {
         throw new XmlBlasterException(Global.instance(), ErrorCode.RESOURCE_CONFIGURATION, ME, "Sorry, can't find file " + fileName);
      }
      if (!f.isFile()) {
         throw new XmlBlasterException(Global.instance(), ErrorCode.RESOURCE_CONFIGURATION, ME, "Sorry, doesn't seem to be a file " + fileName);
      }
      if (!f.canRead()) {
         throw new XmlBlasterException(Global.instance(), ErrorCode.RESOURCE_CONFIGURATION, ME, "Sorry, no access permissions for file " + fileName);
      }
      FileInputStream from = null;
      try {
         from = new FileInputStream(f);
         fileBlob = new byte[ (int) f.length()];
         int bytes_read = from.read(fileBlob);
         if (bytes_read != f.length()) {
            throw new XmlBlasterException(Global.instance(), ErrorCode.RESOURCE_CONFIGURATION, ME, "File read error in " + fileName + ": Excpected " + f.length() + " bytes, but only found " + bytes_read + "bytes");
         }
      }
      catch (FileNotFoundException e) {
         throw new XmlBlasterException(Global.instance(), ErrorCode.RESOURCE_CONFIGURATION, ME, e.toString());
      }
      catch (IOException e2) {
         throw new XmlBlasterException(Global.instance(), ErrorCode.RESOURCE_CONFIGURATION, ME, e2.toString());
      }
      finally {
         if (from != null)
            try {
            from.close();
         }
         catch (IOException e) {
            ;
         }
      }
      if (f.length() != fileBlob.length) {
         throw new XmlBlasterException(Global.instance(), ErrorCode.RESOURCE_CONFIGURATION, ME, "Read file " + fileName + " with size=" + f.length() + " but only got " + fileBlob.length + " bytes");
      }
      return fileBlob;
   }

   /**
    * Write data from <code>byte[]</code> into a file.
    *
    * @param      parent the path, can be null
    * @param      child the name
    * @param      arr data
    */
   public static final void writeFile(String parent, String child, byte[] arr)
      throws XmlBlasterException
   {
      try {
         File to_file = (parent==null) ? new File(child) : new File(parent, child);
         FileOutputStream to = new FileOutputStream(to_file);
         to.write(arr);
         to.close();
      }
      catch (Exception e) {
         throw new XmlBlasterException(Global.instance(), ErrorCode.RESOURCE_CONFIGURATION, ME, "Can't write file " + child + ":" + e.toString());
      }
   }

   /**
   * Write data from <code>StringBuffer</code> into a file.
   * @param outName  name of file including path
   * @param str      data
   */
   public static final void writeFile(String name, String str) throws XmlBlasterException {
      writeFile(null, name, str.getBytes());
   }

   /**
    * Write data from <code>StringBuffer</code> into a file.
    * @param outName  name of file including path
    * @param str      some binary data
    */
    public static final void writeFile(String name, byte[] arr) throws XmlBlasterException {
       writeFile(null, name, arr);
    }

   /**
   * Append data from into a file.
   * @param outName  name of file including path
   * @param str      Text
   */
   public static final void appendToFile(String outName, String str) throws XmlBlasterException {
      try {
         boolean append = true;
         FileOutputStream to = new FileOutputStream(outName, append);
         to.write(str.getBytes());
         to.close();
      }
      catch (Exception e) {
         throw new XmlBlasterException(Global.instance(), ErrorCode.RESOURCE, ME, "Can't write file " + e.toString());
      }
   }

   /**
   * Read a file into <code>String</code>.
   * @param fileName Complete name of file
   * @return ASCII data from the file<br />
   *         null on error
   */
   public static final String readAsciiFile(String fileName) throws XmlBlasterException {
      return readAsciiFile(null, fileName);
   }


   /**
   * Read a file into <code>String</code>.
   * <br><b>Example:</b><br>
   *    <code>String data=FileUtil.readAsciiFile("/tmp/hello");</code>
   * @param parent Path to the file
   * @param fileName name of file
   * @return ASCII data from the file<br />
   *         null on error
   */
   public static final String readAsciiFile(String parent, String child) throws XmlBlasterException {
      byte[] bb = readFile(parent, child);
      if (bb == null)
         return null;
      return new String(bb);
   }


   /**
    * Read a file into <code>byte[]</code>.
    *
    * @param      fileName
    *             Complete name of file
    * @return     data from the file
    * @exception  JUtilsException
    *             if the file is not readable or any error occured while reading the file.
    */
   public static final byte[] readFile(String fileName)
      throws XmlBlasterException
   {
      return readFile(null, fileName);
   }

   public static final void deleteFile(String parent, String fileName) {
      File f = new File(parent, fileName);
      if (f.exists())
         f.delete();
   }

    /**
     * Concatenate a filename to a path (DOS and UNIX, checks for separator).
     * @param path for example "/tmp"
     * @param name for example "hello.txt"
     * @return "/tmp/hello.txt"
     */
   public static String concatPath(String path, String name) {
      if (path == null)
         return name;
      if (name == null)
         return path;
      if (path.endsWith(File.separator) && name.startsWith(File.separator))
         return path + name.substring(1);
      if (path.endsWith(File.separator))
         return path + name;
      if (name.startsWith(File.separator))
         return path + name;
      return path + File.separator + name;
   }

   /**
   * Return the file name extension.
   * @param fileName for example "/tmp/hello.txt"
   * @return extension of the filename "txt"
   */
   public static String getExtension(String fileName) {
      if (fileName == null)
         return null;
      int dot = fileName.lastIndexOf(".");
      if (dot == -1)
         return null;
      return fileName.substring(dot + 1);
   }

   /**
   * Strip the path and the file name extension.
   * @param fileName for example "/tmp/hello.txt"
   * @return filename without extension "hello"
   */
   public static String getBody(String fileName) {
      if (fileName == null)
         return null;
      int dot = fileName.lastIndexOf(".");
      String body = null;
      if (dot == -1)
         body = fileName;
      else
         body = fileName.substring(0, dot);
      int sep = body.lastIndexOf(File.separator);
      if (sep == -1)
         return body;
      return body.substring(sep + 1);
   }
  
   /**
    * Deletes all files and subdirectories under dir.
    * Returns true if all deletions were successful.
    * If a deletion fails, the method stops attempting to delete and returns false.
    * Thanks to "The Java Developers Almanac 1.4"
    */
   public static boolean deleteDir(File dir) {
       if (dir.isDirectory()) {
           String[] children = dir.list();
           for (int i=0; i<children.length; i++) {
               boolean success = deleteDir(new File(dir, children[i]));
               if (!success) {
                   return false;
               }
           }
       }
  
       // The directory is now empty so delete it
       return dir.delete();
   }  

   /**
   * Convert some file extensions to MIME types.
   * <p />
   * A candidate for a property file like /etc/httpd/mime.types
   * @param extension for example "xml"
   * @param defaultVal for example "text/plain"
   * @return for example "text/xml"
   */
   public static String extensionToMime(String extension, String defaultVal) {
      if (extension == null)
         return defaultVal;
      if (extension.equalsIgnoreCase("xml"))
         return "text/xml";
      if (extension.equalsIgnoreCase("html"))
         return "text/html";
      if (extension.equalsIgnoreCase("gml"))
         return "text/gml"; // grafic markup language http://infosun.fmi.uni-passau.de/Graphlet/GML
      if (extension.equalsIgnoreCase("sgml"))
         return "text/sgml";
      if (extension.equalsIgnoreCase("gif"))
         return "image/gif";
      if (extension.equalsIgnoreCase("png"))
         return "image/png";
      if (extension.equalsIgnoreCase("jpeg"))
         return "image/jpeg";
      if (extension.equalsIgnoreCase("jpg"))
         return "image/jpg";
      if (extension.equalsIgnoreCase("pdf"))
         return "application/pdf";
      if (extension.equalsIgnoreCase("rtf"))
         return "text/rtf";
      return defaultVal;
   }

   /**
    * java org.xmlBlaster.util.FileLocator -pluginsFile http://www.xmlblaster.org/empty.html
    * @param args
    */
   public static void main(String[] args) {
       Global glob = Global.instance();
       glob.init(args);

       FileLocator locator = new FileLocator(glob);

       try {
          URL url = locator.findFileInXmlBlasterSearchPath("pluginsFile", "xmlBlasterPlugins.xml");
          if (url != null && url.getFile() != null) {
             System.out.println("The file 'xmlBlasterPlugins.xml' has been found");
             System.out.println("Its complete path is: '" + url.toString() + "' and the file is '" + url.getFile() + "'");
             System.out.println("DUMP:");
             System.out.println(locator.read(url));
          }
          else {
             System.out.println("The file 'xmlBlasterPlugins.xml' has not been found");
          }
       }
       catch (Exception ex) {
          System.err.println("Error occured: " + ex.toString());
       }
    }  
}
TOP

Related Classes of org.xmlBlaster.util.FileLocator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.