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    }