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 }