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.io.InputStream;
   23   
   24   import org.apache.jdo.impl.model.java.AbstractJavaModel;
   25   import org.apache.jdo.impl.model.jdo.caching.JDOModelFactoryImplCaching;
   26   import org.apache.jdo.model.java.JavaType;
   27   import org.apache.jdo.model.jdo.JDOModel;
   28   import org.apache.jdo.model.jdo.JDOModelFactory;
   29   
   30   /**
   31    * A reflection based JavaModel implementation used at runtime.  
   32    * The implementation takes <code>java.lang.Class</code> and
   33    * <code>java.lang.reflect.Field</code> instances to get Java related
   34    * metadata about types and fields. 
   35    * <p>
   36    * The ReflectionJavaModel implementation will use this ClassLoader to lookup
   37    * any type by name. This makes sure that the type name is unique.
   38    *
   39    * @since 1.1
   40    * @version 2.0
   41    */
   42   public class ReflectionJavaModel
   43       extends AbstractJavaModel
   44   {
   45       /** The ClassLoader instance used as key to cache this JavaModel. */
   46       private final ClassLoader classLoader;
   47   
   48       /** The declaring JavaModelFactory. */
   49       protected final ReflectionJavaModelFactory declaringJavaModelFactory;
   50   
   51       /** Constructor. */
   52       protected ReflectionJavaModel(ClassLoader classLoader,
   53           ReflectionJavaModelFactory declaringJavaModelFactory)
   54       {
   55           super();
   56           this.classLoader = classLoader;
   57           this.declaringJavaModelFactory = declaringJavaModelFactory;
   58       }
   59   
   60       /** 
   61        * The method returns the JavaType instance for the specified type
   62        * name. A type name is unique within one JavaModel instance. The
   63        * method returns <code>null</code> if this model instance does not
   64        * know a type with the specified name.
   65        * <p>
   66        * Note, this method calls Class.forName with the wrapped ClassLoader,
   67        * if it cannot find a JavaType with the specified name in the cache.
   68        * @param name the name of the type
   69        * @return a JavaType instance for the specified name or
   70        * <code>null</code> if not present in this model instance.
   71        */
   72       public JavaType getJavaType(String name) 
   73       {
   74           synchronized (types) {
   75               JavaType javaType = (JavaType)types.get(name);
   76               if (javaType == null) {
   77                   try {
   78                       final boolean initialize = false; 
   79                       Class clazz = ReflectionJavaModelFactory.forNamePrivileged(
   80                           name, initialize, classLoader);
   81                       javaType = getJavaTypeInternal(clazz);
   82                   }
   83                   catch (ClassNotFoundException ex) {
   84                       // cannot find class => return null
   85                   }
   86               }
   87               return javaType;
   88           }
   89       }
   90   
   91       /** 
   92        * The method returns the JavaType instance for the type name of the
   93        * specified class object. This is a convenience method for 
   94        * <code>getJavaType(clazz.getName())</code>. The major difference
   95        * between this method and getJavaType taking a type name is that this 
   96        * method is supposed to return a non-<code>null<code> value. The
   97        * specified class object describes an existing type.
   98        * @param clazz the Class instance representing the type
   99        * @return a JavaType instance for the name of the specified class
  100        * object.
  101        */
  102       public JavaType getJavaType(Class clazz)
  103       {
  104           if (clazz == null)
  105               return null;
  106           
  107           return getJavaTypeInternal(clazz);
  108       }
  109   
  110       /**
  111        * Finds a resource with a given name. A resource is some data that can
  112        * be accessed by class code in a way that is independent of the
  113        * location of the code. The name of a resource is a "/"-separated path
  114        * name that identifies the resource. The method method opens the
  115        * resource for reading and returns an InputStream. It returns 
  116        * <code>null</code> if no resource with this name is found or if the
  117        * caller doesn't have adequate privileges to get the resource.  
  118        * <p>
  119        * This implementation delegates the request to the wrapped
  120        * ClassLoader. 
  121        * @param resourceName the resource name
  122        * @return an input stream for reading the resource, or <code>null</code> 
  123        * if the resource could not be found or if the caller doesn't have
  124        * adequate privileges to get the resource. 
  125        */
  126       public InputStream getInputStreamForResource(final String resourceName)
  127       {
  128           return (InputStream) AccessController.doPrivileged(
  129               new PrivilegedAction () {
  130                   public Object run () {
  131                       ClassLoader loader = (classLoader == null) ?
  132                           ClassLoader.getSystemClassLoader() : classLoader;
  133                       return loader.getResourceAsStream(resourceName);
  134                   }
  135               }
  136               );
  137       }
  138   
  139       /**
  140        * Returns the corresponding JDOModel instance.
  141        * @return the corresponding JDOModel.
  142        */
  143       public JDOModel getJDOModel()
  144       {
  145           if (jdoModel == null) {
  146               JDOModelFactory factory = JDOModelFactoryImplCaching.getInstance();
  147               jdoModel = factory.getJDOModel(this);
  148           }
  149           return jdoModel;
  150       }
  151   
  152       // ===== Methods not defined in JavaModel =====
  153   
  154       /** 
  155        * Returns the ClassLoader wrapped by this ReflectionJavaModel instance.
  156        * @return the ClassLoader
  157        */
  158       public ClassLoader getClassLoader()
  159       {
  160           return classLoader;
  161       }
  162   
  163       /**
  164        * The method returns the JavaType instance for the type name of the
  165        * specified class object. It first checks the cache and if there is no
  166        * entry for the type name in the cache then it creates a new JavaType
  167        * instance for the specified Class object.
  168        * @param clazz the Class instance representing the type
  169        * @return a JavaType instance for the name of the specified class
  170        * object or <code>null</code> if not present in this model instance.
  171        */
  172       public JavaType getJavaTypeInternal(Class clazz)
  173       {
  174           String name = clazz.getName();
  175           synchronized (types) {
  176               JavaType javaType = (JavaType)types.get(name);
  177               if (javaType == null) {
  178                   javaType = newJavaTypeInstance(clazz);
  179                   types.put(name, javaType);
  180               }
  181               return javaType;
  182           }
  183       }
  184   
  185       /**
  186        * Returns the declaring ReflectionJavaModelFactory of this
  187        * ReflectionJavaModel.
  188        * @return the declaring ReflectionJavaModelFactory
  189        */
  190       public ReflectionJavaModelFactory getDeclaringJavaModelFactory()
  191       {
  192           return declaringJavaModelFactory;
  193       }
  194   
  195       /** 
  196        * Creates a new instance of the JavaType implementation class.
  197        * <p>
  198        * This implementation returns a ReflectionJavaType instance.
  199        * @param clazz the Class instance representing the type
  200        * @return a new JavaType instance
  201        */
  202       protected JavaType newJavaTypeInstance(Class clazz)
  203       {
  204           return new ReflectionJavaType(clazz, this);
  205       }
  206       
  207   }

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