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 }