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