Package hermes.impl

Source Code of hermes.impl.LoaderSupport

/*
* Copyright 2003,2004 Colin Crist
*
* 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.
*
*/

package hermes.impl;

import hermes.browser.HermesBrowser;
import hermes.config.ClasspathConfig;
import hermes.config.PropertyConfig;
import hermes.config.PropertySetConfig;
import hermes.util.TextUtils;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandlerFactory;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;

import javax.jms.ConnectionFactory;
import javax.swing.ProgressMonitor;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;

/**
* Helper for mucking about with ClassLoaders
*
* @author colincrist@hermesjms.com
* @version $Id: LoaderSupport.java,v 1.29 2006/07/13 07:35:31 colincrist Exp $
*/
public class LoaderSupport
{
   private static final Logger log = Logger.getLogger(LoaderSupport.class);

   public static class DebugClassLoader extends URLClassLoader
   {
      /**
       * @param arg0
       */
      public DebugClassLoader(URL[] arg0)
      {
         super(arg0);
      }

      /**
       * @param arg0
       * @param arg1
       */
      public DebugClassLoader(URL[] arg0, ClassLoader arg1)
      {
         super(arg0, arg1);
      }

      /**
       * @param arg0
       * @param arg1
       * @param arg2
       */
      public DebugClassLoader(URL[] arg0, ClassLoader arg1, URLStreamHandlerFactory arg2)
      {
         super(arg0, arg1, arg2);
      }

      /*
       * (non-Javadoc)
       *
       * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
       */
      protected synchronized Class loadClass(String arg0, boolean arg1) throws ClassNotFoundException
      {
         if (arg0.startsWith("hermes.ext"))
         {
            log.debug("loadClass(" + arg0 + ", " + arg1 + ") from " + toString());
         }

         return super.loadClass(arg0, arg1);
      }

      public String toString()
      {
         StringBuffer rval = new StringBuffer();

         rval.append("DebugClassLoader: ");

         for (int i = 0; i < getURLs().length; i++)
         {
            URL url = getURLs()[i];

            rval.append(url.toString());

            if (i != getURLs().length - 1)
            {
               rval.append(", ");
            }
         }

         if (getParent() instanceof DebugClassLoader)
         {
            rval.append(", parent=" + getParent().toString());
         }

         return rval.toString();
      }

      protected Class findClass(String name) throws ClassNotFoundException
      {
         return super.findClass(name);
      }
   }

  

   /**
    * Return ClassLoader given the list of ClasspathConfig instances. The
    * resulting loader can then be used to instantiate providers from those
    * libraries.
    */
   static ClassLoader createClassLoader(List loaderConfigs, URL[] extraUrls, ClassLoader classLoader) throws IOException
   {
      int index = 0;
      int size = loaderConfigs.size();

      if (extraUrls != null)
      {
         size += extraUrls.length;
      }

      URL[] urls = new URL[size];
      StringBuffer debug = new StringBuffer("URLClassLoader: ");

      for (Iterator iter = loaderConfigs.iterator(); iter.hasNext();)
      {
         ClasspathConfig lConfig = (ClasspathConfig) iter.next();

         URL url = null;

         if (lConfig.getJar().startsWith("http"))
         {
            url = new URL(TextUtils.replaceClasspathVariables(lConfig.getJar()));
         }
         else
         {
            url = new File(TextUtils.replaceClasspathVariables(lConfig.getJar())).toURL();

         }

         urls[index++] = url;

         debug.append(url.toString());

         if (iter.hasNext())
         {
            debug.append(", ");
         }
      }

      if (extraUrls != null)
      {
         for (int i = 0; i < extraUrls.length; i++)
         {
            urls[index++] = extraUrls[i];
            debug.append(", " + extraUrls[i].toString());
         }
      }

      log.debug(debug.toString());

      return new DebugClassLoader(urls, classLoader);
   }

   static ClassLoader createClassLoader(List loaderConfigs, ClassLoader classLoader) throws IOException
   {
      return createClassLoader(loaderConfigs, null, classLoader);

   }

