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=\"KS-Uif-LookupView\"");
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=\"50\"");
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.shouldDoLookup (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.shouldDoLookup (ms.getLookup())) {
224                 out.println(" />");
225                 continue;
226             }
227             out.println("");
228             out.incrementIndent();
229             XmlType msType = finder.findXmlType(ms.getLookup().getXmlTypeName());
230             if (msType == null) {
231                 throw new NullPointerException ("Processing lookup for: " + type.getName () 
232                         + ms.getName() 
233                         + " lookup=" + ms.getLookup().getXmlTypeName());
234             }
235             out.indentPrintln("p:quickfinder.dataObjectClassName=\"" + msType.getJavaPackage() + "." + msType.getName() + "\"");
236             MessageStructure pk = this.getPrimaryKey(ms.getLookup().getXmlTypeName());
237             if (pk == null) {
238                 throw new NullPointerException("could not find primary key for " + ms.getId());
239             }
240             out.indentPrintln("p:quickfinder.fieldConversions=\"" + pk.getShortName() + ":" + fieldName + "\"");
241             out.indentPrintln("/>");
242             out.decrementIndent();
243         }
244         parents.pop();
245     }
246     
247     private List<MessageStructure> getFieldsToSearchOn() {
248         List<MessageStructure> list = new ArrayList<MessageStructure>();
249         for (MessageStructure ms : finder.findMessageStructures(xmlType.getName())) {
250             // lists of values cannot be displayed within a list of values
251             if (ms.getType().endsWith("List")) {
252                 continue;
253             }
254             if (ms.getType().endsWith("List")) {
255                 continue;
256             }
257             XmlType msType = finder.findXmlType(ms.getType());
258             // just show fields on the main object for now don't dive down into complex fields
259             if (msType.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
260                 continue;
261             }
262         }
263         return list;
264     }
265 
266     private List<MessageStructure> getFieldsToShowOnLookup() {
267         List<MessageStructure> list = new ArrayList<MessageStructure>();
268         for (MessageStructure ms : finder.findMessageStructures(xmlType.getName())) {
269             // lists of values cannot be displayed within a list of values
270             if (ms.getType().endsWith("List")) {
271                 continue;
272             }
273             XmlType msType = finder.findXmlType(ms.getType());
274             // just show fields on the main object for now don't dive down into complex fields
275             if (msType.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
276                 continue;
277             }
278             list.add(ms);
279         }
280         return list;
281     }
282 
283     private void initXmlWriter() {
284         String infoClass = GetterSetterNameCalculator.calcInitUpper(xmlType.getName());
285         String serviceClass = GetterSetterNameCalculator.calcInitUpper(service.getName());
286         String serviceVar = GetterSetterNameCalculator.calcInitLower(service.getName());
287         String serviceContract = service.getImplProject() + "." + service.getName();
288 
289         fullDirectoryPath = AdminUiLookupableWriter.calcPackage(servKey, rootPackage, xmlType).replace('.', '/');
290         fileName = infoClass + "AdminLookupView.xml";
291 
292         File dir = new File(this.directory);
293 
294         if (!dir.exists()) {
295             if (!dir.mkdirs()) {
296                 throw new IllegalStateException("Could not create directory "
297                         + this.directory);
298             }
299         }
300 
301         String dirStr = this.directory + "/" + "resources" + "/" + fullDirectoryPath;
302         File dirFile = new File(dirStr);
303         if (!dirFile.exists()) {
304             if (!dirFile.mkdirs()) {
305                 throw new IllegalStateException(
306                         "Could not create directory " + dirStr);
307             }
308         }
309         try {
310             PrintStream out = new PrintStream(new FileOutputStream(
311                     dirStr + "/"
312                     + fileName, false));
313             log.info("AdminUILookupViewBeanWriter: writing " + dirStr + "/" + fileName);
314             this.out = new XmlWriter(out, 0);
315         } catch (FileNotFoundException ex) {
316             throw new IllegalStateException(ex);
317         }
318     }
319 
320     private void writeBoilerPlate() {
321         out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
322         out.println("<beans xmlns=\"http://www.springframework.org/schema/beans\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
323         out.println("       xmlns:p=\"http://www.springframework.org/schema/p\"");
324         out.println("       xsi:schemaLocation=\"http://www.springframework.org/schema/beans");
325         out.println("                    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd\">");
326         out.println("    <!--");
327         out.println("     Copyright 2007-2012 The Kuali Foundation");
328         out.println("");
329         out.println("     Licensed under the Educational Community License, Version 2.0 (the \"License\");");
330         out.println("     you may not use this file except in compliance with the License.");
331         out.println("     You may obtain a copy of the License at");
332         out.println("");
333         out.println("     http://www.opensource.org/licenses/ecl2.php");
334         out.println("");
335         out.println("     Unless required by applicable law or agreed to in writing, software");
336         out.println("     distributed under the License is distributed on an \"AS IS\" BASIS,");
337         out.println("     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.");
338         out.println("     See the License for the specific language governing permissions and");
339         out.println("     limitations under the License.");
340         out.println("    -->");
341 
342     }
343 }