Save This Page
Home » jdo2-model-2.3-ea-src » org.apache.jdo.impl.model.java.reflection » [javadoc | source]
    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   
   18   package org.apache.jdo.impl.model.java.reflection;
   19   
   20   import java.security.AccessController;
   21   import java.security.PrivilegedAction;
   22   import java.security.PrivilegedActionException;
   23   import java.security.PrivilegedExceptionAction;
   24   
   25   import org.apache.jdo.model.ModelException;
   26   import org.apache.jdo.model.ModelFatalException;
   27   import org.apache.jdo.model.java.JavaModel;
   28   import org.apache.jdo.model.java.JavaType;
   29   import org.apache.jdo.impl.model.java.AbstractJavaModelFactory;
   30   import org.apache.jdo.impl.model.java.BaseReflectionJavaType;
   31   import org.apache.jdo.util.I18NHelper;
   32   
   33   /**
   34    * A reflection based JavaModelFactory implementation. 
   35    * The implementation takes <code>java.lang.Class</code> and
   36    * <code>java.lang.reflect.Field</code> instances to get Java related
   37    * metadata about types and fields. This implementation caches JavaModel
   38    * instances per ClassLoader.
   39    * 
   40    * @since 1.1
   41    */
   42   public abstract class ReflectionJavaModelFactory
   43       extends AbstractJavaModelFactory
   44   {    
   45       /** I18N support */
   46       private final static I18NHelper msg =  
   47           I18NHelper.getInstance("org.apache.jdo.impl.model.java.Bundle"); //NOI18N
   48   
   49       /**
   50        * Creates a new empty JavaModel instance. A factory implementation may
   51        * use the specified key when caching the new JavaModel instance. 
   52        * <p>
   53        * This implementation only accepts <code>java.lang.ClassLoader</code>
   54        * instances as key. A ModelException indicates an invalid key.
   55        * <p>
   56        * The method automatically sets the parent/child relationship for the
   57        * created JavaModel according to the parent/child relationship of the 
   58        * ClassLoader passed as key. 
   59        * @param key the key that may be used to cache the returned JavaModel
   60        * instance. 
   61        * @return a new JavaModel instance.
   62        * @exception ModelException if impossible; the key is of an
   63        * inappropriate type.
   64        */
   65       public JavaModel createJavaModel(Object key)
   66           throws ModelException
   67       {
   68           if ((key != null) && (!(key instanceof ClassLoader)))
   69               throw new ModelException(msg.msg("EXC_InvalidJavaModelKey", //NOI18N
   70                                                key.getClass().getName()));
   71           
   72           ClassLoader classLoader = (ClassLoader)key;
   73           JavaModel javaModel = newJavaModelInstance(classLoader);
   74   
   75           // check parent <-> child relationship
   76           if (classLoader != null) {
   77               // if the specified classLoader is not null,
   78               // try to get the parent class loader and update the parent property
   79               try {
   80                   ClassLoader parentClassLoader = classLoader.getParent();
   81                   if (parentClassLoader != null) {
   82                       javaModel.setParent(getJavaModel(parentClassLoader));
   83                   }
   84               }
   85               catch (SecurityException ex) {
   86                   // ignore => parentClassLoader and parent JavaModel are null
   87               }
   88           }
   89   
   90           return javaModel;
   91       }
   92   
   93       /**
   94        * Returns a JavaType instance for the specified type description
   95        * (optional operation). This method is a convenience method and a
   96        * short cut for <code>getJavaModel(key).getJavaType(typeName)</code>.
   97        * <p>
   98        * The ReflectionJavaModelFactory supports this short cut and accepts
   99        * <code>java.lang.Class</code> instances as valid arguments for this
  100        * method. The method throws a 
  101        * {@link org.apache.jdo.model.ModelFatalException}, if the specified
  102        * type descriptor is not a <code>java.lang.Class</code> instance. 
  103        * @param typeDesc the type description
  104        * @return a JavaType instance for the specified type.
  105        * @exception ModelFatalException the specified type description is not
  106        * a <code>java.lang.Class</code> instance.
  107        */
  108       public JavaType getJavaType(Object typeDesc)
  109       {
  110           if (typeDesc == null)
  111               return null;
  112   
  113           try {
  114               Class clazz = (Class)typeDesc;
  115               ClassLoader classLoader = getClassLoaderPrivileged(clazz);
  116               return getJavaModel(classLoader).getJavaType(clazz);
  117           }
  118           catch (ClassCastException ex) {
  119               throw new ModelFatalException(msg.msg("EXC_InvalidTypeDesc", //NOI18N
  120                   typeDesc.getClass().getName()));
  121           }
  122       }
  123   
  124       // ===== Methods not defined in JavaModelFactory =====
  125   
  126       /**
  127        * Calls getClassLoader on the specified Class instance in a
  128        * doPrivileged block. Any SecurityException is wrapped into a
  129        * ModelFatalException. 
  130        * @param clazz the class to get the ClassLoader from.
  131        * @return the class loader that loaded the specified Class instance.
  132        * @exception ModelFatalException wraps the SecurityException thrown by
  133        * getClassLoader.
  134        */
  135       public static ClassLoader getClassLoaderPrivileged(final Class clazz)
  136       {
  137           if (clazz == null)
  138               return null;
  139   
  140           try { 
  141               return (ClassLoader) AccessController.doPrivileged(
  142                   new PrivilegedAction () {
  143                       public Object run () {
  144                           return clazz.getClassLoader();
  145                       }
  146                   }
  147                   );
  148           }
  149           catch (SecurityException ex) {
  150               throw new ModelFatalException(
  151                   msg.msg("EXC_CannotGetClassLoader", clazz), ex); //NOI18N
  152           }
  153       }
  154   
  155       /**
  156        * Calls Class.forName in a doPrivileged block. Any SecurityException is
  157        * wrapped into a ModelFatalException.
  158        * @param name fully qualified name of the desired class
  159        * @param initialize whether the class must be initialized
  160        * @param loader class loader from which the class must be loaded
  161        * @return class object representing the desired class.
  162        * @exception ModelFatalException wraps the SecurityException thrown by
  163        * getClassLoader.
  164        * @exception ClassNotFoundException if the class cannot be located by the
  165        * specified class loader.
  166        */
  167       public static Class forNamePrivileged(final String name, 
  168                                             final boolean initialize, 
  169                                             final ClassLoader loader)
  170           throws ClassNotFoundException
  171       {
  172           try { 
  173               return (Class) AccessController.doPrivileged(
  174                   new PrivilegedExceptionAction () {
  175                       public Object run () throws ClassNotFoundException {
  176                           return Class.forName(name, initialize, loader);
  177                       }
  178                   }
  179                   );
  180           }
  181           catch (PrivilegedActionException pae) {
  182               throw (ClassNotFoundException) pae.getException();
  183           }
  184           catch (SecurityException ex) {
  185               throw new ModelFatalException(
  186                   msg.msg("EXC_CannotGetClassInstance", name, loader), ex);
  187           }
  188       }
  189   
  190       /**
  191        * Returns the <code>java.lang.Class</code> wrapped in the specified 
  192        * JavaType. 
  193        * @return the <code>java.lang.Class</code> for the specified
  194        * JavaType. 
  195        * @exception ModelFatalException the specified JavaType does
  196        * not wrap a <code>java.lang.Class</code> instance.
  197        */
  198       public Class getJavaClass(JavaType javaType) 
  199       {
  200           if (javaType == null)
  201               return null;
  202           
  203           try {
  204               return ((BaseReflectionJavaType)javaType).getJavaClass();
  205           }
  206           catch (ClassCastException ex) {
  207               throw new ModelFatalException(msg.msg(
  208                   "EXC_InvalidJavaType", javaType.getClass())); //NOI18N
  209           }
  210       }
  211   
  212       //========= Internal helper methods ==========
  213       
  214       /** 
  215        * Creates a new instance of the JavaModel implementation class.
  216        * <p>
  217        * This implementation returns a <code>ReflectionJavaModel</code>
  218        * instance.
  219        * @return a new JavaModel instance.
  220        */
  221       protected JavaModel newJavaModelInstance(ClassLoader classLoader) {
  222           return new ReflectionJavaModel(classLoader, this);
  223       }
  224   
  225   }

Save This Page
Home » jdo2-model-2.3-ea-src » org.apache.jdo.impl.model.java.reflection » [javadoc | source]