1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.student.admin.ui.mojo;
17
18 import java.util.ArrayList;
19 import java.util.List;
20 import java.util.Map;
21 import javax.xml.namespace.QName;
22 import org.kuali.rice.core.api.criteria.Predicate;
23 import org.kuali.rice.core.api.criteria.PredicateFactory;
24 import org.kuali.rice.core.api.criteria.QueryByCriteria;
25 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
26 import org.kuali.rice.krad.web.form.LookupForm;
27 import org.kuali.student.contract.model.Service;
28
29 import org.kuali.student.contract.model.ServiceContractModel;
30 import org.kuali.student.contract.model.ServiceMethod;
31 import org.kuali.student.contract.model.ServiceMethodParameter;
32 import org.kuali.student.contract.model.XmlType;
33 import org.kuali.student.contract.model.util.ModelFinder;
34 import org.kuali.student.contract.writer.JavaClassWriter;
35 import org.kuali.student.contract.writer.service.GetterSetterNameCalculator;
36
37
38
39
40
41 public class AdminUiLookupableWriter extends JavaClassWriter {
42
43 private ServiceContractModel model;
44 private ModelFinder finder;
45 private String directory;
46 private String rootPackage;
47 private String servKey;
48 private Service service;
49 private XmlType xmlType;
50 private List<ServiceMethod> methods;
51
52 public AdminUiLookupableWriter(ServiceContractModel model,
53 String directory,
54 String rootPackage,
55 String servKey,
56 XmlType xmlType,
57 List<ServiceMethod> methods) {
58 super(directory + "/" + "java", calcPackage(servKey, rootPackage, xmlType), calcClassName(servKey, xmlType));
59 this.model = model;
60 this.finder = new ModelFinder(model);
61 this.directory = directory;
62 this.rootPackage = rootPackage;
63 this.servKey = servKey;
64 service = finder.findService(servKey);
65 this.xmlType = xmlType;
66 this.methods = methods;
67 }
68
69 public static String calcPackage(String servKey, String rootPackage, XmlType xmlType) {
70 String pack = rootPackage + "." + servKey.toLowerCase();
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 return pack;
89
90 }
91
92 public static String calcClassName(String servKey, String xmlTypeName) {
93 return GetterSetterNameCalculator.calcInitUpper(xmlTypeName) + "AdminLookupableImpl";
94 }
95
96 public static String calcClassName(String servKey, XmlType xmlType) {
97 return calcClassName(servKey, xmlType.getName());
98 }
99
100 public static String calcDecoratorClassName(String servKey) {
101 return GetterSetterNameCalculator.calcInitUpper(servKey + "ServiceDecorator");
102 }
103
104 private static enum MethodType {
105
106 VALIDATE, CREATE, UPDATE
107 };
108
109 private MethodType calcMethodType(ServiceMethod method) {
110 if (method.getName().startsWith("validate")) {
111 return MethodType.VALIDATE;
112 }
113 if (method.getName().startsWith("create")) {
114 return MethodType.CREATE;
115 }
116 if (method.getName().startsWith("update")) {
117 return MethodType.UPDATE;
118 }
119 return null;
120 }
121
122
123
124
125
126
127 public void write() {
128 indentPrint("public class " + calcClassName(servKey, xmlType));
129 println(" extends LookupableImpl");
130 importsAdd("org.kuali.rice.krad.lookup.LookupableImpl");
131 openBrace();
132 writeLogic();
133 closeBrace();
134
135 this.writeJavaClassAndImportsOutToFile();
136 this.getOut().close();
137 }
138
139 private void writeLogic() {
140
141 String initUpper = GetterSetterNameCalculator.calcInitUpper(servKey);
142 String initLower = GetterSetterNameCalculator.calcInitLower(servKey);
143 String infoClass = GetterSetterNameCalculator.calcInitUpper(xmlType.getName());
144 String serviceClass = GetterSetterNameCalculator.calcInitUpper(service.getName());
145 String serviceVar = GetterSetterNameCalculator.calcInitLower(service.getName());
146 importsAdd(service.getImplProject() + "." + service.getName());
147 importsAdd("org.apache.log4j.Logger");
148 indentPrintln("private static final Logger LOG = Logger.getLogger(" + calcClassName(servKey, xmlType) + ".class);");
149 indentPrintln("private transient " + serviceClass + " " + serviceVar + ";");
150
151 println("");
152 indentPrintln("@Override");
153 importsAdd(xmlType.getJavaPackage() + "." + infoClass);
154 importsAdd(List.class.getName());
155 importsAdd(Map.class.getName());
156 importsAdd(LookupForm.class.getName());
157 importsAdd(QueryByCriteria.class.getName());
158 importsAdd(Predicate.class.getName());
159 importsAdd(PredicateFactory.class.getName());
160 importsAdd(GlobalResourceLoader.class.getName());
161 XmlType contextInfo = finder.findXmlType("contextInfo");
162 importsAdd(contextInfo.getJavaPackage() + "." + contextInfo.getName());
163 importsAdd("org.kuali.student.common.util.ContextBuilder");
164 importsAdd(PredicateFactory.class.getName());
165 importsAdd(ArrayList.class.getName());
166 importsAdd(QName.class.getName());
167
168 indentPrintln("protected List<" + infoClass + "> getSearchResults(LookupForm lookupForm, Map<String, String> fieldValues, boolean unbounded)");
169 openBrace();
170 indentPrintln("QueryByCriteria.Builder qBuilder = QueryByCriteria.Builder.create();");
171 indentPrintln("List<Predicate> pList = new ArrayList<Predicate>();");
172 indentPrintln("for (String fieldName : fieldValues.keySet())");
173 openBrace();
174 indentPrintln("String value = fieldValues.get(fieldName);");
175 indentPrintln("if (value != null && !value.isEmpty())");
176 openBrace();
177 indentPrintln("if (fieldName.equals(\"maxResultsToReturn\"))");
178 openBrace();
179 indentPrintln("qBuilder.setMaxResults (Integer.parseInt(value));");
180 indentPrintln("continue;");
181 closeBrace();
182 indentPrintln("pList.add(PredicateFactory.equal(fieldName, value));");
183 closeBrace();
184 closeBrace();
185 indentPrintln("if (!pList.isEmpty())");
186 openBrace();
187 indentPrintln("qBuilder.setPredicates(PredicateFactory.and(pList.toArray(new Predicate[pList.size()])));");
188 closeBrace();
189 indentPrintln("try");
190 openBrace();
191 String searchMethodName = calcSearchMethodName();
192 if (searchMethodName == null) {
193 indentPrintln("// WARNING: Missing searchMethod please add it to the service contract: " + servKey + "." + xmlType.getName());
194 searchMethodName = "searchFor" + GetterSetterNameCalculator.calcInitUpper(xmlType.getName()) + "s";
195 }
196 indentPrintln("List<" + infoClass + "> list = this.get" + serviceClass + "()." + searchMethodName + "(qBuilder.build(), getContextInfo());");
197 indentPrintln("return list;");
198 closeBrace();
199 indentPrintln("catch (Exception ex) {");
200 indentPrintln(" throw new RuntimeException(ex);");
201 indentPrintln("}");
202 closeBrace();
203
204 AdminUiInquirableWriter.writeServiceGetterAndSetter(this, serviceClass, serviceVar, xmlType);
205 }
206
207 private String calcSearchMethodName() {
208 ServiceMethod method = this.findSearchMethod();
209 if (method != null) {
210 return method.getName();
211 }
212 return null;
213 }
214
215 private ServiceMethod findSearchMethod() {
216 return findSearchMethod(xmlType, methods);
217 }
218
219 public static ServiceMethod findSearchMethod(XmlType xmlType, List<ServiceMethod> methods) {
220 for (ServiceMethod method : methods) {
221 if (hasProperReturnTypeForSearchMethod(xmlType, method)) {
222 if (hasProperParameterForSearchMethod(xmlType, method)) {
223 return method;
224 }
225 }
226 }
227 return null;
228 }
229
230 private static boolean hasProperReturnTypeForSearchMethod(XmlType xmlType, ServiceMethod method) {
231 String returnValueTypeLower = method.getReturnValue().getType().toLowerCase();
232 if (returnValueTypeLower.endsWith("List".toLowerCase())) {
233 if (returnValueTypeLower.startsWith(xmlType.getName().toLowerCase())) {
234 return true;
235 }
236 }
237 if (returnValueTypeLower.endsWith("QueryResults".toLowerCase())) {
238 if (returnValueTypeLower.startsWith(xmlType.getName().toLowerCase())) {
239 return true;
240 }
241 }
242 return false;
243 }
244
245 private static boolean hasProperParameterForSearchMethod(XmlType xmlType, ServiceMethod method) {
246 for (ServiceMethodParameter parameter : method.getParameters()) {
247 if (parameter.getType().equals("QueryByCriteria")) {
248 return true;
249 }
250 }
251 return false;
252 }
253 }