Save This Page
Home » xml-commons-external-1.4.01-src » javax » xml » rpc » [javadoc | source]
    1   /*
    2    * Copyright 2001-2004 The Apache Software Foundation.
    3    * 
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    * 
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    * 
   10    * Unless required by applicable law or agreed to in writing, software
   11    * distributed under the License is distributed on an "AS IS" BASIS,
   12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13    * See the License for the specific language governing permissions and
   14    * limitations under the License.
   15    */
   16   
   17   package javax.xml.rpc;
   18   
   19   import java.io.BufferedReader;
   20   import java.io.File;
   21   import java.io.FileInputStream;
   22   import java.io.InputStream;
   23   import java.io.InputStreamReader;
   24   import java.lang.reflect.InvocationTargetException;
   25   import java.lang.reflect.Method;
   26   import java.util.Properties;
   27   
   28   /**
   29    * This code is designed to implement the pluggability
   30    * feature and is designed to both compile and run on JDK version 1.1 and
   31    * later.  The code also runs both as part of an unbundled jar file and
   32    * when bundled as part of the JDK.
   33    *
   34    * This class is duplicated for each subpackage so keep it in sync.
   35    * It is package private and therefore is not exposed as part of the JAXRPC
   36    * API.
   37    */
   38   class FactoryFinder {
   39       /** Set to true for debugging. */
   40       private static final boolean debug = false;
   41   
   42       private static void debugPrintln(String msg) {
   43           if (debug) {
   44               System.err.println("JAXRPC: " + msg);
   45           }
   46       }
   47   
   48       /**
   49        * Figure out which ClassLoader to use.  For JDK 1.2 and later use
   50        * the context ClassLoader.
   51        *
   52        * @return the <code>ClassLoader</code>
   53        * @throws ConfigurationError   if this class is unable to work with the
   54        *              host JDK
   55        */
   56       private static ClassLoader findClassLoader()
   57           throws ConfigurationError
   58       {
   59           Method m = null;
   60   
   61           try {
   62               m = Thread.class.getMethod("getContextClassLoader", null);
   63           } catch (NoSuchMethodException e) {
   64               // Assume that we are running JDK 1.1, use the current ClassLoader
   65               debugPrintln("assuming JDK 1.1");
   66               return FactoryFinder.class.getClassLoader();
   67           }
   68   
   69           try {
   70               return (ClassLoader) m.invoke(Thread.currentThread(), null);
   71           } catch (IllegalAccessException e) {
   72               // assert(false)
   73               throw new ConfigurationError("Unexpected IllegalAccessException",
   74                                            e);
   75           } catch (InvocationTargetException e) {
   76               // assert(e.getTargetException() instanceof SecurityException)
   77               throw new ConfigurationError("Unexpected InvocationTargetException",
   78                                            e);
   79           }
   80       }
   81   
   82       /**
   83        * Create an instance of a class using the specified
   84        * <code>ClassLoader</code>, or if that fails from the
   85        * <code>ClassLoader</code> that loaded this class.
   86        *
   87        * @param className     the name of the class to instantiate
   88        * @param classLoader   a <code>ClassLoader</code> to load the class from
   89        *
   90        * @return a new <code>Object</code> that is an instance of the class of
   91        *              the given name from the given class loader
   92        * @throws ConfigurationError   if the class could not be found or
   93        *              instantiated
   94        */
   95       private static Object newInstance(String className,
   96                                         ClassLoader classLoader)
   97           throws ConfigurationError
   98       {
   99           try {
  100               if (classLoader != null) {
  101                   try {
  102                       return classLoader.loadClass(className).newInstance ();
  103                   } catch (ClassNotFoundException x) {
  104                         // try again
  105                   }
  106               }
  107               return Class.forName(className).newInstance();
  108           } catch (ClassNotFoundException x) {
  109               throw new ConfigurationError(
  110                   "Provider " + className + " not found", x);
  111           } catch (Exception x) {
  112               throw new ConfigurationError(
  113                   "Provider " + className + " could not be instantiated: " + x,
  114                   x);
  115           }
  116       }
  117   
  118       /**
  119        * Finds the implementation Class object in the specified order.  Main
  120        * entry point.
  121        * @return Class object of factory, never null
  122        *
  123        * @param factoryId             Name of the factory to find, same as
  124        *                              a property name
  125        * @param fallbackClassName     Implementation class name, if nothing else
  126        *                              is found.  Use null to mean no fallback.
  127        *
  128        * @exception FactoryFinder.ConfigurationError
  129        *
  130        * Package private so this code can be shared.
  131        */
  132       static Object find(String factoryId, String fallbackClassName)
  133           throws ConfigurationError
  134       {
  135           debugPrintln("debug is on");
  136   
  137           ClassLoader classLoader = findClassLoader();
  138   
  139           // Use the system property first
  140           try {
  141               String systemProp =
  142                   System.getProperty( factoryId );
  143               if( systemProp!=null) {
  144                   debugPrintln("found system property " + systemProp);
  145                   return newInstance(systemProp, classLoader);
  146               }
  147           } catch (SecurityException se) {
  148           }
  149   
  150           // try to read from $java.home/lib/xml.properties
  151           try {
  152               String javah=System.getProperty( "java.home" );
  153               String configFile = javah + File.separator +
  154                   "lib" + File.separator + "jaxrpc.properties";
  155               File f=new File( configFile );
  156               if( f.exists()) {
  157                   Properties props=new Properties();
  158                   props.load( new FileInputStream(f));
  159                   String factoryClassName = props.getProperty(factoryId);
  160                   debugPrintln("found java.home property " + factoryClassName);
  161                   return newInstance(factoryClassName, classLoader);
  162               }
  163           } catch(Exception ex ) {
  164               if( debug ) ex.printStackTrace();
  165           }
  166   
  167           String serviceId = "META-INF/services/" + factoryId;
  168           // try to find services in CLASSPATH
  169           try {
  170               InputStream is=null;
  171               if (classLoader == null) {
  172                   is=ClassLoader.getSystemResourceAsStream( serviceId );
  173               } else {
  174                   is=classLoader.getResourceAsStream( serviceId );
  175               }
  176   
  177               if( is!=null ) {
  178                   debugPrintln("found " + serviceId);
  179   
  180                   // Read the service provider name in UTF-8 as specified in
  181                   // the jar spec.  Unfortunately this fails in Microsoft
  182                   // VJ++, which does not implement the UTF-8
  183                   // encoding. Theoretically, we should simply let it fail in
  184                   // that case, since the JVM is obviously broken if it
  185                   // doesn't support such a basic standard.  But since there
  186                   // are still some users attempting to use VJ++ for
  187                   // development, we have dropped in a fallback which makes a
  188                   // second attempt using the platform's default encoding. In
  189                   // VJ++ this is apparently ASCII, which is a subset of
  190                   // UTF-8... and since the strings we'll be reading here are
  191                   // also primarily limited to the 7-bit ASCII range (at
  192                   // least, in English versions), this should work well
  193                   // enough to keep us on the air until we're ready to
  194                   // officially decommit from VJ++. [Edited comment from
  195                   // jkesselm]
  196                   BufferedReader rd;
  197                   try {
  198                       rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
  199                   } catch (java.io.UnsupportedEncodingException e) {
  200                       rd = new BufferedReader(new InputStreamReader(is));
  201                   }
  202   
  203                   String factoryClassName = rd.readLine();
  204                   rd.close();
  205   
  206                   if (factoryClassName != null &&
  207                       ! "".equals(factoryClassName)) {
  208                       debugPrintln("loaded from services: " + factoryClassName);
  209                       return newInstance(factoryClassName, classLoader);
  210                   }
  211               }
  212           } catch( Exception ex ) {
  213               if( debug ) ex.printStackTrace();
  214           }
  215   
  216           if (fallbackClassName == null) {
  217               throw new ConfigurationError(
  218                   "Provider for " + factoryId + " cannot be found", null);
  219           }
  220   
  221           debugPrintln("loaded from fallback value: " + fallbackClassName);
  222           return newInstance(fallbackClassName, classLoader);
  223       }
  224   
  225       static class ConfigurationError extends Error {
  226           // fixme: should this be refactored to use the jdk1.4 exception
  227           // wrapping?
  228   
  229           private Exception exception;
  230   
  231           /**
  232            * Construct a new instance with the specified detail string and
  233            * exception.
  234            *
  235            * @param msg   the Message for this error
  236            * @param x     an Exception that caused this failure, or null
  237            */
  238           ConfigurationError(String msg, Exception x) {
  239               super(msg);
  240               this.exception = x;
  241           }
  242   
  243           Exception getException() {
  244               return exception;
  245           }
  246       }
  247   }

Save This Page
Home » xml-commons-external-1.4.01-src » javax » xml » rpc » [javadoc | source]