1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package junitx.ddtunit.data.processing;
39
40 import java.util.Collection;
41 import java.util.List;
42 import java.util.Map;
43
44 import junitx.ddtunit.DDTException;
45 import junitx.ddtunit.data.DDTTestDataException;
46 import junitx.ddtunit.data.IDataSet;
47 import junitx.ddtunit.data.TestDataSet;
48 import junitx.ddtunit.data.TypedObject;
49
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53
54
55
56
57
58
59 public class CollectionCreatorAction extends ActionBase {
60 protected Logger log = LoggerFactory.getLogger(CollectionCreatorAction.class);
61 protected int elementCount;
62
63
64
65
66
67
68
69
70 public CollectionCreatorAction(Map<String, String> attrMap) {
71 super(attrMap);
72 this.elementCount = 0;
73 }
74
75
76
77
78
79
80 public IAction process() {
81 log.debug("process CollectionCreator - START");
82 IAction rootAction = getPrevious();
83 if (!this.successorProcessed) {
84 processNoSuccessor();
85 }
86 if (rootAction != null) {
87 String hintValue = rootAction.getHint();
88
89 if (HintTypes.COLLECTION.equals(hintValue)) {
90 rootAction.processSuccessor(this);
91 } else if (HintTypes.ARRAY.equals(hintValue)) {
92 rootAction.processSuccessor(this);
93 } else if (HintTypes.ATTRLIST.equals(hintValue)) {
94 rootAction.processSuccessor(this);
95 } else if (HintTypes.BEAN.equals(hintValue)) {
96 rootAction.processSuccessor(this);
97 } else if (HintTypes.FIELDS.equals(hintValue)) {
98 rootAction.processSuccessor(this);
99 } else {
100 throw new UnsupportedOperationException(
101 "CollectionCreatorAction does not support hint '"
102 + hintValue + "'");
103 }
104 } else {
105 rootAction = this;
106 }
107
108
109 pop();
110
111 IAction previousRootAction = rootAction.getPrevious();
112 if (previousRootAction != null) {
113 if (!((previousRootAction instanceof CollectionCreatorAction) || (previousRootAction instanceof SubelementCreatorAction))) {
114 rootAction = rootAction.process();
115 }
116 }
117 return rootAction;
118 }
119
120 public void processNoSuccessor() {
121 this.createObject();
122 }
123
124 public void processSuccessor(IAction successor) {
125 log.debug("processSuccessor(" + successor + ") - START");
126 if (HintTypes.CONTENT.equals(successor.getHint())) {
127 String content = successor.getValue().toString();
128 if (!ContentCreatorAction.CONTENT_NULL.equals(content)) {
129 throw new DDTException(
130 "Only \"!NULL!\" supported in Collection type");
131 }
132 } else {
133 try {
134 this.createObject();
135 this.elementCount += 1;
136
137
138
139
140 if (HintTypes.ATTRLIST.equals(successor.getHint())
141 && ((SubelementCreatorAction) successor)
142 .hasReferenceInfo()) {
143 TypedObject destObject;
144 String linkType = successor.getType();
145 if (linkType == null) {
146 destObject = new TypedObject(successor
147 .getAttribute("refid"));
148 } else {
149 destObject = new TypedObject(successor
150 .getAttribute("refid"), linkType);
151 }
152 IReferenceInfo refInfo;
153 if (isSorted()) {
154 refInfo = new CollectionReferenceInfo(this.getObject(),
155 destObject, this.elementCount);
156
157 ((List) this.getValue()).add(null);
158 } else {
159 refInfo = new CollectionReferenceInfo(this.getObject(),
160 destObject, CollectionReferenceInfo.noPosition);
161 }
162 add(refInfo);
163 } else {
164 ((Collection) this.getValue()).add(successor.getValue());
165 }
166 } catch (Exception ex) {
167 throw new DDTException(
168 "Error on Collection element processing", ex);
169 }
170 }
171 this.successorProcessed = true;
172 }
173
174 private boolean isSorted() {
175 boolean found = verifyInterface(this.getType(), List.class);
176 return found;
177 }
178
179
180
181
182
183
184 public IAction inject() {
185 String type = (String) this.attrMap.get(ParserConstants.XML_ATTR_TYPE);
186 String id = (String) this.attrMap.get(ParserConstants.XML_ATTR_ID);
187
188 try {
189 if (type == null && ParserConstants.XML_ELEM_ITEM.equals(id)) {
190 type = TypedObject.UNKNOWN_TYPE;
191 } else if (HintTypes.ARRAY.equals(this.getHint())) {
192
193 } else {
194 boolean found = verifyInterface(type, Collection.class);
195 if (!found) {
196 throw new DDTException("Container class '" + type
197 + "' does not implement java.util.Collection.");
198 }
199 }
200 } catch (Exception ex) {
201 throw new DDTException("Container class '" + type
202 + "' does not implement java.util.Collection.", ex);
203 }
204 this.injectedObject = new TypedObject(id, type);
205 return this;
206 }
207
208 private boolean verifyInterface(String clazzType, Class interFace) {
209 Class clazz;
210 try {
211 clazz = Class.forName(clazzType);
212 } catch (ClassNotFoundException ex) {
213 throw new DDTTestDataException("Wrong data type " + clazzType, ex);
214 }
215 Class superclazz = clazz;
216 Class[] interfaces = null;
217 boolean found = false;
218 while (!found && superclazz != null) {
219 found = isImplementing(superclazz, interFace);
220 if (!found) {
221 superclazz = superclazz.getSuperclass();
222 }
223 }
224 return found;
225 }
226
227 private boolean isImplementing(Class clazz, Class interFace) {
228 boolean found = false;
229 Class[] interfaces = clazz.getInterfaces();
230 for (Class inter : interfaces) {
231 if (interFace.equals(inter)) {
232 found = true;
233 break;
234 } else {
235 found = isImplementing(inter, interFace);
236 }
237 }
238 return found;
239 }
240
241 static class CollectionReferenceInfo extends ReferenceInfoBase {
242 protected int position;
243 static int noPosition = -1;
244
245 public CollectionReferenceInfo(TypedObject source,
246 TypedObject destination, int position) {
247 super(source, destination);
248 this.position = position;
249 }
250
251 public void raiseRankOf(IReferenceInfo info) {
252 if (this.getDestId().equals(info.getSourceId())
253 && (this.getDestType().equals(info.getSourceType()) || TypedObject.UNKNOWN_TYPE
254 .equals(info.getDestType()))) {
255 if (this.getRank() >= info.getRank()) {
256 info.setRank(this.getRank() + 1);
257 }
258 }
259 }
260
261 public void resolve(IDataSet dataSet, String groupId, String testId) {
262 if (ParserConstants.UNKNOWN.equals(groupId)
263 && ParserConstants.UNKNOWN.equals(testId)) {
264 doResolution(dataSet);
265 } else if (!ParserConstants.UNKNOWN.equals(testId)) {
266 IDataSet groupSet = dataSet.get(groupId);
267 IDataSet testDataSet = null;
268 if (groupSet != null) {
269 testDataSet = groupSet.get(testId);
270 }
271 doResolution(testDataSet);
272 } else {
273 throw new DDTTestDataException(
274 "Do not process group data without testId");
275 }
276 }
277
278
279
280
281
282 private void doResolution(IDataSet dataSet) {
283 TypedObject dest = dataSet.findObject(this.getDestId(), this
284 .getDestType());
285 TypedObject source = dataSet.getObject(this.getSourceId(), this
286 .getSourceType());
287 if (source == null && dataSet instanceof TestDataSet) {
288 source = ((TestDataSet) dataSet).getAssert(this.getSourceId(),
289 this.getSourceType());
290 }
291 if (dest != null && source != null) {
292
293 if (this.position == this.noPosition) {
294 ((Collection) source.getValue()).add(dest.getValue());
295 } else {
296 ((List) source.getValue()).set(this.position - 1, dest
297 .getValue());
298 }
299 } else {
300 throw new DDTTestDataException(
301 "Error on processing references on testdata.");
302 }
303 }
304
305 }
306 }