View Javadoc

1   package net.sourceforge.jparam.conversion.converters;
2   
3   import java.util.Arrays;
4   import java.util.HashSet;
5   import java.util.LinkedList;
6   import java.util.List;
7   import java.util.Set;
8   
9   import net.sourceforge.jparam.JParamException;
10  import net.sourceforge.jparam.conversion.weights.ScalarConversionWeight;
11  import net.sourceforge.jparam.typename.TypeNameRegistry;
12  import net.sourceforge.jparam.util.Utils;
13  
14  public class PathConverter extends AbstractConverter {
15  	IConverter[] path;
16  
17  	/***
18  	 * @param path
19  	 */
20  	public PathConverter(IConverter[] path) {
21  		setPath(path);
22  		conversionWeight = path[0].getWeight();
23  
24  		for (int i = 1; i < path.length; i++) {
25  			conversionWeight = new ScalarConversionWeight(conversionWeight,
26  					path[i].getWeight());
27  		}
28  	}
29  
30  	private PathConverter(IConverter first, IConverter second) {
31  		List localPath = new LinkedList();
32  		if (first instanceof PathConverter) {
33  			PathConverter firstPath = (PathConverter) first;
34  			for (int i = 0; i < firstPath.path.length; i++) {
35  				localPath.add(firstPath.path[i]);
36  			}
37  		} else {
38  			localPath.add(first);
39  		}
40  
41  		if (second instanceof PathConverter) {
42  			PathConverter secondPath = (PathConverter) second;
43  			for (int i = 0; i < secondPath.path.length; i++) {
44  				localPath.add(secondPath.path[i]);
45  			}
46  		} else {
47  			localPath.add(second);
48  		}
49  
50  		setPath((IConverter[]) localPath.toArray(new IConverter[localPath
51  				.size()]));
52  		conversionWeight = new ScalarConversionWeight(first
53  				.getWeight(), second.getWeight());
54  	}
55  
56  	private void setPath(IConverter[] path) {
57  		this.path = path;
58  		this.sourceClass = path[0].getSourceClass();
59  		this.targetClass = path[path.length - 1].getTargetClass();
60  	}
61  
62  	public boolean equals(Object o) {
63  		if (!o.getClass().equals(PathConverter.class)) {
64  			return false;
65  		}
66  
67  		PathConverter other = (PathConverter) o;
68  
69  		return Arrays.equals(other.path, path)
70  				&& conversionWeight.equals(other.conversionWeight);
71  	}
72  
73  	public Object internalConvert(Object o) throws JParamException {
74  		for (int i = 0; i < path.length; i++) {
75  			o = path[i].convert(o);
76  		}
77  
78  		return o;
79  	}
80  
81  	public static IConverter createConversionPath(IConverter first,
82  			IConverter second) {
83  		IConverter[] firstConverters;
84  		IConverter[] secondConverters;
85  
86  		if (first instanceof AmbigousConverter) {
87  			firstConverters = ((AmbigousConverter) first).getConverters();
88  		} else {
89  			firstConverters = new IConverter[] { first };
90  		}
91  
92  		if (second instanceof AmbigousConverter) {
93  			secondConverters = ((AmbigousConverter) second).getConverters();
94  		} else {
95  			secondConverters = new IConverter[] { second };
96  		}
97  
98  		if ((firstConverters.length > 1) || (secondConverters.length > 1)) {
99  			Set converters = new HashSet();
100 			for (int i = 0; i < firstConverters.length; i++) {
101 				for (int j = 0; j < secondConverters.length; j++) {
102 					converters.add(new PathConverter(firstConverters[i],
103 							secondConverters[j]));
104 				}
105 			}
106 			return new AmbigousConverter(converters);
107 		}
108 
109 		return new PathConverter(first, second);
110 	}
111 
112 	protected boolean converterEquals(IConverter o) {
113 		PathConverter other = (PathConverter) o;
114 
115 		return Arrays.equals(path, other.path);
116 	}
117 
118 	public String toConversionString() {
119 		StringBuffer result = new StringBuffer();
120 
121 		try {
122 			result.append(TypeNameRegistry.getInstance().getJParamTypeName(
123 					sourceClass));
124 		} catch (JParamException e) {
125 			result.append(sourceClass.getName());
126 		}
127 
128 		for (int i = 0; i < path.length; i++) {
129 			result.append(" -> ");
130 			try {
131 				result.append(TypeNameRegistry.getInstance().getJParamTypeName(
132 						path[i].getTargetClass()));
133 			} catch (JParamException e) {
134 				result.append(path[i].getTargetClass().getName());
135 			}
136 		}
137 
138 		return result.toString();
139 	}
140 
141 	public IConverter update(IConverter updatedConverter) {
142 		IConverter retConverter = this;
143 
144 		if (Utils.isDebugEnabled(this)) {
145 			System.err.println("Updating " + this + " with: "
146 					+ updatedConverter);
147 		}
148 
149 		List prefix = new LinkedList();
150 
151 		Class updatedSource = updatedConverter.getSourceClass();
152 		Class updatedTarget = updatedConverter.getSourceClass();
153 
154 		int sourceIndex = 0;
155 		for (; sourceIndex < path.length; sourceIndex++) {
156 			IConverter curStep = path[sourceIndex];
157 			if (updatedSource.equals(curStep.getSourceClass())) {
158 				break;
159 			}
160 			prefix.add(curStep);
161 		}
162 
163 		if (sourceIndex < path.length) {
164 			List postfix = new LinkedList();
165 			int targetIndex = sourceIndex + 1;
166 			for (; targetIndex < path.length; targetIndex++) {
167 				IConverter curStep = path[targetIndex];
168 				if (updatedTarget.equals(curStep.getTargetClass())) {
169 					break;
170 				}
171 				postfix.add(curStep);
172 			}
173 
174 			if (targetIndex < path.length) {
175 				IConverter preConverter = null;
176 				IConverter postConverter = null;
177 
178 				if (prefix.size() > 0) {
179 					preConverter = new PathConverter((IConverter[]) prefix
180 							.toArray(new IConverter[prefix.size()]));
181 				}
182 
183 				if (postfix.size() > 0) {
184 					postConverter = new PathConverter((IConverter[]) postfix
185 							.toArray(new IConverter[postfix.size()]));
186 				}
187 
188 				IConverter secondHalf;
189 				if (postConverter != null) {
190 					secondHalf = createConversionPath(updatedConverter,
191 							postConverter);
192 				} else {
193 					secondHalf = updatedConverter;
194 				}
195 
196 				if (preConverter != null) {
197 					retConverter = createConversionPath(preConverter,
198 							secondHalf);
199 				} else {
200 					retConverter = createConversionPath(updatedConverter,
201 							secondHalf);
202 				}
203 			}
204 		}
205 
206 		if (Utils.isDebugEnabled(this)) {
207 			if (retConverter != this) {
208 				System.err.println("Converter updated, new converter: "
209 						+ retConverter);
210 			} else {
211 				System.err.println("No change");
212 			}
213 		}
214 		return this;
215 	}
216 }