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.net.URL;
17  import java.util.ArrayList;
18  import java.util.HashMap;
19  import java.util.List;
20  import java.util.Map;
21  
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  import org.castor.mapping.BindingType;
25  import org.castor.mapping.MappingUnmarshaller;
26  import org.exolab.castor.mapping.ClassDescriptor;
27  import org.exolab.castor.mapping.Mapping;
28  import org.exolab.castor.mapping.MappingException;
29  import org.exolab.castor.mapping.MappingLoader;
30  import org.exolab.castor.xml.ResolverException;
31  import org.exolab.castor.xml.XMLConstants;
32  
33  /**
34   * Tries to load the package mapping file for the given package. <br/>
35   * If the mapping file is available and could be loaded properly the descriptors listed in it are
36   * added to the description class cache of the configuration. <br/>
37   * To disable loading of pacakge mapping files just don't use this command. <br/>
38   * If a mapping file is not available for the given package this method will not load any
39   * descriptors and not throw any exceptions.<br/>
40   * The class loader specified in the configuration is used. <br/>
41   * The mapping file - if available - is loaded using the <code>MappingLoader</code>.<br/>
42   * <br/>
43   * Further calls to this command with the same package name will not be processed.
44   * 
45   * @author <a href="mailto:jgrueneis AT gmail DOT com">Joachim Grueneis</a>
46   * @author <a href="mailto:stevendolg AT gxm DOT at">Steven Dolg</a>
47   * @version $Revision$ $Date$
48   * @since 1.2
49   */
50  public class ByPackageMapping extends AbstractResolverPackageCommand {
51    private static final Log LOG = LogFactory.getLog(ByPackageMapping.class);
52  
53    private List<String> _loadedPackages = new ArrayList<String>();
54  
55    /**
56     * No specific stuff needed.
57     */
58    public ByPackageMapping() {
59      super();
60    }
61  
62    /**
63     * Loads a package mapping file for the given package name using the provided ClassLoader.
64     *
65     * @param packageName The name of the package to load the mapping file for.
66     * @return The loaded Mapping or <code>null</code> if no mapping file is available for the given
67     *         package.
68     * @throws MappingException
69     */
70    private Mapping loadMapping(final String packageName, final ClassLoader classLoader)
71        throws MappingException {
72      URL url = classLoader.getResource(
73          ResolveHelpers.getQualifiedFileName(XMLConstants.PKG_MAPPING_FILE, packageName));
74      if (url == null) {
75        return null;
76      }
77      try {
78        Mapping mapping = new Mapping(classLoader);
79        mapping.loadMapping(url);
80        return mapping;
81      } catch (java.io.IOException ioex) {
82        throw new MappingException(ioex);
83      }
84    }
85  
86    /**
87     * {@inheritDoc}
88     */
89    protected Map<String, ClassDescriptor> internalResolve(final String packageName,
90        final ClassLoader classLoader, final Map properties) throws ResolverException {
91  
92      Map<String, ClassDescriptor> results = new HashMap<String, ClassDescriptor>();
93      if (!isEmptyPackageName(packageName) && _loadedPackages.contains(packageName)) {
94        if (LOG.isDebugEnabled()) {
95          LOG.debug("Package: " + packageName + " has already been loaded.");
96        }
97        return results;
98      }
99  
100     if (!isEmptyPackageName(packageName)) {
101       _loadedPackages.add(packageName);
102     }
103     try {
104       final Mapping mapping = this.loadMapping(packageName, classLoader);
105       if (mapping != null) {
106         MappingUnmarshaller unmarshaller = new MappingUnmarshaller();
107         // TODO: Joachim 2007-09-07 the InternalContext should be set into the unmarshaller!
108         MappingLoader mappingLoader = unmarshaller.getMappingLoader(mapping, BindingType.XML);
109         for (ClassDescriptor classDescriptor : mappingLoader.getDescriptors()) {
110           if (LOG.isDebugEnabled()) {
111             LOG.debug("Found descriptor: " + classDescriptor);
112           }
113           results.put(classDescriptor.getJavaClass().getName(), classDescriptor);
114         }
115       }
116     } catch (MappingException e) {
117       if (LOG.isDebugEnabled()) {
118         LOG.debug("Ignored exception: " + e + " while loading mapping for package: " + packageName);
119       }
120     }
121     return results;
122   }
123 }