Java/File Input Output/Resources

Материал из Java эксперт
Перейти к: навигация, поиск

Load a resource as a stream

   
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

//Revised from apache cxf 
public class Main {
  /**
   * Load a given resource. <p/> This method will try to load the resource
   * using the following methods (in order):
   * <ul>
   * <li>From Thread.currentThread().getContextClassLoader()
   * <li>From ClassLoaderUtil.class.getClassLoader()
   * <li>callingClass.getClassLoader()
   * </ul>
   * 
   * @param resourceName The name of the resource to load
   * @param callingClass The Class object of the calling object
   */
  public static URL getResource(String resourceName, Class callingClass) {
      URL url = Thread.currentThread().getContextClassLoader().getResource(resourceName);
      if (url == null && resourceName.startsWith("/")) {
          //certain classloaders need it without the leading /
          url = Thread.currentThread().getContextClassLoader()
              .getResource(resourceName.substring(1));
      }
      ClassLoader cluClassloader = Main.class.getClassLoader();
      if (cluClassloader == null) {
          cluClassloader = ClassLoader.getSystemClassLoader();
      }
      if (url == null) {
          url = cluClassloader.getResource(resourceName);
      }
      if (url == null && resourceName.startsWith("/")) {
          //certain classloaders need it without the leading /
          url = cluClassloader.getResource(resourceName.substring(1));
      }
      if (url == null) {
          ClassLoader cl = callingClass.getClassLoader();
          if (cl != null) {
              url = cl.getResource(resourceName);
          }
      }
      if (url == null) {
          url = callingClass.getResource(resourceName);
      }
      
      if ((url == null) && (resourceName != null) && (resourceName.charAt(0) != "/")) {
          return getResource("/" + resourceName, callingClass);
      }
      return url;
  }
  
  /**
   * This is a convenience method to load a resource as a stream. <p/> The
   * algorithm used to find the resource is given in getResource()
   * 
   * @param resourceName The name of the resource to load
   * @param callingClass The Class object of the calling object
   */
  public static InputStream getResourceAsStream(String resourceName, Class callingClass) {
      URL url = getResource(resourceName, callingClass);
      try {
          return (url != null) ? url.openStream() : null;
      } catch (IOException e) {
          return null;
      }
  }
  /**
   * Load a given resources. <p/> This method will try to load the resources
   * using the following methods (in order):
   * <ul>
   * <li>From Thread.currentThread().getContextClassLoader()
   * <li>From ClassLoaderUtil.class.getClassLoader()
   * <li>callingClass.getClassLoader()
   * </ul>
   * 
   * @param resourceName The name of the resource to load
   * @param callingClass The Class object of the calling object
   */
  public static List<URL> getResources(String resourceName, Class callingClass) {
      List<URL> ret = new ArrayList<URL>();
      Enumeration<URL> urls = new Enumeration<URL>() {
          public boolean hasMoreElements() {
              return false;
          }
          public URL nextElement() {
              return null;
          }
          
      };
      try {
          urls = Thread.currentThread().getContextClassLoader()
              .getResources(resourceName);
      } catch (IOException e) {
          //ignore
      }
      if (!urls.hasMoreElements() && resourceName.startsWith("/")) {
          //certain classloaders need it without the leading /
          try {
              urls = Thread.currentThread().getContextClassLoader()
                  .getResources(resourceName.substring(1));
          } catch (IOException e) {
              // ignore
          }
      }
      ClassLoader cluClassloader = Main.class.getClassLoader();
      if (cluClassloader == null) {
          cluClassloader = ClassLoader.getSystemClassLoader();
      }
      if (!urls.hasMoreElements()) {
          try {
              urls = cluClassloader.getResources(resourceName);
          } catch (IOException e) {
              // ignore
          }
      }
      if (!urls.hasMoreElements() && resourceName.startsWith("/")) {
          //certain classloaders need it without the leading /
          try {
              urls = cluClassloader.getResources(resourceName.substring(1));
          } catch (IOException e) {
              // ignore
          }
      }
      if (!urls.hasMoreElements()) {
          ClassLoader cl = callingClass.getClassLoader();
          if (cl != null) {
              try {
                  urls = cl.getResources(resourceName);
              } catch (IOException e) {
                  // ignore
              }
          }
      }
      if (!urls.hasMoreElements()) {
          URL url = callingClass.getResource(resourceName);
          if (url != null) {
              ret.add(url);
          }
      }
      while (urls.hasMoreElements()) {
          ret.add(urls.nextElement());
      }
      
      if (ret.isEmpty() && (resourceName != null) && (resourceName.charAt(0) != "/")) {
          return getResources("/" + resourceName, callingClass);
      }
      return ret;
  }

}





