1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.student.remote.impl.mojo;
17
18 import java.util.ArrayList;
19 import java.util.HashSet;
20 import java.util.List;
21 import java.util.Set;
22 import java.util.Stack;
23 import org.kuali.rice.core.api.criteria.Predicate;
24 import org.kuali.rice.core.api.criteria.PredicateFactory;
25 import org.kuali.rice.core.api.criteria.QueryByCriteria;
26 import org.kuali.student.admin.ui.mojo.AdminUiLookupableWriter;
27 import org.kuali.student.contract.model.MessageStructure;
28 import org.kuali.student.contract.model.Service;
29
30 import org.kuali.student.contract.model.ServiceContractModel;
31 import org.kuali.student.contract.model.ServiceMethod;
32 import org.kuali.student.contract.model.ServiceMethodError;
33 import org.kuali.student.contract.model.XmlType;
34 import org.kuali.student.contract.model.util.ModelFinder;
35 import org.kuali.student.contract.writer.JavaClassWriter;
36 import org.kuali.student.contract.writer.service.GetterSetterNameCalculator;
37 import org.kuali.student.contract.writer.service.MessageStructureTypeCalculator;
38 import org.kuali.student.contract.writer.service.ServiceExceptionWriter;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42
43
44
45
46 public class RemoteImplServiceTestWriter extends JavaClassWriter {
47
48 private static final Logger log = LoggerFactory.getLogger(RemoteImplServiceTestWriter.class);
49 private ServiceContractModel model;
50 private ModelFinder finder;
51 private String directory;
52 private String rootPackage;
53 private String servKey;
54 private List<ServiceMethod> methods;
55 private Service service;
56
57 public RemoteImplServiceTestWriter(ServiceContractModel model,
58 String directory,
59 String rootPackage,
60 String servKey,
61 List<ServiceMethod> methods) {
62 super(directory + "/test/java", calcPackage(servKey, rootPackage), calcClassName(servKey));
63 this.model = model;
64 this.finder = new ModelFinder(model);
65 this.directory = directory;
66 this.rootPackage = rootPackage;
67 this.servKey = servKey;
68 this.service = finder.findService(servKey);
69 this.methods = methods;
70 }
71
72 public static String calcPackage(String servKey, String rootPackage) {
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 return rootPackage;
93 }
94
95 public static String calcClassName(String servKey) {
96 return GetterSetterNameCalculator.calcInitUpper(servKey + "ServiceRemoteImplTest");
97 }
98
99 public static String calcDecoratorClassName(String servKey) {
100 return GetterSetterNameCalculator.calcInitUpper(servKey + "ServiceDecorator");
101 }
102
103 private static enum MethodType {
104
105 VALIDATE, CREATE, UPDATE
106 };
107
108 private MethodType calcMethodType(ServiceMethod method) {
109 if (method.getName().startsWith("validate")) {
110 return MethodType.VALIDATE;
111 }
112 if (method.getName().startsWith("create")) {
113 return MethodType.CREATE;
114 }
115 if (method.getName().startsWith("update")) {
116 return MethodType.UPDATE;
117 }
118 return null;
119 }
120
121
122
123
124
125
126 public void write() {
127 String serviceName = service.getName();
128 indentPrintln("//@Ignore");
129 indentPrintln("public class " + calcClassName(servKey));
130
131 openBrace();
132 importsAdd("org.junit.*");
133 XmlType contextInfo = finder.findXmlType("contextInfo");
134 importsAdd(contextInfo.getJavaPackage() + "." + contextInfo.getName());
135 indentPrintln("private static ContextInfo contextInfo;");
136
137 indentPrintln("private static " + serviceName + "RemoteImpl service;");
138 indentPrintln("");
139 indentPrintln("");
140 indentPrintln("@BeforeClass");
141 indentPrintln("public static void setUpClass() throws Exception");
142 openBrace();
143 indentPrintln("service = new " + serviceName + "RemoteImpl();");
144 indentPrintln("service.setHostUrl(RemoteServiceConstants.ENV2_URL);");
145 indentPrintln("//service.setHostUrl(RemoteServiceConstants.LOCAL_HOST_EMBEDDED_URL);");
146 indentPrintln("contextInfo = new ContextInfo();");
147 indentPrintln("contextInfo.setPrincipalId(\"TESTUSER\");");
148 closeBrace();
149 indentPrintln("");
150 indentPrintln("@AfterClass");
151 indentPrintln("public static void tearDownClass() throws Exception");
152 openBrace();
153 closeBrace();
154 indentPrintln("");
155 indentPrintln("@Before");
156 indentPrintln("public void setUp()");
157 openBrace();
158 closeBrace();
159 indentPrintln("");
160 indentPrintln("@After");
161 indentPrintln("public void tearDown()");
162 openBrace();
163 closeBrace();
164 indentPrintln("");
165
166
167 Set<XmlType> types = this.getMainXmlTypesUsedByService(methods);
168 if (types.isEmpty()) {
169 log.warn("No types defined for servKey: " + servKey);
170 return;
171 }
172
173 log.info("Generating search by criteria tests for " + types.size() + " in " + servKey);
174 for (XmlType type : types) {
175 this.writeTestMethodsForXmlType(type);
176 }
177 closeBrace();
178
179 this.writeJavaClassAndImportsOutToFile();
180 this.getOut().close();
181 }
182
183 private void writeTestMethodsForXmlType(XmlType xmlType) {
184 ServiceMethod searchMethod = AdminUiLookupableWriter.findSearchMethod(xmlType, methods);
185 String infoClass = GetterSetterNameCalculator.calcInitUpper(xmlType.getName());
186 importsAdd(xmlType.getJavaPackage() + "." + xmlType.getName());
187 indentPrintln("");
188 indentPrintln("@Test");
189 indentPrintln("public void testSearch" + infoClass + "All () throws Exception");
190 openBrace();
191 importsAdd(QueryByCriteria.class.getName());
192 importsAdd(Predicate.class.getName());
193 importsAdd(PredicateFactory.class.getName());
194 indentPrintln("QueryByCriteria.Builder qBuilder = QueryByCriteria.Builder.create();");
195 indentPrintln("qBuilder.setMaxResults (30);");
196 importsAdd(List.class.getName());
197 indentPrintln("List<" + infoClass + "> infos = service." + searchMethod.getName() + "(qBuilder.build(), contextInfo);");
198 closeBrace();
199
200
201 indentPrintln("");
202 indentPrintln("@Test");
203 indentPrintln("public void testSearch" + infoClass + "KeywordSearch () throws Exception");
204 openBrace();
205 importsAdd(QueryByCriteria.class.getName());
206 importsAdd(Predicate.class.getName());
207 importsAdd(PredicateFactory.class.getName());
208 indentPrintln("QueryByCriteria.Builder qBuilder = QueryByCriteria.Builder.create();");
209 importsAdd (ArrayList.class.getName());
210 indentPrintln("List<Predicate> pList = new ArrayList<Predicate>();");
211 indentPrintln("pList.add(PredicateFactory.equal(\"keywordSearch\", \"xyzzysomethingnothingmatches\"));");
212 indentPrintln("qBuilder.setPredicates(PredicateFactory.and(pList.toArray(new Predicate[pList.size()])));");
213 indentPrintln("qBuilder.setMaxResults (30);");
214 importsAdd(List.class.getName());
215 indentPrintln("List<" + infoClass + "> infos = service." + searchMethod.getName() + "(qBuilder.build(), contextInfo);");
216 closeBrace();
217
218 this.writeFieldTests(infoClass, searchMethod, xmlType, new Stack<XmlType>(), "");
219 }
220
221 private void writeFieldTests(String infoClass, ServiceMethod searchMethod, XmlType type, Stack<XmlType> parents, String prefix) {
222
223 if (parents.contains(type)) {
224 return;
225 }
226 parents.push(type);
227 for (MessageStructure ms : finder.findMessageStructures(type.getName())) {
228 String fieldName = GetterSetterNameCalculator.calcInitLower(ms.getShortName());
229 if (!prefix.isEmpty()) {
230 fieldName = prefix + "." + fieldName;
231 }
232 String fieldNameCamel = GetterSetterNameCalculator.dot2Camel(fieldName);
233 if (ms.getShortName().equalsIgnoreCase("versionInd")) {
234 indentPrintln("// TODO: deal with seaching on the version indicator which is a string in the contract but a number in the database");
235 continue;
236 }
237 if (ms.getType().equalsIgnoreCase("AttributeInfoList")) {
238 indentPrintln("// TODO: deal with dynamic attributes");
239 continue;
240 }
241 if (ms.getType().endsWith("List")) {
242 indentPrintln("// TODO: deal with " + fieldName + " which is a List");
243 continue;
244 }
245 XmlType fieldType = finder.findXmlType(ms.getType());
246 if (fieldType.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
247
248 this.writeFieldTests(infoClass, searchMethod, fieldType, parents, fieldName);
249 continue;
250 }
251 if (!ms.getType().equalsIgnoreCase("String")) {
252 indentPrintln("// TODO: deal with " + fieldName + " which is a " + ms.getType());
253 continue;
254 }
255
256 indentPrintln("");
257 indentPrintln("@Test");
258 indentPrintln("public void testSearch" + infoClass + "By" + fieldNameCamel + " () throws Exception");
259 openBrace();
260 indentPrintln("QueryByCriteria.Builder qBuilder = QueryByCriteria.Builder.create();");
261 indentPrintln("List<Predicate> pList = new ArrayList<Predicate>();");
262 indentPrintln("pList.add(PredicateFactory.equal(\"" + fieldName + "\", \"xyzzysomethingnothingmatches\"));");
263 indentPrintln("qBuilder.setPredicates(PredicateFactory.and(pList.toArray(new Predicate[pList.size()])));");
264 indentPrintln("qBuilder.setMaxResults (30);");
265 indentPrintln("List<" + infoClass + "> infos = service." + searchMethod.getName() + "(qBuilder.build(), contextInfo);");
266 closeBrace();
267
268 }
269 parents.pop();
270 }
271
272 private String calcType(String type, String realType) {
273 XmlType t = finder.findXmlType(this.stripList(type));
274 return MessageStructureTypeCalculator.calculate(this, model, type, realType,
275 t.getJavaPackage());
276 }
277
278 private String stripList(String str) {
279 return GetterSetterNameCalculator.stripList(str);
280 }
281
282 private String calcExceptionClassName(ServiceMethodError error) {
283 if (error.getClassName() == null) {
284 return ServiceExceptionWriter.calcClassName(error.getType());
285 }
286 return error.getClassName();
287 }
288
289 private String calcExceptionPackageName(ServiceMethodError error) {
290 if (error.getClassName() == null) {
291 return ServiceExceptionWriter.calcPackage(rootPackage);
292 }
293 return error.getPackageName();
294 }
295
296 private Set<XmlType> getMainXmlTypesUsedByService(List<ServiceMethod> methods) {
297 Set<XmlType> set = new HashSet();
298 for (ServiceMethod method : methods) {
299 if (method.getReturnValue().getType().endsWith("List")) {
300 continue;
301 }
302 XmlType returnType = finder.findXmlType(method.getReturnValue().getType());
303 if (returnType == null) {
304 continue;
305 }
306 if (!returnType.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
307 continue;
308 }
309
310 if (returnType.getName().equalsIgnoreCase("TypeInfo")) {
311 if (!servKey.equalsIgnoreCase("type")) {
312 continue;
313 }
314 }
315
316 if (returnType.getName().equalsIgnoreCase("StateInfo")) {
317 if (!servKey.equalsIgnoreCase("state")) {
318 continue;
319 }
320 }
321
322
323
324
325
326
327
328
329 if (method.getName().startsWith("get")) {
330 if (method.getParameters().size() == 2) {
331 if (method.getParameters().get(0).getType().equalsIgnoreCase("String")) {
332 set.add(returnType);
333 continue;
334 }
335 }
336 }
337 }
338 return set;
339 }
340
341 private List<MessageStructure> getFieldsToSearchOn(XmlType xmlType) {
342 List<MessageStructure> list = new ArrayList<MessageStructure>();
343 for (MessageStructure ms : finder.findMessageStructures(xmlType.getName())) {
344 XmlType msType = finder.findXmlType(ms.getType());
345
346 if (msType.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
347 continue;
348 }
349 list.add(ms);
350 }
351 return list;
352 }
353 }