   /**
    * Return ClassLoader given the list of ClasspathConfig instances. The
    * resulting loader can then be used to instantiate providers from those
    * libraries.
    */
   static List lookForFactories(final List loaderConfigs, final ClassLoader baseLoader) throws IOException
   {
      final List rval = new ArrayList();

      for (Iterator iter = loaderConfigs.iterator(); iter.hasNext();)
      {
         final ClasspathConfig lConfig = (ClasspathConfig) iter.next();

         if (lConfig.getFactories() != null)
         {
            log.debug("using cached " + lConfig.getFactories());

            for (StringTokenizer tokens = new StringTokenizer(lConfig.getFactories(), ","); tokens.hasMoreTokens();)
            {
               rval.add(tokens.nextToken());
            }
         }
         else if (lConfig.isNoFactories())
         {
            log.debug("previously scanned " + lConfig.getJar());
         }
         else
         {
            Runnable r = new Runnable()
            {
               public void run()
               {
                  final List localFactories = new ArrayList();
                  boolean foundFactory = false;
                  StringBuffer factoriesAsString = null;

                  try
                  {
                     log.debug("searching " + lConfig.getJar());

                     ClassLoader l = createClassLoader(loaderConfigs, baseLoader);
                     JarFile jarFile = new JarFile(lConfig.getJar());
                     ProgressMonitor monitor = null;
                     int entryNumber = 0;

                     if (HermesBrowser.getBrowser() != null)
                     {
                        monitor = new ProgressMonitor(HermesBrowser.getBrowser(), "Looking for factories in " + lConfig.getJar(), "Scanning...", 0, jarFile
                              .size());
                        monitor.setMillisToDecideToPopup(0);
                        monitor.setMillisToPopup(0);
                        monitor.setProgress(0);
                     }

                     for (Enumeration iter = jarFile.entries(); iter.hasMoreElements();)
                     {
                        ZipEntry entry = (ZipEntry) iter.nextElement();
                        entryNumber++;

                        if (monitor != null)
                        {
                           monitor.setProgress(entryNumber);
                           monitor.setNote("Checking entry " + entryNumber + " of " + jarFile.size());
                        }

                        if (entry.getName().endsWith(".class"))
                        {
                           String s = entry.getName().substring(0, entry.getName().indexOf(".class"));

                           s = s.replaceAll("/", ".");

                           try
                           {
                              if (s.startsWith("hermes.browser") || s.startsWith("hermes.impl") || s.startsWith("javax.jms"))
                              {
                                 // NOP
                              }
                              else
                              {
                                 Class clazz = l.loadClass(s);

                                 if (!clazz.isInterface())
                                 {

                                    if (implementsOrExtends(clazz, ConnectionFactory.class))
                                    {

                                       foundFactory = true;
                                       localFactories.add(s);

                                       if (factoriesAsString == null)
                                       {
                                          factoriesAsString = new StringBuffer();
                                          factoriesAsString.append(clazz.getName());
                                       }
                                       else
                                       {
                                          factoriesAsString.append(",").append(clazz.getName());
                                       }
                                       log.debug("found " + clazz.getName());
                                    }
                                 }

                                 /**
                                  * TODO: remove Class clazz = l.loadClass(s);
                                  * Class[] interfaces = clazz.getInterfaces();
                                  * for (int i = 0; i < interfaces.length; i++) {
                                  * if
                                  * (interfaces[i].equals(TopicConnectionFactory.class) ||
                                  * interfaces[i].equals(QueueConnectionFactory.class) ||
                                  * interfaces[i].equals(ConnectionFactory.class)) {
                                  * foundFactory = true; localFactories.add(s);
                                  * if (factoriesAsString == null) {
                                  * factoriesAsString = new
                                  * StringBuffer(clazz.getName()); } else {
                                  * factoriesAsString.append(",").append(clazz.getName()); }
                                  * log.debug("found " + clazz.getName()); } }
                                  */
                              }
                           }
                           catch (Throwable t)
                           {
                              // NOP
                           }
                        }
                     }
                  }
                  catch (IOException e)
                  {
                     log.error("unable to access jar/zip " + lConfig.getJar() + ": " + e.getMessage(), e);
                  }

                  if (!foundFactory)
                  {
                     lConfig.setNoFactories(true);
                  }
                  else
                  {
                     lConfig.setFactories(factoriesAsString.toString());
                     rval.addAll(localFactories);
                  }

               }
            };

            r.run();

         }
      }

      return rval;
   }

   /**
    * Indicates if a class or interface implements or extends the specified
    * interfaces or classes. If the specified <CODE>Class</CODE> is a class,
    * this method will recursively test if this class, its superclass or one of
    * the implemented interfaces of this class implements the specified
    * interface.<BR>
    * If the specified <CODE>Class</CODE> is an interface, this method will
    * recursively test if this interface or one of the implemented interfaces of
    * this interface implements the specified interface.<BR>
    *
    * @param clazz
    *           the class or interface in question
    * @param testInterface
    *           the class or interface to test against
    * @return <CODE>true</CODE> if the specified interfaces is implemented by
    *         this class or one of its super-classes or interfaces
    */
   public static boolean implementsOrExtends(Class clazz, Class testInterface)
   {
      Class[] implementedInterfaces = clazz.getInterfaces();

      // test interface
      if (clazz.equals(testInterface))
      {
         return true; // possibly the end of the recursion
      }

      for (int i = 0; i < implementedInterfaces.length; i++)
      {
         if (implementsOrExtends(implementedInterfaces[i], testInterface))
         {
            return true; // recursion
         }
      }

      // maybe the superclass implements this interface ?
      Class superClass = clazz.getSuperclass();
      if (superClass != null && implementsOrExtends(superClass, testInterface))
      {
         return true; // recursion
      }

      return false;
   }

   public static void populateBean(Object bean, PropertySetConfig propertySet) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, IOException
   {
      if (propertySet != null)
      {
         Set appliedProperties = new HashSet();

         for (Iterator iter = propertySet.getProperty().iterator(); iter.hasNext();)
         {
            PropertyConfig propertyConfig = (PropertyConfig) iter.next();

            if (appliedProperties.contains(propertyConfig.getName()))
            {
               iter.remove();
            }
            else
            {
               try
               {
                 
                  BeanUtils.setProperty(bean, propertyConfig.getName(), TextUtils.replaceClasspathVariables(propertyConfig.getValue()));

                  appliedProperties.add(propertyConfig.getName());
                 
                  log.debug("set " + bean.getClass().getName() + " " + propertyConfig.getName() + "=" +  TextUtils.replaceClasspathVariables(propertyConfig.getValue())) ;
               }
               catch (InvocationTargetException t)
               {
                  log.error("unable to set property name=" + propertyConfig.getName() + " value=" + propertyConfig.getValue() + " on object of class "
                        + bean.getClass().getName() + ": " + t.getCause().getMessage(), t.getCause());
               }
            }
         }
      }
   }
}
TOP

Related Classes of hermes.impl.LoaderSupport

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.