Loading resources and classes in a fault tolerant manner

   
/*
 * Copyright (c) 2002-2003 by OpenSymphony
 * All rights reserved.
 */
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Collections;

/**
 * This class is extremely useful for loading resources and classes in a fault tolerant manner
 * that works across different applications servers.
 * <p/>
 * It has come out of many months of frustrating use of multiple application servers at Atlassian,
 * please don"t change things unless you"re sure they"re not going to break in one server or another!
 *
 * @author plightbo
 * @author tmjee
 * @version $Date: 2007-11-30 18:45:26 +0800 (Fri, 30 Nov 2007) $ $Id: ClassLoaderUtils.java 2977 2007-11-30 10:45:26Z tm_jee $
 */
public class ClassLoaderUtils {
    /**
     * Load a given resource.
     * <p/>
     * This method will try to load the resource using the following methods (in order):
     * <ul>
     * <li>From {@link Thread#getContextClassLoader() Thread.currentThread().getContextClassLoader()}
     * <li>From {@link Class#getClassLoader() ClassLoaderUtil.class.getClassLoader()}
     * <li>From the {@link Class#getClassLoader() callingClass.getClassLoader() }
     * </ul>
     *
     * @param resourceName The name of the resource to load
     * @param callingClass The Class object of the calling object
     */
    public static URL getResource(String resourceName, Class callingClass) {
        URL url = null;
        url = Thread.currentThread().getContextClassLoader().getResource(resourceName);
        if (url == null) {
            url = ClassLoaderUtils.class.getClassLoader().getResource(resourceName);
        }
        if (url == null) {
            url = callingClass.getClassLoader().getResource(resourceName);
        }
        return url;
    }
    /**
     * This is a convenience method to load a resource as a stream.
     * <p/>
     * The algorithm used to find the resource is given in getResource()
     *
     * @param resourceName The name of the resource to load
     * @param callingClass The Class object of the calling object
     */
    public static InputStream getResourceAsStream(String resourceName, Class callingClass) {
        URL url = getResource(resourceName, callingClass);
        try {
            return (url != null) ? url.openStream() : null;
        } catch (IOException e) {
            return null;
        }
    }
    /**
     * Load a class with a given name.
     * <p/>
     * It will try to load the class in the following order:
     * <ul>
     * <li>From {@link Thread#getContextClassLoader() Thread.currentThread().getContextClassLoader()}
     * <li>Using the basic {@link Class#forName(java.lang.String) }
     * <li>From {@link Class#getClassLoader() ClassLoaderUtil.class.getClassLoader()}
     * <li>From the {@link Class#getClassLoader() callingClass.getClassLoader() }
     * </ul>
     *
     * @param className    The name of the class to load
     * @param callingClass The Class object of the calling object
     * @throws ClassNotFoundException If the class cannot be found anywhere.
     */
    public static Class loadClass(String className, Class callingClass) throws ClassNotFoundException {
        try {
            return Thread.currentThread().getContextClassLoader().loadClass(className);
        } catch (ClassNotFoundException e) {
            try {
                return Class.forName(className);
            } catch (ClassNotFoundException ex) {
                try {
                    return ClassLoaderUtils.class.getClassLoader().loadClass(className);
                } catch (ClassNotFoundException exc) {
                    return callingClass.getClassLoader().loadClass(className);
                }
            }
        }
    }
    /**
     * Prints the current classloader hierarchy - useful for debugging.
     */
    public static void printClassLoader() {
        System.out.println("ClassLoaderUtils.printClassLoader");
        printClassLoader(Thread.currentThread().getContextClassLoader());
    }
    /**
     * Prints the classloader hierarchy from a given classloader - useful for debugging.
     */
    public static void printClassLoader(ClassLoader cl) {
        System.out.println("ClassLoaderUtils.printClassLoader(cl = " + cl + ")");
        if (cl != null) {
            printClassLoader(cl.getParent());
        }
    }
}





Return a resource URL.

   
/*
 * 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.
 */
import java.net.MalformedURLException;
import java.net.URL;
/**
 * A collection of class management utility methods.
 *
 * @version $Id: ClassUtils.java 587751 2007-10-24 02:41:36Z vgritsenko $
 */
public class ClassUtils {

    /**
     * Return a resource URL.
     * BL: if this is command line operation, the classloading issues
     *     are more sane.  During servlet execution, we explicitly set
     *     the ClassLoader.
     *
     * @return The context classloader.
     * @exception MalformedURLException If a loading error occurs
     */
    public static URL getResource(String resource) throws MalformedURLException {
        return getClassLoader().getResource(resource);
    }
    /**
     * Return the context classloader.
     * BL: if this is command line operation, the classloading issues
     *     are more sane.  During servlet execution, we explicitly set
     *     the ClassLoader.
     *
     * @return The context classloader.
     */
    public static ClassLoader getClassLoader() {
        return Thread.currentThread().getContextClassLoader();
    }
}





