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.io.File;
19 import java.io.FileNotFoundException;
20 import java.io.FileOutputStream;
21 import java.io.PrintStream;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Stack;
25 import org.kuali.student.contract.model.Lookup;
26 import org.kuali.student.contract.model.MessageStructure;
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.XmlType;
32 import org.kuali.student.contract.model.impl.ServiceContractModelQDoxLoader;
33 import org.kuali.student.contract.model.util.ModelFinder;
34 import org.kuali.student.contract.writer.XmlWriter;
35 import org.kuali.student.contract.writer.service.GetterSetterNameCalculator;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39
40
41
42
43 public class AdminUiLookupViewBeanWriter {
44
45 private static final Logger log = LoggerFactory.getLogger(AdminUiLookupViewBeanWriter.class);
46
47 private ServiceContractModel model;
48 private ModelFinder finder;
49 private String directory;
50 private String rootPackage;
51 private String servKey;
52 private Service service;
53 private XmlType xmlType;
54 private List<ServiceMethod> methods;
55 private XmlWriter out;
56 String fileName;
57 String fullDirectoryPath;
58
59 public AdminUiLookupViewBeanWriter(ServiceContractModel model,
60 String directory,
61 String rootPackage,
62 String servKey,
63 XmlType xmlType,
64 List<ServiceMethod> methods) {
65 this.model = model;
66 this.finder = new ModelFinder(model);
67 this.directory = directory;
68 this.rootPackage = rootPackage;
69 this.servKey = servKey;
70 service = finder.findService(servKey);
71 this.xmlType = xmlType;
72 this.methods = methods;
73 }
74
75
76
77
78
79
80 public void write() {
81 initXmlWriter();
82 writeBoilerPlate();
83 writeBean();
84 }
85
86 private void writeBean() {
87 String infoClass = GetterSetterNameCalculator.calcInitUpper(xmlType.getName());
88 String serviceClass = GetterSetterNameCalculator.calcInitUpper(service.getName());
89 String serviceVar = GetterSetterNameCalculator.calcInitLower(service.getName());
90 String serviceContract = service.getImplProject() + "." + service.getName();
91 String lookupable = AdminUiLookupableWriter.calcPackage(servKey, rootPackage, xmlType) + "."
92 + AdminUiLookupableWriter.calcClassName(servKey, xmlType);
93 String viewId = "KS-" + infoClass + "-AdminLookupView";
94 out.println("");
95 out.incrementIndent();
96 out.indentPrintln("<import resource=\"classpath:ks-" + infoClass + "-dictionary.xml\"/>");
97 out.indentPrintln("<import resource=\"classpath:UifKSDefinitions.xml\"/>");
98 out.indentPrintln("<!-- **********************************************");
99 out.indentPrintln("Paste this link below into WEB-INF ksAdminLinks.tag or ksMaintenance.tag in KS with Rice Bundled etc");
100 out.indentPrintln("");
101 out.indentPrintln("<li><portal:portalLink displayTitle=\"true\" title=\"" + xmlType.getName() + " Lookup\""
102 + " url=\"${ConfigProperties.application.url}/kr-krad/lookup?methodToCall=start"
103 + "&dataObjectClassName=" + xmlType.getJavaPackage() + "." + infoClass + ""
104 + "&viewId=" + viewId
105 + "&returnLocation=${ConfigProperties.application.url}/portal.do&hideReturnLink=true\" /></li>");
106 out.indentPrintln ("Also...");
107 out.indentPrintln("Paste bean definition below into the list of dataDictionaryPackages in StudentSpringBeans.xml ");
108 out.indentPrintln ("<value>classpath:" + fullDirectoryPath + "/" + fileName + "</value>");
109 out.indentPrintln("********************************************** -->");
110 out.indentPrintln("<!-- LookupView -->");
111 out.indentPrintln("<bean id=\"" + viewId + "\" parent=\"KS-Uif-LookupView\"");
112 out.incrementIndent();
113 out.indentPrintln("p:title=\"" + xmlType.getName() + " Lookup\"");
114 out.indentPrintln("p:header.headerText=\"" + xmlType.getName() + " Lookup\"");
115 out.indentPrintln("p:dataObjectClassName=\"" + xmlType.getJavaPackage() + "." + infoClass + "\"");
116 out.indentPrintln("p:viewHelperServiceClass=\"" + lookupable + "\">");
117 out.indentPrintln("");
118 out.indentPrintln("<property name=\"criteriaFields\">");
119 out.incrementIndent();
120 out.indentPrintln("<list>");
121 out.incrementIndent();
122 out.indentPrintln("<bean parent=\"Uif-LookupCriteriaInputField\" p:propertyName=\"keywordSearch\"");
123 out.indentPrintln(" p:label=\"Keyword(s)\"");
124 out.indentPrintln(" p:helpSummary=\"Searches fields like name and description to see if they contain the keyword\" />");
125 this.writeFieldsToSearchOn (xmlType, new Stack<XmlType>(), "");
126 out.indentPrintln("<bean parent=\"Uif-LookupCriteriaInputField\" p:propertyName=\"maxResultsToReturn\"");
127 out.indentPrintln(" p:label=\"Max. Results\"");
128 out.indentPrintln(" p:defaultValue=\"50\"");
129 out.indentPrintln(" p:helpSummary=\"The maximum number of results to return from the query, leave null to not limit the results\" />");
130 out.decrementIndent();
131 out.indentPrintln("</list>");
132 out.decrementIndent();
133 out.indentPrintln("</property>");
134 out.indentPrintln("<property name=\"resultFields\">");
135 out.indentPrintln(" <list>");
136 for (MessageStructure ms : this.getFieldsToShowOnLookup()) {
137 String fieldName = GetterSetterNameCalculator.calcInitLower(ms.getShortName());
138 out.indentPrint(" <bean parent=\"Uif-DataField\" p:propertyName=\"" + fieldName + "\"");
139 if (ms.isPrimaryKey()) {
140 out.println(">");
141 out.indentPrintln(" <property name=\"inquiry\">");
142 out.indentPrintln(" <bean parent=\"Uif-Inquiry\" p:dataObjectClassName=\"" + xmlType.getJavaPackage() + "." + xmlType.getName() + "\" p:inquiryParameters=\"" + ms.getShortName() + "\" />");
143 out.indentPrintln(" </property>");
144 out.indentPrintln(" </bean>");
145 } else if (AdminUiInquiryViewBeanWriter.shouldDoLookup (ms.getLookup())) {
146
147 out.println(">");
148 Lookup lookup = ms.getLookup();
149 XmlType msType = finder.findXmlType(lookup.getXmlTypeName());
150 MessageStructure pk = this.getPrimaryKey(ms.getLookup().getXmlTypeName());
151 out.indentPrintln(" <property name=\"inquiry\">");
152 out.indentPrintln(" <bean parent=\"Uif-Inquiry\" p:dataObjectClassName=\""
153 + msType.getJavaPackage() + "." + msType.getName()
154 + "\" p:inquiryParameters=\"" + fieldName + ":" + pk.getShortName() + "\" />");
155 out.indentPrintln(" </property>");
156 out.indentPrintln(" </bean>");
157 } else {
158 out.println(" />");
159 }
160 }
161 out.indentPrintln(" </list>");
162 out.indentPrintln("</property>");
163 out.decrementIndent();
164 out.indentPrintln("</bean>");
165 out.indentPrintln("");
166 out.decrementIndent();
167 out.indentPrintln("</beans>");
168 }
169
170
171 private MessageStructure getPrimaryKey(String xmlTypeName) {
172 for (MessageStructure ms : finder.findMessageStructures(xmlTypeName)) {
173 if (ms.isPrimaryKey()) {
174 return ms;
175 }
176 }
177 throw new NullPointerException ("could not find primary key for " + xmlTypeName);
178 }
179
180
181 private void writeFieldsToSearchOn(XmlType type, Stack<XmlType> parents, String prefix) {
182
183 if (parents.contains(type)) {
184 return;
185 }
186 parents.push(type);
187 for (MessageStructure ms : finder.findMessageStructures(type.getName())) {
188 String fieldName = GetterSetterNameCalculator.calcInitLower(ms.getShortName());
189 if (!prefix.isEmpty()) {
190 fieldName = prefix + "." + fieldName;
191 }
192 String fieldNameCamel = GetterSetterNameCalculator.dot2Camel(fieldName);
193 if (ms.getShortName().equalsIgnoreCase("versionInd")) {
194 out.indentPrintln("<!-- TODO: deal with seaching on the version indicator which is a string in the contract but a number in the database -->");
195 continue;
196 }
197 if (ms.getType().equalsIgnoreCase("AttributeInfoList")) {
198 out.indentPrintln("<!-- TODO: deal with dynamic attributes -->");
199 continue;
200 }
201 if (ms.getShortName ().equalsIgnoreCase("name")) {
202 out.indentPrintln("<!-- skip name because keyword searching should cover it -->");
203 continue;
204 }
205 if (ms.getShortName ().equalsIgnoreCase("descr")) {
206 out.indentPrintln("<!-- skip description because keyword searching should cover it -->");
207 continue;
208 }
209 if (ms.getType().endsWith("List")) {
210 out.indentPrintln("<!-- TODO: deal with " + fieldName + " which is a List -->");
211 continue;
212 }
213 XmlType fieldType = finder.findXmlType(ms.getType());
214 if (fieldType.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
215
216 this.writeFieldsToSearchOn(fieldType, parents, fieldName);
217 continue;
218 }
219 if (!ms.getType().equalsIgnoreCase("String")) {
220 out.indentPrintln("<!-- TODO: deal with " + fieldName + " which is a " + ms.getType() + " -->");
221 continue;
222 }
223
224 out.indentPrint("<bean parent=\"Uif-LookupCriteriaInputField\" p:propertyName=\"" + fieldName + "\"");
225 if (!AdminUiInquiryViewBeanWriter.shouldDoLookup (ms.getLookup())) {
226 out.println(" />");
227 continue;
228 }
229 out.println(">");
230 out.incrementIndent();
231 XmlType msType = finder.findXmlType(ms.getLookup().getXmlTypeName());
232 if (msType == null) {
233 throw new NullPointerException ("Processing lookup for: " + type.getName ()
234 + ms.getName()
235 + " lookup=" + ms.getLookup().getXmlTypeName());
236 }
237 out.indentPrintln("<property name=\"quickfinder\">");
238 out.incrementIndent();
239 out.indentPrintln("<bean parent=\"Uif-QuickFinder\" p:dataObjectClassName=\"" + msType.getJavaPackage() + "." + msType.getName() + "\"");
240 MessageStructure pk = this.getPrimaryKey(ms.getLookup().getXmlTypeName());
241 if (pk == null) {
242 throw new NullPointerException("could not find primary key for " + ms.getId());
243 }
244 out.indentPrintln("p:fieldConversions=\"" + pk.getShortName() + ":" + fieldName + "\" />");
245 out.decrementIndent();
246 out.indentPrintln("</property>");
247 out.decrementIndent();
248 out.indentPrintln("</bean>");
249 }
250 parents.pop();
251 }
252
253 private List<MessageStructure> getFieldsToSearchOn() {
254 List<MessageStructure> list = new ArrayList<MessageStructure>();
255 for (MessageStructure ms : finder.findMessageStructures(xmlType.getName())) {
256
257 if (ms.getType().endsWith("List")) {
258 continue;
259 }
260 if (ms.getType().endsWith("List")) {
261 continue;
262 }
263 XmlType msType = finder.findXmlType(ms.getType());
264
265 if (msType.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
266 continue;
267 }
268 }
269 return list;
270 }
271
272 private List<MessageStructure> getFieldsToShowOnLookup() {
273 List<MessageStructure> list = new ArrayList<MessageStructure>();
274 for (MessageStructure ms : finder.findMessageStructures(xmlType.getName())) {
275
276 if (ms.getType().endsWith("List")) {
277 continue;
278 }
279 XmlType msType = finder.findXmlType(ms.getType());
280
281 if (msType.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
282 continue;
283 }
284 list.add(ms);
285 }
286 return list;
287 }
288
289 private void initXmlWriter() {
290 String infoClass = GetterSetterNameCalculator.calcInitUpper(xmlType.getName());
291 String serviceClass = GetterSetterNameCalculator.calcInitUpper(service.getName());
292 String serviceVar = GetterSetterNameCalculator.calcInitLower(service.getName());
293 String serviceContract = service.getImplProject() + "." + service.getName();
294
295 fullDirectoryPath = AdminUiLookupableWriter.calcPackage(servKey, rootPackage, xmlType).replace('.', '/');
296 fileName = infoClass + "AdminLookupView.xml";
297
298 File dir = new File(this.directory);
299
300 if (!dir.exists()) {
301 if (!dir.mkdirs()) {
302 throw new IllegalStateException("Could not create directory "
303 + this.directory);
304 }
305 }
306
307 String dirStr = this.directory + "/" + "resources" + "/" + fullDirectoryPath;
308 File dirFile = new File(dirStr);
309 if (!dirFile.exists()) {
310 if (!dirFile.mkdirs()) {
311 throw new IllegalStateException(
312 "Could not create directory " + dirStr);
313 }
314 }
315 try {
316 PrintStream out = new PrintStream(new FileOutputStream(
317 dirStr + "/"
318 + fileName, false));
319 log.info("AdminUILookupViewBeanWriter: writing " + dirStr + "/" + fileName);
320 this.out = new XmlWriter(out, 0);
321 } catch (FileNotFoundException ex) {
322 throw new IllegalStateException(ex);
323 }
324 }
325
326 private void writeBoilerPlate() {
327 out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
328 out.println("<beans xmlns=\"http://www.springframework.org/schema/beans\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
329 out.println(" xmlns:p=\"http://www.springframework.org/schema/p\"");
330 out.println(" xsi:schemaLocation=\"http://www.springframework.org/schema/beans");
331 out.println(" http://www.springframework.org/schema/beans/spring-beans-3.0.xsd\">");
332 out.println(" <!--");
333 out.println(" Copyright 2007-2012 The Kuali Foundation");
334 out.println("");
335 out.println(" Licensed under the Educational Community License, Version 2.0 (the \"License\");");
336 out.println(" you may not use this file except in compliance with the License.");
337 out.println(" You may obtain a copy of the License at");
338 out.println("");
339 out.println(" http://www.opensource.org/licenses/ecl2.php");
340 out.println("");
341 out.println(" Unless required by applicable law or agreed to in writing, software");
342 out.println(" distributed under the License is distributed on an \"AS IS\" BASIS,");
343 out.println(" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.");
344 out.println(" See the License for the specific language governing permissions and");
345 out.println(" limitations under the License.");
346 out.println(" -->");
347
348 }
349 }