View Javadoc
1   /*
2    * Copyright 2007 Joachim Grueneis
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5    * in compliance with the License. You may obtain a copy of the License at
6    *
7    * http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software distributed under the License
10   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11   * or implied. See the License for the specific language governing permissions and limitations under
12   * the License.
13   */
14  package org.exolab.castor.xml.util.resolvers;
15  
16  import java.util.HashMap;
17  import java.util.Map;
18  
19  import org.apache.commons.logging.Log;
20  import org.apache.commons.logging.LogFactory;
21  import org.exolab.castor.xml.Introspector;
22  import org.exolab.castor.xml.MarshalException;
23  import org.exolab.castor.xml.ResolverException;
24  import org.exolab.castor.xml.XMLClassDescriptor;
25  import org.exolab.castor.xml.util.ResolverStrategy;
26  
27  /**
28   * Resolve a class by creating a generic descriptor based on the informations read from the class
29   * with introspection.
30   * 
31   * @author <a href="mailto:jgrueneis AT gmail DOT com">Joachim Grueneis</a>
32   * @author <a href="mailto:stevendolg AT gxm DOT at">Steven Dolg</a>
33   * @version $Revision$ $Date$
34   * @since 1.2
35   */
36  public class ByIntrospection extends AbstractResolverClassCommand {
37    /**
38     * Logger to be used.
39     */
40    private static final Log LOG = LogFactory.getLog(ByIntrospection.class);
41  
42    /**
43     * No specific stuff needed.
44     */
45    public ByIntrospection() {
46      super();
47    }
48  
49    /**
50     * Creates an XMLClassDescriptor for the given type by using introspection. This method will rely
51     * on the <code>Introspector</code> set with <code>setIntrospector</code>. If a descriptor is
52     * successfully created it will be added to the DescriptorCache. <br>
53     * <b>NOTE</b>: If this XMLClassDescriptorResolver is NOT configured to use introspection this
54     * method will NOT create an descriptor.<br>
55     * <br>
56     * {@inheritDoc}
57     */
58    protected Map internalResolve(final String className, final ClassLoader classLoader,
59        final Map properties) throws ResolverException {
60  
61      Boolean useIntrospector = (Boolean) properties.get(ResolverStrategy.PROPERTY_USE_INTROSPECTION);
62      HashMap results = new HashMap();
63      if (classLoader == null) {
64        LOG.debug("No class loader available.");
65        return results;
66      }
67  
68      if ((useIntrospector != null) && (!useIntrospector.booleanValue())) {
69        // I know the logic is a bit weired... either introspection is explicitly
70        // disabled or it is ok!
71        LOG.debug("Introspection is disabled!");
72        return results;
73      }
74  
75      Introspector introspector =
76          (Introspector) properties.get(ResolverStrategy.PROPERTY_INTROSPECTOR);
77      if (introspector == null) {
78        String message = "No Introspector defined in properties!";
79        LOG.warn(message);
80        throw new IllegalStateException(message);
81      }
82      Class clazz = ResolveHelpers.loadClass(classLoader, className);
83      if (clazz != null) {
84        try {
85          XMLClassDescriptor descriptor = introspector.generateClassDescriptor(clazz);
86          if (descriptor != null) {
87            if (LOG.isDebugEnabled()) {
88              LOG.debug("Found descriptor: " + descriptor);
89            }
90            results.put(clazz.getName(), descriptor);
91          }
92        } catch (MarshalException e) {
93          String message =
94              "Failed to generate class descriptor for: " + clazz + " with exception: " + e;
95          LOG.warn(message);
96          throw new ResolverException(message);
97        }
98      }
99      return results;
100   }
101 }