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.HashMap;
42 import java.util.List;
43 import java.util.Map;
44
45 import junitx.ddtunit.DDTException;
46 import junitx.ddtunit.data.DDTTestDataException;
47 import junitx.ddtunit.data.IDataSet;
48 import junitx.ddtunit.data.TestDataSet;
49 import junitx.ddtunit.data.TypedObject;
50 import junitx.ddtunit.data.processing.CollectionCreatorAction.CollectionReferenceInfo;
51
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55
56
57
58
59
60 public class MapCreatorAction extends ActionBase {
61 private Logger log = LoggerFactory.getLogger(MapCreatorAction.class);
62
63
64
65
66
67
68 public MapCreatorAction(Map<String, String> attrMap) {
69 super(attrMap);
70 }
71
72
73
74
75
76 public IAction process() {
77 log.debug("process MapCreator Action - START");
78 if (!this.successorProcessed) {
79 processNoSuccessor();
80 }
81 IAction rootAction = getPrevious();
82 if (rootAction != null) {
83 String hintValue = rootAction.getHint();
84 if (HintTypes.CONSTRUCTOR.equals(hintValue)
85 || HintTypes.CALL.equals(hintValue)) {
86 log.debug("createRecord - process addition of field '" + this.getId()
87 + "'...");
88
89 Map attribMap = new HashMap();
90 IAction attribListAction = ActionFactory.getAction(
91 ActionState.ATTRLIST_CREATION, attribMap);
92 rootAction.insert(attribListAction);
93 try {
94
95 attribListAction.createObject();
96
97 ((List) attribListAction.getValue()).add(this.getObject());
98 rootAction = attribListAction;
99 } catch (Exception ex) {
100 throw new DDTException("Error on action processing", ex);
101 }
102
103 } else if (HintTypes.FIELDS.equals(hintValue)) {
104 rootAction.processSuccessor(this);
105 } else if (HintTypes.COLLECTION.equals(hintValue)) {
106 rootAction.processSuccessor(this);
107 } else if (HintTypes.MAP.equals(hintValue)) {
108 rootAction.processSuccessor(this);
109 } else {
110 throw new UnsupportedOperationException(
111 "MapCreatorAction does not support hint '" + hintValue + "'");
112 }
113 } else {
114 rootAction = this;
115 }
116 pop();
117 return rootAction;
118 }
119
120 public void processSuccessor(IAction successor) {
121 log.debug("processSuccessor(" + successor + ") - START");
122 if (HintTypes.CONTENT.equals(successor.getHint())) {
123 String content = successor.getValue().toString();
124 if (!ContentCreatorAction.CONTENT_NULL.equals(content)) {
125 throw new DDTException("Only \"!NULL!\" supported in Map type");
126 }
127 } else {
128 try {
129 this.createObject();
130
131 MapEntry entry = (MapEntry) successor.getValue();
132 if (HintTypes.INTERNAL_MAPENTRY.equals(successor.getHint())
133 && ((SubelementCreatorAction) successor).hasReferenceInfo()) {
134 TypedObject destObject;
135 String linkType = successor.getAttribute(ParserConstants.XML_ATTR_VALUETYPE);
136 if (linkType == null) {
137 destObject = new TypedObject(successor.getAttribute("refid"));
138 } else {
139 destObject = new TypedObject(successor.getAttribute("refid"),
140 linkType);
141 }
142 IReferenceInfo refInfo;
143 refInfo = new MapValueReferenceInfo(this.getObject(), destObject,
144 (String) entry.getKey().getValue());
145 add(refInfo);
146 } else {
147 if (entry == null || entry.getKey() == null
148 || entry.getValue() == null) {
149 throw new DDTException(
150 "<key> or <value> tag of map element missing");
151 }
152 ((Map<Object, Object>) this.getValue()).put(
153 entry.getKey().getValue(), entry.getValue().getValue());
154 }
155 } catch (Exception e) {
156 throw new DDTException("Error on map processing", e);
157 }
158 }
159 this.successorProcessed = true;
160 }
161
162 public void processNoSuccessor() {
163 this.createObject();
164 }
165
166
167
168
169
170 public IAction inject() {
171 String type = (String) this.attrMap.get(ParserConstants.XML_ATTR_TYPE);
172 String id = (String) this.attrMap.get(ParserConstants.XML_ATTR_ID);
173
174 try {
175 Class clazz = Class.forName(type);
176 Class superclazz = clazz;
177
178 boolean found = false;
179 while (!found && superclazz != null) {
180 Class[] interfaces = superclazz.getInterfaces();
181 for (int i = 0; i < interfaces.length; i++) {
182 Class iface = interfaces[i];
183 if ("java.util.Map".equals(iface.getName())) {
184 found = true;
185 break;
186 }
187 }
188 if (found) {
189 break;
190 }
191 superclazz = superclazz.getSuperclass();
192 }
193 if (!found) {
194 throw new DDTException("Container class '" + type
195 + "' does not implement java.util.Map.");
196 }
197 } catch (Exception ex) {
198 throw new DDTException("Container class '" + type
199 + "' does not implement java.util.Map.", ex);
200 }
201 this.injectedObject = new TypedObject(id, type);
202 return this;
203 }
204
205
206
207
208
209 static class MapValueReferenceInfo extends ReferenceInfoBase {
210 protected String key;
211
212 public MapValueReferenceInfo(TypedObject source, TypedObject destination,
213 String key) {
214 super(source, destination);
215 this.key = key;
216 }
217
218 public void raiseRankOf(IReferenceInfo info) {
219 if (this.getDestId().equals(info.getSourceId())
220 && (this.getDestType().equals(info.getSourceType()) || TypedObject.UNKNOWN_TYPE
221 .equals(info.getDestType()))) {
222 if (this.getRank() >= info.getRank()) {
223 info.setRank(this.getRank() + 1);
224 }
225 }
226 }
227
228 public void resolve(IDataSet dataSet, String groupId, String testId) {
229 if (ParserConstants.UNKNOWN.equals(groupId)
230 && ParserConstants.UNKNOWN.equals(testId)) {
231 doResolution(dataSet);
232 } else if (!ParserConstants.UNKNOWN.equals(testId)) {
233 IDataSet groupSet = dataSet.get(groupId);
234 IDataSet testDataSet = null;
235 if (groupSet != null) {
236 testDataSet = groupSet.get(testId);
237 }
238 doResolution(testDataSet);
239 } else {
240 throw new DDTTestDataException(
241 "Do not process group data without testId");
242 }
243 }
244
245
246
247
248 private void doResolution(IDataSet dataSet) {
249 TypedObject dest = dataSet.findObject(this.getDestId(),
250 this.getDestType());
251 TypedObject source = dataSet.getObject(this.getSourceId(),
252 this.getSourceType());
253 if (source == null && dataSet instanceof TestDataSet) {
254 source = ((TestDataSet) dataSet).getAssert(this.getSourceId(),
255 this.getSourceType());
256 }
257 if (dest != null && source != null) {
258 ((Map) source.getValue()).put(this.key, dest.getValue());
259 } else {
260 throw new DDTTestDataException(
261 "Error on processing references on testdata.");
262 }
263 }
264
265 }
266
267 }