/* * Copyright 2008 Sebastian Gabmeyer * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.castor.cpa.util.classresolution.command; import java.io.IOException; import java.net.URL; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.castor.core.constants.cpa.JDOConstants; import org.castor.cpa.util.classresolution.nature.ClassLoaderNature; import org.castor.cpa.util.classresolution.nature.PackageBasedCDRResolutionNature; import org.exolab.castor.mapping.ClassDescriptor; import org.exolab.castor.xml.util.resolvers.ResolveHelpers; /** * This class tries to resolve a {@link ClassDescriptor} from a package that * contains a {@link JDOConstants#PKG_CDR_LIST_FILE} file. This file defines the * mapping between a domain class and its corresponding * <code>ClassDescriptor</code>. * * @author Sebastian Gabmeyer * @version 1.2.1 */ public class ClassResolutionByCDR extends BaseResolutionCommand { /** The Logger instance to use. */ private static final Log LOG = LogFactory .getLog(ClassResolutionByCDR.class); /** * Constructor. */ public ClassResolutionByCDR() { addNature(ClassLoaderNature.class.getName()); addNature(PackageBasedCDRResolutionNature.class.getName()); } /** * Resolves a <code>type</code> to a {@link ClassDescriptor} by looking for * a {@link JDOConstants#PKG_CDR_LIST_FILE} file in the root directory. * * @param type * the <code>class</code> to obtain the * <code>ClassDescriptor</code> for. * @return the {@link ClassDescriptor} if found, <code>null</code> * otherwise. */ public ClassDescriptor resolve(final Class type) { List<String> packages = new PackageBasedCDRResolutionNature(this) .getPackageNames(); if (packages == null) { if (LOG.isDebugEnabled()) { LOG .debug("No package names to search descriptors in were passed." + " No descriptors will be loaded!"); } return null; } String typeName = type.getName(); for (Iterator<String> it = packages.iterator(); it.hasNext(); ) { Map<String, ClassDescriptor> descriptors = getDescriptors(it.next()); if (descriptors.containsKey(typeName)) { return descriptors.get(typeName); } // TODO remove this following code if above implementation is // sufficient in regard to performance. // String packageName = (String) it.next(); // URL cdrUrl = loader.getResource( // ResolveHelpers // .getQualifiedFileName(JDOConstants.PKG_CDR_LIST_FILE, // packageName)); // try { // Properties cdrList = getProperties(cdrUrl); // Enumeration classes = cdrList.keys(); // for ( ; classes.hasMoreElements(); ) { // String className = (String) classes.nextElement(); // if (className.equals(typeName)) { // String classDescriptorName = cdrList.getProperty(className); // Class classDescriptor = // ResolveHelpers.loadClass(loader, classDescriptorName); // if (classDescriptor != null) { // return (ClassDescriptor) classDescriptor.newInstance(); // } // } // } // } catch (Exception e) { // String message = "Failed to load package: " + packageName + // "with exception: " + e; // LOG.warn(message); // ResolverException resolverException = // (ResolverException) new ResolverException(message).initCause(e); // throw resolverException; // } } return null; } /** * Loads {@link Properties} from the specified <code>URL</code>. * * @param url * the location where the properties are located. * @return the loaded properties. * @throws IOException * if an IOException occurs. */ private Properties getProperties(final URL url) throws IOException { Properties properties = new Properties(); java.io.InputStream stream = url.openStream(); properties.load(stream); stream.close(); return properties; } /** * Get all descriptors from the package defined by the * <code>packageName</code> that contains the * {@link JDOConstants#PKG_CDR_LIST_FILE} file. * * @param packageName * the package to search descriptors for. * @return a {@link java.util.List} of descriptors contained in the package. */ public Map<String, ClassDescriptor> getDescriptors(final String packageName) { Map<String, ClassDescriptor> descriptors = new HashMap<String, ClassDescriptor>(); ClassLoader loader = new ClassLoaderNature(this).getClassLoader(); URL cdrUrl = loader.getResource(ResolveHelpers.getQualifiedFileName( JDOConstants.PKG_CDR_LIST_FILE, packageName)); Properties cdrList = new Properties(); try { cdrList = getProperties(cdrUrl); Enumeration classes = cdrList.keys(); for (; classes.hasMoreElements(); ) { String className = (String) classes.nextElement(); String classDescriptorName = cdrList.getProperty(className); Class classDescriptor = ResolveHelpers.loadClass(loader, classDescriptorName); if (classDescriptor != null) { ClassDescriptor descriptorInstance = (ClassDescriptor) classDescriptor .newInstance(); descriptors.put(className, descriptorInstance); } } } catch (Exception e) { String message = "Failure occured while loading classes from packacge \"" + packageName + "\" with exception: " + e; LOG.warn(message); throw new RuntimeException(e.getMessage()); } return descriptors; } }