/* * Copyright 2007 Joachim Grueneis * * 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.exolab.castor.xml.util.resolvers; import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.castor.xml.AbstractInternalContext; import org.exolab.castor.mapping.ClassDescriptor; import org.exolab.castor.xml.ResolverException; import org.exolab.castor.xml.XMLClassDescriptor; import org.exolab.castor.xml.util.ResolverStrategy; /** * The Castor XML resolver strategy implements the resolving behaviour as it had * been implmented before this refactoring step. Meaning that:<br/> It uses * multiple steps to find a class descriptor for a class.<br/> It uses a cache * of class descriptors<br/> A class that couldn't be resolved once is marked * as unresolvable and will not be resolved again - even on a second call.<br/> * * @author <a href="mailto:jgrueneis AT gmail DOT com">Joachim Grueneis</a> * @author <a href="mailto:stevendolg AT gxm DOT at">Steven Dolg</a> * @version $Revision$ $Date$ * @since 1.2 */ public class CastorXMLStrategy implements ResolverStrategy { /** Logger to be used. */ private static final Log LOG = LogFactory.getLog(CastorXMLStrategy.class); /** The strategy configuration held as map of properties. */ private Map _properties; /** * CastorXMLStrategy requires a configuration to be set. Within the constructor the * commands building the strategy are instantiated, a command configuration is created * and the descriptor cache. */ public CastorXMLStrategy() { _properties = new HashMap(); } //-- CastorXmlStrategy() /** * {@inheritDoc} */ public void setProperty(final String key, final Object value) { if (_properties == null) { _properties = new HashMap(); } if (LOG.isDebugEnabled()) { LOG.debug("Setting property: " + key + " to value: " + value); } _properties.put(key, value); } //-- setProperty /** * {@inheritDoc} */ public ClassDescriptor resolveClass(final ResolverStrategy.ResolverResults resolverResults, final String className) throws ResolverException { if ((className == null) || ("".equals(className))) { String message = "Class name to resolve must not be null or empty!"; LOG.warn(message); throw new IllegalArgumentException(message); } XMLClassDescriptor descriptor = this.getDescriptor(resolverResults, className); return descriptor; } //-- resolve /** * Gets the XMLClassDescriptor for the class with the given name.<br> * * The descriptor is searched in the following resources are search: * <ul> * <li>The resolver results are checked in the beginning and * after each command executed * <li>The MappingLoader * <li>The package mapping of the package the given class is located in * <li>The CDR file of the package the given class is located in * <li>The class file of the corresponding descriptor class (which is * className + "Descriptor") * </ul> * <br/> * If any of these resources yield an XMLClassDescriptor it is added to the * internal cache and returned as result. * * @param resolverResults The resolver results (a Map of className and XMLClassDescriptor) * @param className The class to get the descriptor for. * @return An <code>XMLClassDescriptor</code> for the given class or * <code>null</code> if no descriptor could be found. * @throws ResolverException in case that resolution failed unexpectedly */ private XMLClassDescriptor getDescriptor(final ResolverStrategy.ResolverResults resolverResults, final String className) throws ResolverException { String packageName = ResolveHelpers.getPackageName(className); XMLClassDescriptor descriptor = resolverResults.getDescriptor(className); if (descriptor != null) { return descriptor; } resolverResults.addAllDescriptors(new ByMappingLoader().resolve(className, _properties)); descriptor = resolverResults.getDescriptor(className); if (descriptor != null) { return descriptor; } this.resolvePackage(resolverResults, packageName); descriptor = resolverResults.getDescriptor(className); if (descriptor != null) { return descriptor; } resolverResults.addAllDescriptors(new ByDescriptorClass().resolve(className, _properties)); descriptor = resolverResults.getDescriptor(className); if (descriptor != null) { return descriptor; } resolverResults.addAllDescriptors(new ByIntrospection().resolve(className, _properties)); descriptor = resolverResults.getDescriptor(className); if (descriptor != null) { return descriptor; } // none of the commands have found a match - return null resolverResults.addDescriptor(className, null); return null; } //-- getDescriptor /** * {@inheritDoc} */ public void resolvePackage(final ResolverResults resolverResults, final String packageName) throws ResolverException { resolverResults.addAllDescriptors(new ByCDR().resolve(packageName, _properties)); resolverResults.addAllDescriptors(new ByPackageMapping().resolve(packageName, _properties)); } }