View Javadoc

1   /*
2    * Copyright 2009 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may	obtain a copy of the License at
7    *
8    * 	http://www.osedu.org/licenses/ECL-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
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   * @author nwright
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       * Write out the entire file
77       *
78       * @param out
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          out.println("");
94          out.incrementIndent();
95          out.indentPrintln("<import resource=\"classpath:ks-" + infoClass + "-dictionary.xml\"/>");
96          out.indentPrintln("<import resource=\"classpath:UifKSDefinitions.xml\"/>");
97          out.indentPrintln("<!-- **********************************************");
98          out.indentPrintln("Paste this link below into WEB-INF ksAdminLinks.tag");
99          out.indentPrintln("<li><portal:portalLink displayTitle=\"true\" title=\"" + xmlType.getName() + " Lookup\""
100                 + "url=\"${ConfigProperties.application.url}/kr-krad/lookup?methodToCall=start"
101                 + "&dataObjectClassName=" + xmlType.getJavaPackage() + "." + infoClass + ""
102                 + "&viewId=" + fileName
103                 + "&returnLocation=${ConfigProperties.application.url}/portal.do&hideReturnLink=true\" /></li>");
104         out.indentPrintln ("Also...");
105         out.indentPrintln("Paste bean definition below into the list of dataDictionaryPackages of org.kuali.rice.krad.bo.ModuleConfiguration ");
106         out.indentPrintln ("<value>classpath:" + fullDirectoryPath + "/" + fileName + "</value>");
107         out.indentPrintln("********************************************** -->");
108         out.indentPrintln("<!-- LookupView -->");
109         out.indentPrintln("<bean id=\"KS-" + infoClass + "-AdminLookupView\" parent=\"KSLookupView\"");
110         out.incrementIndent();
111         out.indentPrintln("p:title=\"" + xmlType.getName() + " Lookup\"");
112         out.indentPrintln("p:header.headerText=\"" + xmlType.getName() + " Lookup\"");
113         out.indentPrintln("p:dataObjectClassName=\"" + xmlType.getJavaPackage() + "." + infoClass + "\"");
114         out.indentPrintln("p:viewHelperServiceClass=\"" + lookupable + "\">");
115         out.indentPrintln("");
116         out.indentPrintln("<property name=\"criteriaFields\">");
117         out.incrementIndent();
118         out.indentPrintln("<list>");
119         out.incrementIndent();
120         out.indentPrintln("<bean parent=\"Uif-LookupCriteriaInputField\" p:propertyName=\"keywordSearch\"");
121         out.indentPrintln("      p:label=\"Keyword(s)\"");
122         out.indentPrintln("      p:helpSummary=\"Searches fields like name and description to see if they contain the keyword\" />");
123         this.writeFieldsToSearchOn (xmlType, new Stack<XmlType>(), "");
124         out.indentPrintln("<bean parent=\"Uif-LookupCriteriaInputField\" p:propertyName=\"maxResultsToReturn\"");
125         out.indentPrintln("      p:label=\"Max. Results\"");
126         out.indentPrintln("      p:defaultValue=\"30\"");
127         out.indentPrintln("      p:helpSummary=\"The maximum number of results to return from the query, leave null to not limit the results\" />");
128         out.decrementIndent();
129         out.indentPrintln("</list>");
130         out.decrementIndent();
131         out.indentPrintln("</property>");
132         out.indentPrintln("<property name=\"resultFields\">");
133         out.indentPrintln("    <list>");
134         for (MessageStructure ms : this.getFieldsToShowOnLookup()) {
135             String fieldName = GetterSetterNameCalculator.calcInitLower(ms.getShortName());
136             out.indentPrint("        <bean parent=\"Uif-DataField\" p:propertyName=\"" + fieldName + "\"");
137             if (ms.isPrimaryKey()) {
138                 out.println(">");
139                 out.indentPrintln("            <property name=\"inquiry\">");
140                 out.indentPrintln("                <bean parent=\"Uif-Inquiry\" p:dataObjectClassName=\"" + xmlType.getJavaPackage() + "." + xmlType.getName() + "\" p:inquiryParameters=\"" + ms.getShortName() + "\" />");
141                 out.indentPrintln("            </property>");
142                 out.indentPrintln("        </bean>");
143             } else if (AdminUiInquiryViewBeanWriter.doLookup (ms.getLookup())) {
144                 
145                 out.println(">");
146                 Lookup lookup = ms.getLookup();
147                 XmlType msType = finder.findXmlType(lookup.getXmlTypeName());
148                 MessageStructure pk = this.getPrimaryKey(ms.getLookup().getXmlTypeName());
149                 out.indentPrintln("            <property name=\"inquiry\">");
150                 out.indentPrintln("                <bean parent=\"Uif-Inquiry\" p:dataObjectClassName=\""
151                         + msType.getJavaPackage() + "." + msType.getName()
152                         + "\" p:inquiryParameters=\"" + fieldName + ":" + pk.getShortName() + "\" />");
153                 out.indentPrintln("            </property>");
154                 out.indentPrintln("        </bean>");
155             } else {
156                 out.println(" />");
157             }
158         }
159         out.indentPrintln("    </list>");
160         out.indentPrintln("</property>");
161         out.decrementIndent();
162         out.indentPrintln("</bean>");
163         out.indentPrintln("");
164         out.decrementIndent();
165         out.indentPrintln("</beans>");
166     }
167 
168     
169     private MessageStructure getPrimaryKey(String xmlTypeName) {
170         for (MessageStructure ms : finder.findMessageStructures(xmlTypeName)) {
171             if (ms.isPrimaryKey()) {
172                 return ms;
173             }
174         }
175         throw new NullPointerException ("could not find primary key for " + xmlTypeName);
176     }
177 
178     
179     private void writeFieldsToSearchOn(XmlType type, Stack<XmlType> parents, String prefix) {
180          // avoid recursion
181         if (parents.contains(type)) {
182             return;
183         }
184         parents.push(type);
185         for (MessageStructure ms : finder.findMessageStructures(type.getName())) {
186             String fieldName = GetterSetterNameCalculator.calcInitLower(ms.getShortName());
187             if (!prefix.isEmpty()) {
188                 fieldName = prefix + "." + fieldName;
189             }
190             String fieldNameCamel = GetterSetterNameCalculator.dot2Camel(fieldName);
191             if (ms.getShortName().equalsIgnoreCase("versionInd")) {
192                 out.indentPrintln("<!-- TODO: deal with seaching on the version indicator which is a string in the contract but a number in the database -->");
193                 continue;
194             }
195             if (ms.getType().equalsIgnoreCase("AttributeInfoList")) {
196                 out.indentPrintln("<!-- TODO: deal with dynamic attributes -->");
197                 continue;
198             }
199             if (ms.getShortName ().equalsIgnoreCase("name")) {
200                 out.indentPrintln("<!-- skip name because keyword searching should cover it -->");
201                 continue;
202             }
203             if (ms.getShortName ().equalsIgnoreCase("descr")) {
204                 out.indentPrintln("<!-- skip description because keyword searching should cover it -->");
205                 continue;
206             }
207             if (ms.getType().endsWith("List")) {
208                 out.indentPrintln("<!-- TODO: deal with  " + fieldName + " which is a List -->");
209                 continue;
210             }
211             XmlType fieldType = finder.findXmlType(ms.getType());
212             if (fieldType.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
213                 // complex sub-types such as rich text 
214                 this.writeFieldsToSearchOn(fieldType, parents, fieldName);
215                 continue;
216             }
217             if (!ms.getType().equalsIgnoreCase("String")) {
218                 out.indentPrintln("<!-- TODO: deal with  " + fieldName + " which is a " + ms.getType() + " -->");
219                 continue;
220             }
221 
222             out.indentPrint("<bean parent=\"Uif-LookupCriteriaInputField\" p:propertyName=\"" + fieldName + "\"");
223             if (!AdminUiInquiryViewBeanWriter.doLookup (ms.getLookup())) {
224                 out.println(" />");
225                 continue;
226             }
227             out.println("");
228             out.incrementIndent();
229             XmlType msType = finder.findXmlType(ms.getLookup().getXmlTypeName());
230             out.indentPrintln("p:quickfinder.dataObjectClassName=\"" + msType.getJavaPackage() + "." + msType.getName() + "\"");
231             MessageStructure pk = this.getPrimaryKey(ms.getLookup().getXmlTypeName());
232             if (pk == null) {
233                 throw new NullPointerException("could not find primary key for " + ms.getId());
234             }
235             out.indentPrintln("p:quickfinder.fieldConversions=\"" + pk.getShortName() + ":" + fieldName + "\"");
236             out.indentPrintln("/>");
237             out.decrementIndent();
238         }
239         parents.pop();
240     }
241     
242     private List<MessageStructure> getFieldsToSearchOn() {
243         List<MessageStructure> list = new ArrayList<MessageStructure>();
244         for (MessageStructure ms : finder.findMessageStructures(xmlType.getName())) {
245             // lists of values cannot be displayed within a list of values
246             if (ms.getType().endsWith("List")) {
247                 continue;
248             }
249             if (ms.getType().endsWith("List")) {
250                 continue;
251             }
252             XmlType msType = finder.findXmlType(ms.getType());
253             // just show fields on the main object for now don't dive down into complex fields
254             if (msType.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
255                 continue;
256             }
257         }
258         return list;
259     }
260 
261     private List<MessageStructure> getFieldsToShowOnLookup() {
262         List<MessageStructure> list = new ArrayList<MessageStructure>();
263         for (MessageStructure ms : finder.findMessageStructures(xmlType.getName())) {
264             // lists of values cannot be displayed within a list of values
265             if (ms.getType().endsWith("List")) {
266                 continue;
267             }
268             XmlType msType = finder.findXmlType(ms.getType());
269             // just show fields on the main object for now don't dive down into complex fields
270             if (msType.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
271                 continue;
272             }
273             list.add(ms);
274         }
275         return list;
276     }
277 
278     private void initXmlWriter() {
279         String infoClass = GetterSetterNameCalculator.calcInitUpper(xmlType.getName());
280         String serviceClass = GetterSetterNameCalculator.calcInitUpper(service.getName());
281         String serviceVar = GetterSetterNameCalculator.calcInitLower(service.getName());
282         String serviceContract = service.getImplProject() + "." + service.getName();
283 
284         fullDirectoryPath = AdminUiLookupableWriter.calcPackage(servKey, rootPackage, xmlType).replace('.', '/');
285         fileName = infoClass + "AdminLookupView.xml";
286 
287         File dir = new File(this.directory);
288 
289         if (!dir.exists()) {
290             if (!dir.mkdirs()) {
291                 throw new IllegalStateException("Could not create directory "
292                         + this.directory);
293             }
294         }
295 
296         String dirStr = this.directory + "/" + "resources" + "/" + fullDirectoryPath;
297         File dirFile = new File(dirStr);
298         if (!dirFile.exists()) {
299             if (!dirFile.mkdirs()) {
300                 throw new IllegalStateException(
301                         "Could not create directory " + dirStr);
302             }
303         }
304         try {
305             PrintStream out = new PrintStream(new FileOutputStream(
306                     dirStr + "/"
307                     + fileName, false));
308             log.info("AdminUILookupViewBeanWriter: writing " + dirStr + "/" + fileName);
309             this.out = new XmlWriter(out, 0);
310         } catch (FileNotFoundException ex) {
311             throw new IllegalStateException(ex);
312         }
313     }
314 
315     private void writeBoilerPlate() {
316         out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
317         out.println("<beans xmlns=\"http://www.springframework.org/schema/beans\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
318         out.println("       xmlns:p=\"http://www.springframework.org/schema/p\"");
319         out.println("       xsi:schemaLocation=\"http://www.springframework.org/schema/beans");
320         out.println("                    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd\">");
321         out.println("    <!--");
322         out.println("     Copyright 2007-2012 The Kuali Foundation");
323         out.println("");
324         out.println("     Licensed under the Educational Community License, Version 2.0 (the \"License\");");
325         out.println("     you may not use this file except in compliance with the License.");
326         out.println("     You may obtain a copy of the License at");
327         out.println("");
328         out.println("     http://www.opensource.org/licenses/ecl2.php");
329         out.println("");
330         out.println("     Unless required by applicable law or agreed to in writing, software");
331         out.println("     distributed under the License is distributed on an \"AS IS\" BASIS,");
332         out.println("     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.");
333         out.println("     See the License for the specific language governing permissions and");
334         out.println("     limitations under the License.");
335         out.println("    -->");
336 
337     }
338 }