View Javadoc

1   package net.sourceforge.jparam.conversion.converters;
2   
3   import java.util.HashSet;
4   import java.util.Iterator;
5   import java.util.Set;
6   
7   import net.sourceforge.jparam.JParam;
8   import net.sourceforge.jparam.JParamException;
9   import net.sourceforge.jparam.typename.TypeNameRegistry;
10  import net.sourceforge.jparam.util.Utils;
11  
12  /***
13   * @author Ron_Sidi
14   *
15   * A converter representing an ambigous conversion, it should hold all possible
16   * conversions from the source to the target using the same weight
17   */
18  public class AmbigousConverter extends AbstractConverter {
19  
20  	private Set converters = new HashSet();
21  
22  	AmbigousConverter(Set converters) {
23  		this.converters = converters;
24  		IConverter conv = (IConverter) converters.iterator().next();
25  		this.conversionWeight = conv.getWeight();
26  		this.sourceClass = conv.getSourceClass();
27  		this.targetClass = conv.getTargetClass();
28  	}
29  
30  	protected Object internalConvert(Object o) throws Exception {
31  		StringBuffer message = new StringBuffer();
32  		try {
33  			String sourceName = TypeNameRegistry.getInstance()
34  					.getJParamTypeName(sourceClass);
35  			String targetName = TypeNameRegistry.getInstance()
36  					.getJParamTypeName(targetClass);
37  
38  			message.append("More than one conversion path found from ");
39  			message.append(sourceName);
40  			message.append(" ( ");
41  			try {
42  				message.append(JParam.toString(o));
43  			} catch (Exception e) {
44  				message.append(o);
45  			}
46  			message.append(" ) to ");
47  			message.append(targetName);
48  			message.append(":");
49  
50  			for (Iterator iter = converters.iterator(); iter.hasNext();) {
51  				IConverter converter = (IConverter) iter.next();
52  				message.append("\n\t");
53  				message.append(converter.toConversionString());
54  			}
55  			message.append("\n");
56  		} catch (Exception e) {
57  			message
58  					.append("This conversion is ambigous, all possible conversions: "
59  							+ converters
60  							+ " error generating correct error: "
61  							+ e);
62  		}
63  
64  		throw new JParamException(message.toString());
65  	}
66  
67  	public static IConverter createConverter(IConverter first, IConverter second) {
68  		Utils.assert(
69  				first.getSourceClass().equals(second.getSourceClass()) && first.getTargetClass().equals(second.getTargetClass()),
70  				"Cannot create ambiguity between non-compatible converters");
71  		Utils
72  				.assert(first.getWeight().equals(
73  						second.getWeight()),
74  						"Cannot create ambiuity between non-similar weighted converters");
75  
76  		Set converters = new HashSet();
77  		if (first instanceof AmbigousConverter) {
78  			converters.addAll(((AmbigousConverter) first).converters);
79  		} else {
80  			converters.add(first);
81  		}
82  
83  		if (second instanceof AmbigousConverter) {
84  			converters.addAll(((AmbigousConverter) second).converters);
85  		} else {
86  			converters.add(second);
87  		}
88  
89  		return new AmbigousConverter(converters);
90  	}
91  
92  	IConverter[] getConverters() {
93  		return (IConverter[]) converters.toArray(new IConverter[converters
94  				.size()]);
95  	}
96  
97  	protected boolean converterEquals(IConverter o) {
98  		AmbigousConverter other = (AmbigousConverter) o;
99  		if (converters.size() != other.converters.size()) {
100 			return false;
101 		}
102 
103 		Iterator myIter = converters.iterator();
104 		Iterator otherIter = other.converters.iterator();
105 		for (; myIter.hasNext() && otherIter.hasNext();) {
106 			IConverter myConverter = (IConverter) myIter.next();
107 			IConverter otherConverter = (IConverter) otherIter.next();
108 
109 			if (!myConverter.equals(otherConverter)) {
110 				return false;
111 			}
112 		}
113 
114 		return true;
115 	}
116 
117 	public String toConversionString() {
118 		StringBuffer result = new StringBuffer("AMBIGOUS(");
119 
120 		for (Iterator iter = converters.iterator(); iter.hasNext();) {
121 			IConverter converter = (IConverter) iter.next();
122 			result.append(converter.toConversionString());
123 			if (iter.hasNext()) {
124 				result.append("; ");
125 			}
126 		}
127 
128 		result.append(")");
129 		return result.toString();
130 	}
131 
132 	public IConverter update(IConverter updatedConverter) {
133 		Set newConverters = new HashSet();
134 
135 		boolean converterUpdated = false;
136 		for (Iterator iter = converters.iterator(); iter.hasNext();) {
137 			IConverter converter = (IConverter) iter.next();
138 			IConverter newConverter = converter.update(updatedConverter);
139 			if (newConverter != converter) {
140 				converterUpdated = true;
141 			}
142 			newConverters.add(converter.update(updatedConverter));
143 		}
144 
145 		if (converterUpdated) {
146 			if (newConverters.size() > 1) {
147 				return new AmbigousConverter(newConverters);
148 			}
149 
150 			return (IConverter) newConverters.iterator().next();
151 		}
152 
153 		return this;
154 	}
155 }