Utility class to manage localization resources

   
/*****************************************************************************
 * Java Plug-in Framework (JPF)
 * Copyright (C) 2004-2005 Dmitry Olshansky
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *****************************************************************************/

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/**
 * Utility class to manage localization resources. This class is not for public
 * usage but mainly for custom implementations developers to provide them
 * uniform access and organization of locale specific data.
 * <br>
 * Class usage is very simple. Put your locale sensible data into
 * <code>Resources.properties</code> files and save them near classes that you
 * are going to get localized. For {@link java.util.Locale} to file mapping
 * details see {@link ResourceBundle} documentation.
 * 
 * @version $Id$
 */
public final class ResourceManager {
    private static final Object FAKE_BUNDLE = new Object();
    private static final Map<String, Object> bundles =
        Collections.synchronizedMap(new HashMap<String, Object>());
    
    /**
     * @param packageName package name, used for
     *        <code>Resources.properties</code> file look-up
     * @param messageKey message key
     * @return message for {@link Locale#getDefault() default locale}
     */
    public static String getMessage(final String packageName,
            final String messageKey) {
        return getMessage(packageName, messageKey, Locale.getDefault(), null);
    }
    
    /**
     * @param packageName package name, used for
     *        <code>Resources.properties</code> file look-up
     * @param messageKey message key
     * @param data data for parameter placeholders substitution, may be
     *        <code>Object</code>, <code>array</code> or
     *        <code>Collection</code>.
     * @return message for {@link Locale#getDefault() default locale}
     */
    public static String getMessage(final String packageName,
            final String messageKey, final Object data) {
        return getMessage(packageName, messageKey, Locale.getDefault(), data);
    }
    /**
     * @param packageName package name, used for
     *        <code>Resources.properties</code> file look-up
     * @param messageKey message key
     * @param locale locale to get message for
     * @return message for given locale
     */
    public static String getMessage(final String packageName,
            final String messageKey, final Locale locale) {
        return getMessage(packageName, messageKey, locale, null);
    }
    /**
     * @param packageName package name, used for
     *        <code>Resources.properties</code> file look-up
     * @param messageKey message key
     * @param locale locale to get message for
     * @param data data for parameter placeholders substitution, may be
     *        <code>Object</code>, <code>array</code> or
     *        <code>Collection</code>.
     * @return message for given locale
     */
    public static String getMessage(final String packageName,
            final String messageKey, final Locale locale, final Object data) {
        Object obj = bundles.get(packageName + "|" + locale);
        if (obj == null) {
            try {
                obj = ResourceBundle.getBundle(packageName + ".Resources", //$NON-NLS-1$
                        locale);
            } catch (MissingResourceException mre) {
                obj = FAKE_BUNDLE;
            }
            bundles.put(packageName + "|" + locale, obj);
        }
        if (obj == FAKE_BUNDLE) {
            return "resource " + packageName + "." + messageKey //$NON-NLS-1$
                + " not found for locale " + locale; //$NON-NLS-1$
        }
        try {
            String result = ((ResourceBundle) obj).getString(messageKey);
            return (data == null) ? result : processParams(result, data);
        } catch (MissingResourceException mre) {
            return "resource " + packageName + "." + messageKey //$NON-NLS-1$
                + " not found for locale " + locale; //$NON-NLS-1$
        }
    }
    private static String processParams(final String str, final Object data) {
        String result = str;
        if ((data != null) && data.getClass().isArray()) {
            Object[] params = (Object[])data;
            for (int i = 0; i < params.length; i++) {
                result = replaceAll(result, "{" + i + "}", "" + params[i]); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
            }
        } else if (data instanceof Collection) {
            int i = 0;
            for (Object object : (Collection) data) {
                result = replaceAll(result, "{" + i++ + "}", "" + object); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
            }
        } else {
            result = replaceAll(result, "{0}", "" + data); //$NON-NLS-1$ //$NON-NLS-2$
        }
        return result;
    }
    private static String replaceAll(final String str, final String from,
            final String to) {
        String result = str;
        int p = 0;
        while (true) {
            p = result.indexOf(from, p);
            if (p == -1) {
                break;
            }
            result = result.substring(0, p) + to
                + result.substring(p + from.length());
            p += to.length();
        }
        return result;
    }
    private ResourceManager() {
        // no-op
    }
}





Utility methods for resolving resource locations to files in the file system

   
/*
 * Copyright 2002-2007 the original author or authors.
 *
 * Licensed 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.
 */

