Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2004-2008 the original author or authors.
   * 
   * 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.springframework.binding.convert.service;
 
 import java.util.Map;
 import java.util.Set;
 
Base implementation of a conversion service. Initially empty, e.g. no converters are registered by default.

Author(s):
Keith Donald
 
 public class GenericConversionService implements ConversionService {

An indexed map of converters. Each entry key is a source class that can be converted from, and each entry value is a map of target classes that can be converted to, ultimately mapping to a specific converter that can perform the source->target conversion.
 
 	private final Map sourceClassConverters = new HashMap();

A map of custom converters. Custom converters are assigned a unique identifier that can be used to lookup the converter. This allows multiple converters for the same source->target class to be registered.
 
 	private final Map customConverters = new HashMap();

Indexes classes by well-known aliases.
 
 	private final Map aliasMap = new HashMap();

An optional parent conversion service.
 
Returns the parent of this conversion service. Could be null.
 
 		return ;
 	}

Set the parent of this conversion service. This is optional.
 
 	public void setParent(ConversionService parent) {
 		this. = parent;
 	}

Add given converter to this conversion service.

Parameters:
converter the converter
 
 	public void addConverter(Converter converter) {
 		Class sourceClass = converter.getSourceClass();
 		Class targetClass = converter.getTargetClass();
 		Map sourceMap = getSourceMap(sourceClass);
 		sourceMap.put(targetClassconverter);
 		if (converter instanceof TwoWayConverter) {
 			sourceMap = getSourceMap(targetClass);
 			sourceMap.put(sourceClassnew ReverseConverter((TwoWayConverterconverter));
 		}
 	}

Add given custom converter to this conversion service.

Parameters:
id the id of the custom converter instance
converter the converter
	public void addConverter(String idConverter converter) {
		.put(idconverter);
	}

Add an alias for given target type.
	public void addAlias(String aliasClass targetType) {
		.put(aliastargetType);
	}
	private Map getSourceMap(Class sourceClass) {
		Map sourceMap = (Map.get(sourceClass);
		if (sourceMap == null) {
			sourceMap = new HashMap();
			.put(sourceClasssourceMap);
		}
		return sourceMap;
	}
	public ConversionExecutor getConversionExecutor(Class sourceClassClass targetClass)
		Assert.notNull(sourceClass"The source class to convert from is required");
		Assert.notNull(targetClass"The target class to convert to is required");
		sourceClass = convertToWrapperClassIfNecessary(sourceClass);
		targetClass = convertToWrapperClassIfNecessary(targetClass);
		if (targetClass.isAssignableFrom(sourceClass)) {
			return new StaticConversionExecutor(sourceClasstargetClassnew NoOpConverter(sourceClasstargetClass));
		}
		if (sourceClass.isArray()) {
			if (targetClass.isArray()) {
				return new StaticConversionExecutor(sourceClasstargetClassnew ArrayToArray(this));
else if (Collection.class.isAssignableFrom(targetClass)) {
				if (!targetClass.isInterface() && Modifier.isAbstract(targetClass.getModifiers())) {
					throw new IllegalArgumentException("Conversion target class [" + targetClass.getName()
"] is invalid; cannot convert to abstract collection types--"
"request an interface or concrete implementation instead");
				}
				return new StaticConversionExecutor(sourceClasstargetClassnew ArrayToCollection(this));
			}
		}
		if (targetClass.isArray()) {
			if (Collection.class.isAssignableFrom(sourceClass)) {
				Converter collectionToArray = new ReverseConverter(new ArrayToCollection(this));
				return new StaticConversionExecutor(sourceClasstargetClasscollectionToArray);
else {
				return new StaticConversionExecutor(sourceClasstargetClassnew ObjectToArray(this));
			}
		}
		Converter converter = findRegisteredConverter(sourceClasstargetClass);
		if (converter != null) {
			// we found a converter
			return new StaticConversionExecutor(sourceClasstargetClassconverter);
else {
			if ( != null) {
				// try the parent
				return .getConversionExecutor(sourceClasstargetClass);
else {
				throw new ConversionExecutorNotFoundException(sourceClasstargetClass,
						"No ConversionExecutor found for converting from sourceClass [" + sourceClass.getName()
"] to target class [" + targetClass.getName() + "]");
			}
		}
	}
	public ConversionExecutor getConversionExecutor(String idClass sourceClassClass targetClass)
		Assert.hasText(id"The id of the custom converter is required");
		Assert.notNull(sourceClass"The source class to convert from is required");
		Assert.notNull(targetClass"The target class to convert to is required");
		Converter converter = (Converter.get(id);
		if (converter == null) {
			if ( != null) {
				return .getConversionExecutor(idsourceClasstargetClass);
else {
				throw new ConversionExecutorNotFoundException(sourceClasstargetClass,
						"No custom ConversionExecutor found with id '" + id + "' for converting from sourceClass ["
sourceClass.getName() + "] to targetClass [" + targetClass.getName() + "]");
			}
		}
		sourceClass = convertToWrapperClassIfNecessary(sourceClass);
		targetClass = convertToWrapperClassIfNecessary(targetClass);
		if (converter.getSourceClass().isAssignableFrom(sourceClass)) {
			if (!converter.getTargetClass().isAssignableFrom(targetClass)) {
				throw new ConversionExecutorNotFoundException(sourceClasstargetClass,
						"Custom ConversionExecutor with id '" + id + "' cannot convert from sourceClass ["
sourceClass.getName() + "] to targetClass [" + targetClass.getName() + "]");
			}
			return new StaticConversionExecutor(sourceClasstargetClassconverter);
else if (converter.getTargetClass().isAssignableFrom(sourceClass) && converter instanceof TwoWayConverter) {
			if (!converter.getSourceClass().isAssignableFrom(targetClass)) {
				throw new ConversionExecutorNotFoundException(sourceClasstargetClass,
						"Custom ConversionExecutor with id '" + id + "' cannot convert from sourceClass ["
sourceClass.getName() + "] to targetClass [" + targetClass.getName() + "]");
			}
			TwoWayConverter twoWay = (TwoWayConverterconverter;
			return new StaticConversionExecutor(sourceClasstargetClassnew ReverseConverter(twoWay));
else {
			throw new ConversionExecutorNotFoundException(sourceClasstargetClass,
					"Custom ConversionExecutor with id '" + id + "' cannot convert from sourceClass ["
sourceClass.getName() + "] to targetClass [" + targetClass.getName() + "]");
		}
	}
	private Converter findRegisteredConverter(Class sourceClassClass targetClass) {
		if (sourceClass.isInterface()) {
			LinkedList classQueue = new LinkedList();
			classQueue.addFirst(sourceClass);
			while (!classQueue.isEmpty()) {
				Class currentClass = (ClassclassQueue.removeLast();
				Map sourceTargetConverters = findConvertersForSource(currentClass);
				Converter converter = findTargetConverter(sourceTargetConverterstargetClass);
				if (converter != null) {
					return converter;
				}
				Class[] interfaces = currentClass.getInterfaces();
				for (int i = 0; i < interfaces.lengthi++) {
					classQueue.addFirst(interfaces[i]);
				}
			}
			Map objectConverters = findConvertersForSource(Object.class);
			return findTargetConverter(objectConverterstargetClass);
else {
			LinkedList classQueue = new LinkedList();
			classQueue.addFirst(sourceClass);
			while (!classQueue.isEmpty()) {
				Class currentClass = (ClassclassQueue.removeLast();
				Map sourceTargetConverters = findConvertersForSource(currentClass);
				Converter converter = findTargetConverter(sourceTargetConverterstargetClass);
				if (converter != null) {
					return converter;
				}
				if (currentClass.getSuperclass() != null) {
					classQueue.addFirst(currentClass.getSuperclass());
				}
				Class[] interfaces = currentClass.getInterfaces();
				for (int i = 0; i < interfaces.lengthi++) {
					classQueue.addFirst(interfaces[i]);
				}
			}
			return null;
		}
	}
	public Object executeConversion(Object sourceClass targetClassthrows ConversionException {
		if (source != null) {
			ConversionExecutor conversionExecutor = getConversionExecutor(source.getClass(), targetClass);
			return conversionExecutor.execute(source);
else {
			return null;
		}
	}
		Class clazz = (Class.get(name);
		if (clazz != null) {
			return clazz;
else {
			if ( != null) {
				return .getClassForAlias(name);
else {
				return null;
			}
		}
	}
	// subclassing support
	public Set getConversionExecutors(Class sourceClass) {
		Set parentExecutors;
		if ( != null) {
			parentExecutors = .getConversionExecutors(sourceClass);
else {
			parentExecutors = .;
		}
		Map sourceMap = getSourceMap(sourceClass);
		if (parentExecutors.isEmpty() && sourceMap.isEmpty()) {
		}
		Set entries = sourceMap.entrySet();
		Set conversionExecutors = new HashSet(entries.size() + parentExecutors.size());
		for (Iterator it = entries.iterator(); it.hasNext();) {
			Map.Entry entry = (Map.Entryit.next();
			Class targetClass = (Classentry.getKey();
			Converter converter = (Converterentry.getValue();
			conversionExecutors.add(new StaticConversionExecutor(sourceClasstargetClassconverter));
		}
		conversionExecutors.addAll(parentExecutors);
		return conversionExecutors;
	}

Returns an indexed map of converters. Each entry key is a source class that can be converted from, and each entry value is a map of target classes that can be convertered to, ultimately mapping to a specific converter that can perform the source->target conversion.
	}

Returns a registered converter object

Parameters:
sourceClass the source class
targetClass the target class
	protected Converter getConverter(Class sourceClassClass targetClass) {
		Map sourceTargetConverters = findConvertersForSource(sourceClass);
		return findTargetConverter(sourceTargetConverterstargetClass);
	}
	// internal helpers
	private Map findConvertersForSource(Class sourceClass) {
		Map sourceConverters = (Map.get(sourceClass);
		return sourceConverters != null ? sourceConverters : .;
	}
	private Converter findTargetConverter(Map sourceTargetConvertersClass targetClass) {
		if (sourceTargetConverters.isEmpty()) {
			return null;
		}
		if (targetClass.isInterface()) {
			LinkedList classQueue = new LinkedList();
			classQueue.addFirst(targetClass);
			while (!classQueue.isEmpty()) {
				Class currentClass = (ClassclassQueue.removeLast();
				Converter converter = (ConvertersourceTargetConverters.get(currentClass);
				if (converter != null) {
					return converter;
				}
				Class[] interfaces = currentClass.getInterfaces();
				for (int i = 0; i < interfaces.lengthi++) {
					classQueue.addFirst(interfaces[i]);
				}
			}
			return (ConvertersourceTargetConverters.get(Object.class);
else {
			LinkedList classQueue = new LinkedList();
			classQueue.addFirst(targetClass);
			while (!classQueue.isEmpty()) {
				Class currentClass = (ClassclassQueue.removeLast();
				Converter converter = (ConvertersourceTargetConverters.get(currentClass);
				if (converter != null) {
					return converter;
				}
				if (currentClass.getSuperclass() != null) {
					classQueue.addFirst(currentClass.getSuperclass());
				}
				Class[] interfaces = currentClass.getInterfaces();
				for (int i = 0; i < interfaces.lengthi++) {
					classQueue.addFirst(interfaces[i]);
				}
			}
			return null;
		}
	}
		if (targetType.isPrimitive()) {
			if (targetType.equals(int.class)) {
				return Integer.class;
else if (targetType.equals(short.class)) {
				return Short.class;
else if (targetType.equals(long.class)) {
				return Long.class;
else if (targetType.equals(float.class)) {
				return Float.class;
else if (targetType.equals(double.class)) {
				return Double.class;
else if (targetType.equals(byte.class)) {
				return Byte.class;
else if (targetType.equals(boolean.class)) {
				return Boolean.class;
else if (targetType.equals(char.class)) {
				return Character.class;
else {
				throw new IllegalStateException("Should never happen - primitive type is not a primitive?");
			}
else {
			return targetType;
		}
	}
New to GrepCode? Check out our FAQ X