001 /* 002 * Copyright 2009 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.osedu.org/licenses/ECL-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.student.admin.ui.mojo; 017 018 import java.io.File; 019 import java.io.FileNotFoundException; 020 import java.io.FileOutputStream; 021 import java.io.PrintStream; 022 import java.util.HashSet; 023 import java.util.List; 024 import java.util.Stack; 025 import org.kuali.student.contract.model.Lookup; 026 import org.kuali.student.contract.model.MessageStructure; 027 import org.kuali.student.contract.model.Service; 028 029 import org.kuali.student.contract.model.ServiceContractModel; 030 import org.kuali.student.contract.model.ServiceMethod; 031 import org.kuali.student.contract.model.XmlType; 032 import org.kuali.student.contract.model.util.ModelFinder; 033 import org.kuali.student.contract.writer.XmlWriter; 034 import org.kuali.student.contract.writer.service.GetterSetterNameCalculator; 035 036 /** 037 * 038 * @author nwright 039 */ 040 public class AdminUiInquiryViewBeanWriter { 041 042 private ServiceContractModel model; 043 private ModelFinder finder; 044 private String directory; 045 private String rootPackage; 046 private String servKey; 047 private Service service; 048 private XmlType xmlType; 049 private List<ServiceMethod> methods; 050 private XmlWriter out; 051 String fileName; 052 String fullDirectoryPath; 053 054 public AdminUiInquiryViewBeanWriter(ServiceContractModel model, 055 String directory, 056 String rootPackage, 057 String servKey, 058 XmlType xmlType, 059 List<ServiceMethod> methods) { 060 this.model = model; 061 this.finder = new ModelFinder(model); 062 this.directory = directory; 063 this.rootPackage = rootPackage; 064 this.servKey = servKey; 065 service = finder.findService(servKey); 066 this.xmlType = xmlType; 067 this.methods = methods; 068 } 069 070 /** 071 * Write out the entire file 072 * 073 * @param out 074 */ 075 public void write() { 076 initXmlWriter(); 077 writeBoilerPlate(); 078 writeBean(); 079 } 080 081 private void writeBean() { 082 String infoClass = GetterSetterNameCalculator.calcInitUpper(xmlType.getName()); 083 String serviceClass = GetterSetterNameCalculator.calcInitUpper(service.getName()); 084 String serviceVar = GetterSetterNameCalculator.calcInitLower(service.getName()); 085 String serviceContract = service.getImplProject() + "." + service.getName(); 086 String inquirable = AdminUiInquirableWriter.calcPackage(servKey, rootPackage, xmlType) + "." 087 + AdminUiInquirableWriter.calcClassName(servKey, xmlType); 088 out.println(""); 089 out.incrementIndent(); 090 out.indentPrintln("<import resource=\"classpath:ks-" + infoClass + "-dictionary.xml\"/>"); 091 out.indentPrintln("<import resource=\"classpath:UifKSDefinitions.xml\"/>"); 092 out.indentPrintln("<!-- **********************************************"); 093 out.indentPrintln("Paste bean definition below into the list of dataDictionaryPackages of org.kuali.rice.krad.bo.ModuleConfiguration "); 094 out.indentPrintln ("<value>classpath:" + fullDirectoryPath + "/" + fileName + "</value>"); 095 out.indentPrintln("********************************************** -->"); 096 out.indentPrintln("<!-- InquiryView -->"); 097 out.indentPrintln("<bean id=\"KS-" + infoClass + "-AdminInquiryView\" parent=\"KSInquiryView\""); 098 out.incrementIndent(); 099 out.indentPrintln("p:title=\"" + xmlType.getName() + " Inquiry\""); 100 out.indentPrintln("p:dataObjectClassName=\"" + xmlType.getJavaPackage() + "." + infoClass + "\""); 101 out.indentPrintln("p:viewHelperServiceClass=\"" + inquirable + "\">"); 102 out.indentPrintln(""); 103 out.indentPrintln("<property name=\"Items\">"); 104 out.indentPrintln(" <list>"); 105 out.indentPrintln(" <bean parent=\"Uif-Disclosure-GridSection\">"); 106 out.indentPrintln(" <property name=\"layoutManager.numberOfColumns\" value=\"2\"/>"); 107 out.indentPrintln(" <property name=\"headerText\" value=\"" + xmlType.getName() + " Inquiry\"/>"); 108 out.indentPrintln(" <property name=\"items\">"); 109 out.indentPrintln(" <list>"); 110 this.writeFields(xmlType, new Stack<XmlType>(), ""); 111 out.indentPrintln(" </list>"); 112 out.indentPrintln(" </property>"); 113 out.indentPrintln(" </bean>"); 114 out.indentPrintln(" </list>"); 115 out.indentPrintln("</property>"); 116 out.decrementIndent(); 117 out.indentPrintln("</bean>"); 118 out.indentPrintln(""); 119 out.decrementIndent(); 120 out.indentPrintln("</beans>"); 121 122 } 123 124 private void writeFields(XmlType type, Stack<XmlType> parents, String prefix) { 125 // avoid recursion 126 if (parents.contains(type)) { 127 return; 128 } 129 parents.push(type); 130 for (MessageStructure ms : finder.findMessageStructures(type.getName())) { 131 String fieldName = GetterSetterNameCalculator.calcInitLower(ms.getShortName()); 132 if (!prefix.isEmpty()) { 133 fieldName = prefix + "." + fieldName; 134 } 135 if (ms.getType().equalsIgnoreCase("AttributeInfoList")) { 136 out.indentPrintln(" <!-- TODO: deal with dynamic attributes -->"); 137 continue; 138 } 139 if (ms.getType().endsWith("List")) { 140 out.indentPrintln(" <!-- TODO: deal with " + fieldName + " which is a list -->"); 141 continue; 142 } 143 XmlType fieldType = finder.findXmlType(ms.getType()); 144 if (fieldType.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) { 145 // complex sub-types such as rich text 146 this.writeFields(fieldType, parents, fieldName); 147 continue; 148 } 149 out.indentPrint(" <bean parent=\"Uif-DataField\" p:propertyName=\"" + fieldName + "\""); 150 if (!doLookup (ms.getLookup())) { 151 out.println(" />"); 152 continue; 153 } 154 // process lookup 155 out.println(">"); 156 Lookup lookup = ms.getLookup(); 157 XmlType msType = finder.findXmlType(lookup.getXmlTypeName()); 158 MessageStructure pk = this.getPrimaryKey(ms.getLookup().getXmlTypeName()); 159 out.indentPrintln(" <property name=\"inquiry\">"); 160 out.indentPrintln(" <bean parent=\"Uif-Inquiry\" p:dataObjectClassName=\"" 161 + msType.getJavaPackage() + "." + msType.getName() 162 + "\" p:inquiryParameters=\"" + fieldName + ":" + pk.getShortName() + "\" />"); 163 out.indentPrintln(" </property>"); 164 out.indentPrintln(" </bean>"); 165 } 166 parents.pop(); 167 } 168 169 170 public static boolean doLookup (Lookup lookup) { 171 if (lookup == null) { 172 return false; 173 } 174 175 // can't do lookups on things we don't have inquirables on yet 176 if (lookup.getXmlTypeName().equals("OrgInfo")) { 177 return false; 178 } 179 if (lookup.getXmlTypeName().equals("Principal")) { 180 return false; 181 } 182 return true; 183 } 184 185 private MessageStructure getPrimaryKey(String xmlTypeName) { 186 for (MessageStructure ms : finder.findMessageStructures(xmlTypeName)) { 187 if (ms.isPrimaryKey()) { 188 return ms; 189 } 190 } 191 throw new NullPointerException ("could not find primary key for " + xmlTypeName); 192 } 193 private void initXmlWriter() { 194 String infoClass = GetterSetterNameCalculator.calcInitUpper(xmlType.getName()); 195 String serviceClass = GetterSetterNameCalculator.calcInitUpper(service.getName()); 196 String serviceVar = GetterSetterNameCalculator.calcInitLower(service.getName()); 197 String serviceContract = service.getImplProject() + "." + service.getName(); 198 199 fullDirectoryPath = AdminUiInquirableWriter.calcPackage(servKey, rootPackage, xmlType).replace('.', '/'); 200 fileName = infoClass + "AdminInquiryView.xml"; 201 202 File dir = new File(this.directory); 203 204 if (!dir.exists()) { 205 if (!dir.mkdirs()) { 206 throw new IllegalStateException("Could not create directory " 207 + this.directory); 208 } 209 } 210 211 String dirStr = this.directory + "/" + "resources" + "/" + fullDirectoryPath; 212 File dirFile = new File(dirStr); 213 if (!dirFile.exists()) { 214 if (!dirFile.mkdirs()) { 215 throw new IllegalStateException( 216 "Could not create directory " + dirStr); 217 } 218 } 219 try { 220 PrintStream out = new PrintStream(new FileOutputStream( 221 dirStr + "/" + fileName, false)); 222 this.out = new XmlWriter(out, 0); 223 } catch (FileNotFoundException ex) { 224 throw new IllegalStateException(ex); 225 } 226 } 227 228 private void writeBoilerPlate() { 229 out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); 230 out.println("<beans xmlns=\"http://www.springframework.org/schema/beans\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""); 231 out.println(" xmlns:p=\"http://www.springframework.org/schema/p\""); 232 out.println(" xsi:schemaLocation=\"http://www.springframework.org/schema/beans"); 233 out.println(" http://www.springframework.org/schema/beans/spring-beans-3.0.xsd\">"); 234 out.println(" <!--"); 235 out.println(" Copyright 2007-2012 The Kuali Foundation"); 236 out.println(""); 237 out.println(" Licensed under the Educational Community License, Version 2.0 (the \"License\");"); 238 out.println(" you may not use this file except in compliance with the License."); 239 out.println(" You may obtain a copy of the License at"); 240 out.println(""); 241 out.println(" http://www.opensource.org/licenses/ecl2.php"); 242 out.println(""); 243 out.println(" Unless required by applicable law or agreed to in writing, software"); 244 out.println(" distributed under the License is distributed on an \"AS IS\" BASIS,"); 245 out.println(" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."); 246 out.println(" See the License for the specific language governing permissions and"); 247 out.println(" limitations under the License."); 248 out.println(" -->"); 249 250 } 251 }