import java.io.File;
import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
/**
 * Utility methods for resolving resource locations to files in the
 * file system. Mainly for internal use within the framework.
 *
 * <p>Consider using Spring"s Resource abstraction in the core package
 * for handling all kinds of file resources in a uniform manner.
 * {@link org.springframework.core.io.ResourceLoader}"s <code>getResource</code>
 * method can resolve any location to a {@link org.springframework.core.io.Resource}
 * object, which in turn allows to obtain a <code>java.io.File</code> in the
 * file system through its <code>getFile()</code> method.
 *
 * <p>The main reason for these utility methods for resource location handling
 * is to support {@link Log4jConfigurer}, which must be able to resolve
 * resource locations <i>before the logging system has been initialized</i>.
 * Spring" Resource abstraction in the core package, on the other hand,
 * already expects the logging system to be available.
 *
 * @author Juergen Hoeller
 * @since 1.1.5
 * @see org.springframework.core.io.Resource
 * @see org.springframework.core.io.ClassPathResource
 * @see org.springframework.core.io.FileSystemResource
 * @see org.springframework.core.io.UrlResource
 * @see org.springframework.core.io.ResourceLoader
 */
public abstract class ResourceUtils {
  /** Pseudo URL prefix for loading from the class path: "classpath:" */
  public static final String CLASSPATH_URL_PREFIX = "classpath:";
  /** URL prefix for loading from the file system: "file:" */
  public static final String FILE_URL_PREFIX = "file:";
  /** URL protocol for a file in the file system: "file" */
  public static final String URL_PROTOCOL_FILE = "file";
  /** URL protocol for an entry from a jar file: "jar" */
  public static final String URL_PROTOCOL_JAR = "jar";
  /** URL protocol for an entry from a zip file: "zip" */
  public static final String URL_PROTOCOL_ZIP = "zip";
  /** URL protocol for an entry from a WebSphere jar file: "wsjar" */
  public static final String URL_PROTOCOL_WSJAR = "wsjar";
  /** URL protocol for an entry from an OC4J jar file: "code-source" */
  public static final String URL_PROTOCOL_CODE_SOURCE = "code-source";
  /** Separator between JAR URL and file path within the JAR */
  public static final String JAR_URL_SEPARATOR = "!/";

  /**
   * Return whether the given resource location is a URL:
   * either a special "classpath" pseudo URL or a standard URL.
   * @param resourceLocation the location String to check
   * @return whether the location qualifies as a URL
   * @see #CLASSPATH_URL_PREFIX
   * @see java.net.URL
   */
  public static boolean isUrl(String resourceLocation) {
    if (resourceLocation == null) {
      return false;
    }
    if (resourceLocation.startsWith(CLASSPATH_URL_PREFIX)) {
      return true;
    }
    try {
      new URL(resourceLocation);
      return true;
    }
    catch (MalformedURLException ex) {
      return false;
    }
  }

  /**
   * Determine whether the given URL points to a resource in a jar file,
   * that is, has protocol "jar", "zip", "wsjar" or "code-source".
   * <p>"zip" and "wsjar" are used by BEA WebLogic Server and IBM WebSphere, respectively,
   * but can be treated like jar files. The same applies to "code-source" URLs on Oracle
   * OC4J, provided that the path contains a jar separator.
   * @param url the URL to check
   * @return whether the URL has been identified as a JAR URL
   */
  public static boolean isJarURL(URL url) {
    String protocol = url.getProtocol();
    return (URL_PROTOCOL_JAR.equals(protocol) ||
        URL_PROTOCOL_ZIP.equals(protocol) ||
        URL_PROTOCOL_WSJAR.equals(protocol) ||
        (URL_PROTOCOL_CODE_SOURCE.equals(protocol) && url.getPath().indexOf(JAR_URL_SEPARATOR) != -1));
  }
  /**
   * Extract the URL for the actual jar file from the given URL
   * (which may point to a resource in a jar file or to a jar file itself).
   * @param jarUrl the original URL
   * @return the URL for the actual jar file
   * @throws MalformedURLException if no valid jar file URL could be extracted
   */
  public static URL extractJarFileURL(URL jarUrl) throws MalformedURLException {
    String urlFile = jarUrl.getFile();
    int separatorIndex = urlFile.indexOf(JAR_URL_SEPARATOR);
    if (separatorIndex != -1) {
      String jarFile = urlFile.substring(0, separatorIndex);
      try {
        return new URL(jarFile);
      }
      catch (MalformedURLException ex) {
        // Probably no protocol in original jar URL, like "jar:C:/mypath/myjar.jar".
        // This usually indicates that the jar file resides in the file system.
        if (!jarFile.startsWith("/")) {
          jarFile = "/" + jarFile;
        }
        return new URL(FILE_URL_PREFIX + jarFile);
      }
    }
    else {
      return jarUrl;
    }
  }
}