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.io.IOException;
17  import java.io.InputStream;
18  import java.net.URL;
19  import java.util.ArrayList;
20  import java.util.Enumeration;
21  import java.util.HashMap;
22  import java.util.List;
23  import java.util.Map;
24  import java.util.Properties;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.exolab.castor.mapping.ClassDescriptor;
29  import org.exolab.castor.xml.ResolverException;
30  import org.exolab.castor.xml.XMLConstants;
31  
32  /**
33   * Resolves a class by reading the package level class-descriptor-resolver file and loading all
34   * descriptors mentioned inside.
35   * 
36   * @author <a href="mailto:jgrueneis AT gmail DOT com">Joachim Grueneis</a>
37   * @author <a href="mailto:stevendolg AT gxm DOT at">Steven Dolg</a>
38   * @version $Revision$ $Date$
39   * @since 1.2
40   */
41  public class ByCDR extends AbstractResolverPackageCommand {
42    private static final Log LOG = LogFactory.getLog(ByCDR.class);
43  
44    private List<String> _loadedPackages = new ArrayList<String>();
45  
46    /**
47     * No specific stuff needed.
48     */
49    public ByCDR() {
50      super();
51    }
52  
53    /**
54     * Creates a Properties object and initializes it with the contents of the given URL. The provided
55     * URL must exist and be suitable for loading properties from.
56     *
57     * @param url The URL to load the properties from. This must not be null!
58     * @return The loaded properties.
59     * @throws IOException If loading the properties from the given ULR failed.
60     *
61     * @see Properties
62     * @see Properties#load(InputStream)
63     */
64    private Properties getProperties(URL url) throws java.io.IOException {
65      Properties cdrList = new Properties();
66  
67      java.io.InputStream stream = url.openStream();
68      cdrList.load(stream);
69      stream.close();
70  
71      return cdrList;
72    }
73  
74    /**
75     * Tries to load the CDR file for the given package name using the provided class loader. If the
76     * CDR file is available and could be loaded properly the descriptors listed in it are added to
77     * this cache. <br>
78     * If a descriptor is listed in the CDR file for the given package but could not be loaded (e.g.
79     * because the reference class file is not available) the descriptor is ignored but no exception
80     * is thrown. <br>
81     * If a CDR file is not available for the given package this method will not load any descriptors
82     * and not throw any exceptions. <br>
83     * Further calls to this method with the same package name will not be processed. <br>
84     * {@inheritDoc}
85     */
86    protected Map<String, ClassDescriptor> internalResolve(final String packageName,
87        final ClassLoader classLoader, final Map properties) throws ResolverException {
88  
89      Map<String, ClassDescriptor> results = new HashMap<String, ClassDescriptor>();
90      if (!isEmptyPackageName(packageName) && _loadedPackages.contains(packageName)) {
91        if (LOG.isDebugEnabled()) {
92          LOG.debug("Package: " + packageName + " has already been loaded.");
93        }
94        return results;
95      }
96      if (!isEmptyPackageName(packageName)) {
97        _loadedPackages.add(packageName);
98      }
99  
100     URL url = classLoader.getResource(
101         ResolveHelpers.getQualifiedFileName(XMLConstants.PKG_CDR_LIST_FILE, packageName));
102     if (url == null) {
103       return results;
104     }
105 
106     try {
107       Properties cdrList = this.getProperties(url);
108 
109       for (Object clazz : cdrList.keySet()) {
110         String clazzName = (String) clazz;
111         String descriptorClassName = (String) cdrList.get(clazzName);
112         try {
113           Class<?> descriptorClass = classLoader.loadClass(descriptorClassName);
114           if (LOG.isDebugEnabled()) {
115             LOG.debug("Found descriptor: " + descriptorClass);
116           }
117           if (descriptorClass != null) {
118             ClassDescriptor instance = (ClassDescriptor) descriptorClass.newInstance();
119             results.put(clazzName, instance);
120           } else if (LOG.isDebugEnabled()) {
121             LOG.debug("Loading of descriptor class: " + descriptorClassName + " for class: "
122                 + clazzName + " has failed - continue without");
123           }
124         } catch (Exception e) {
125           if (LOG.isDebugEnabled()) {
126             LOG.debug(
127                 "Ignored problem at loading of: " + descriptorClassName + " with exception: " + e);
128           }
129         }
130       }
131     } catch (IOException iox) {
132       String message = "Failed to load package: " + packageName + " with exception: " + iox;
133       LOG.warn(message);
134       throw new ResolverException(message);
135     }
136     return results;
137   }
138 }