View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  package org.apache.log4j.chainsaw.plugins;
    18
    19  import java.io.File;
    20  import java.io.FilenameFilter;
    21  import java.net.URL;
    22  import java.net.URLClassLoader;
    23  import java.util.ArrayList;
    24  import java.util.List;
    25
    26  import org.apache.log4j.chainsaw.prefs.SettingsManager;
    27
    28  /**
    29   * A factory class to create a Classloader that can refenerence jars/classes/resources
    30   * within a users plugin directory.
    31   *
    32   * Currently a work in progress to see if this allows external jars required by
    33   * some 3rd party vendors for things like the JMSReceiver.
    34   *
    35   * @author psmith
    36   *
    37   *
    38   */
    39  public class PluginClassLoaderFactory {
    40  	private final ClassLoader pluginClassLoader;
    41
    42      private static final PluginClassLoaderFactory instance = new PluginClassLoaderFactory();
    43
    44  	private PluginClassLoaderFactory() {
    45          this.pluginClassLoader= PluginClassLoaderFactory.create(new File(SettingsManager.getInstance().getSettingsDirectory() + File.separator + "plugins"));
    46
    47  	}
    48
    49      public static PluginClassLoaderFactory getInstance() {
    50       return instance;
    51      }
    52
    53      public ClassLoader getClassLoader() {
    54       return this.pluginClassLoader;
    55      }
    56
    57      /**
    58       * Creates a Classloader that will be able to access any of the classes found
    59       * in any .JAR file contained within the specified directory path, PLUS
    60       * the actual Plugin directory itself, so it acts like the WEB-INF/classes directory,
    61       * any class file in the directory will be accessible
    62       *
    63       * @param pluginDirectory
    64       * @throws IllegalArgumentException if the pluginDirectory is null, does not exist, or cannot be read
    65       * @throws RuntimeException if turning a File into a URL failed, which would be very unexpected
    66       * @return
    67       */
    68      private static final ClassLoader create(File pluginDirectory) {
    69          if(pluginDirectory == null || !pluginDirectory.exists() || !pluginDirectory.canRead()) {
    70           return PluginClassLoaderFactory.class.getClassLoader();
    71          }
    72
    73          String[] strings = pluginDirectory.list(new FilenameFilter() {
    74
    75  			public boolean accept(File dir, String name) {
    76                  return name.toUpperCase().endsWith(".JAR");
    77  			}});
    78
    79
    80          List list = new ArrayList();
    81          // add the plugin directory as a resource loading path
    82          try {
    83  			list.add(pluginDirectory.toURI().toURL());
    84  		} catch (Exception e) {
    85  			throw new RuntimeException(e.getMessage());
    86  		}
    87          if (strings !=null) {
    88  			for (int i = 0; i < strings.length; i++) {
    89  				String name = strings[i];
    90  				File file = new File(pluginDirectory, name);
    91  				try {
    92  					list.add(file.toURI().toURL());
    93  					System.out.println("Added " + file.getAbsolutePath()
    94  							+ " to Plugin class loader list");
    95  				} catch (Exception e) {
    96  					System.err.println("Failed to retrieve the URL for file: "
    97  							+ file.getAbsolutePath());
    98  					throw new RuntimeException(e.getMessage());
    99  				}
    100 			}
    101 		}
    102         ClassLoader parent = PluginClassLoaderFactory.class.getClassLoader();
    103         URL[] urls = (URL[]) list.toArray(new URL[list.size()]);
    104         return new URLClassLoader(urls, parent);
    105     }
    106
    107 }