001: /*
002: * Copyright 2004-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.springframework.binding.convert.support;
017:
018: import java.util.Arrays;
019: import java.util.HashSet;
020: import java.util.Set;
021:
022: import org.springframework.binding.convert.ConversionException;
023: import org.springframework.binding.convert.ConversionExecutor;
024: import org.springframework.binding.convert.ConversionService;
025: import org.springframework.util.Assert;
026:
027: /**
028: * A conversion service that delegates to an ordered chain of other conversion
029: * services. The first correct reply received from a conversion service in
030: * the chain is returned to the caller.
031: *
032: * @author Erwin Vervaet
033: */
034: public class CompositeConversionService implements ConversionService {
035:
036: private ConversionService[] chain;
037:
038: /**
039: * Create a new composite conversion service.
040: * @param conversionServices the conversion services in the chain
041: */
042: public CompositeConversionService(
043: ConversionService[] conversionServices) {
044: Assert.notNull(conversionServices,
045: "The conversion services chain is required");
046: this .chain = conversionServices;
047: }
048:
049: /**
050: * Returns the conversion services in the chain managed by this
051: * composite conversion service.
052: */
053: public ConversionService[] getConversionServices() {
054: return chain;
055: }
056:
057: public ConversionExecutor getConversionExecutor(Class sourceClass,
058: Class targetClass) throws ConversionException {
059: for (int i = 0; i < chain.length; i++) {
060: try {
061: return chain[i].getConversionExecutor(sourceClass,
062: targetClass);
063: } catch (ConversionException e) {
064: // ignore and try the next conversion service in the chain
065: }
066: }
067: throw new ConversionException(sourceClass, targetClass,
068: "No converter registered to convert from sourceClass '"
069: + sourceClass + "' to target class '"
070: + targetClass + "'");
071: }
072:
073: public ConversionExecutor getConversionExecutorByTargetAlias(
074: Class sourceClass, String targetAlias)
075: throws ConversionException {
076: boolean exceptionThrown = false;
077: for (int i = 0; i < chain.length; i++) {
078: try {
079: ConversionExecutor res = chain[i]
080: .getConversionExecutorByTargetAlias(
081: sourceClass, targetAlias);
082: if (res != null) {
083: return res;
084: }
085: } catch (ConversionException e) {
086: exceptionThrown = true;
087: }
088: }
089: if (exceptionThrown) {
090: throw new ConversionException(sourceClass,
091: "No converter registered to convert from sourceClass '"
092: + sourceClass
093: + "' to aliased target type '"
094: + targetAlias + "'");
095: } else {
096: // alias was not recognized by any conversion service in the chain
097: return null;
098: }
099: }
100:
101: public ConversionExecutor[] getConversionExecutorsForSource(
102: Class sourceClass) throws ConversionException {
103: Set executors = new HashSet();
104: for (int i = 0; i < chain.length; i++) {
105: executors.addAll(Arrays.asList(chain[i]
106: .getConversionExecutorsForSource(sourceClass)));
107: }
108: return (ConversionExecutor[]) executors
109: .toArray(new ConversionExecutor[executors.size()]);
110: }
111:
112: public Class getClassByAlias(String alias)
113: throws ConversionException {
114: for (int i = 0; i < chain.length; i++) {
115: try {
116: Class res = chain[i].getClassByAlias(alias);
117: if (res != null) {
118: return res;
119: }
120: } catch (ConversionException e) {
121: // ignore and try the next conversion service in the chain
122: }
123: }
124: return null;
125: }
126: }
|