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.util.ArrayList;
019    import java.util.HashMap;
020    import java.util.List;
021    import java.util.Map;
022    import javax.xml.namespace.QName;
023    import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
024    import org.kuali.student.contract.model.MessageStructure;
025    import org.kuali.student.contract.model.Service;
026    
027    import org.kuali.student.contract.model.ServiceContractModel;
028    import org.kuali.student.contract.model.ServiceMethod;
029    import org.kuali.student.contract.model.XmlType;
030    import org.kuali.student.contract.model.util.ModelFinder;
031    import org.kuali.student.contract.writer.JavaClassWriter;
032    import org.kuali.student.contract.writer.service.GetterSetterNameCalculator;
033    
034    /**
035     *
036     * @author nwright
037     */
038    public class AdminUiInquirableWriter extends JavaClassWriter {
039    
040        private ServiceContractModel model;
041        private ModelFinder finder;
042        private String directory;
043        private String rootPackage;
044        private String servKey;
045        private Service service;
046        private XmlType xmlType;
047        private List<ServiceMethod> methods;
048    
049        public AdminUiInquirableWriter(ServiceContractModel model,
050                String directory,
051                String rootPackage,
052                String servKey,
053                XmlType xmlType,
054                List<ServiceMethod> methods) {
055            super(directory + "/" + "java", calcPackage(servKey, rootPackage, xmlType), calcClassName(servKey, xmlType));
056            this.model = model;
057            this.finder = new ModelFinder(model);
058            this.directory = directory;
059            this.rootPackage = rootPackage;
060            this.servKey = servKey;
061            service = finder.findService(servKey);
062            this.xmlType = xmlType;
063            this.methods = methods;
064        }
065    
066        private static String calcModulePartOfPackage(XmlType xmlType) {
067            if (xmlType.getJavaPackage().contains(".enrollment.")) {
068                return "enrollment";
069            }
070            if (xmlType.getJavaPackage().contains(".core.")) {
071                return "core";
072            }
073            if (xmlType.getJavaPackage().contains(".lum.")) {
074                return "lum";
075            }
076            return null;
077        }
078    
079        public static String calcPackage(String servKey, String rootPackage, XmlType xmlType) {
080            String module = calcModulePartOfPackage(xmlType);
081            if (module == null) {
082                throw new IllegalArgumentException("unknown module " + xmlType.getJavaPackage());
083            }
084            String pack = "org.kuali.student." + module  + "." + rootPackage + "." + servKey.toLowerCase();
085    //  StringBuffer buf = new StringBuffer (service.getVersion ().length ());
086    //  for (int i = 0; i < service.getVersion ().length (); i ++)
087    //  {
088    //   char c = service.getVersion ().charAt (i);
089    //   c = Character.toLowerCase (c);
090    //   if (Character.isLetter (c))
091    //   {
092    //    buf.append (c);
093    //    continue;
094    //   }
095    //   if (Character.isDigit (c))
096    //   {
097    //    buf.append (c);
098    //   }
099    //  }
100    //  pack = pack + buf.toString ();
101    //        pack = pack + "service.decorators";
102            return pack;
103    //        return rootPackage;
104        }
105    
106        public static String calcClassName(String servKey, String xmlTypeName) {
107            return GetterSetterNameCalculator.calcInitUpper(xmlTypeName) + "AdminInquirableImpl";
108        }
109    
110        public static String calcClassName(String servKey, XmlType xmlType) {
111            return calcClassName(servKey, xmlType.getName());
112        }
113    
114        public static String calcDecoratorClassName(String servKey) {
115            return GetterSetterNameCalculator.calcInitUpper(servKey + "ServiceDecorator");
116        }
117    
118        private static enum MethodType {
119    
120            VALIDATE, CREATE, UPDATE
121        };
122    
123        private MethodType calcMethodType(ServiceMethod method) {
124            if (method.getName().startsWith("validate")) {
125                return MethodType.VALIDATE;
126            }
127            if (method.getName().startsWith("create")) {
128                return MethodType.CREATE;
129            }
130            if (method.getName().startsWith("update")) {
131                return MethodType.UPDATE;
132            }
133            return null;
134        }
135    
136        /**
137         * Write out the entire file
138         *
139         * @param out
140         */
141        public void write() {
142            indentPrint("public class " + calcClassName(servKey, xmlType));
143            println(" extends InquirableImpl");
144            importsAdd("org.kuali.rice.krad.inquiry.InquirableImpl");
145            openBrace();
146            writeLogic();
147            closeBrace();
148    
149            this.writeJavaClassAndImportsOutToFile();
150            this.getOut().close();
151        }
152    
153        private void writeLogic() {
154    
155            String initUpper = GetterSetterNameCalculator.calcInitUpper(servKey);
156            String initLower = GetterSetterNameCalculator.calcInitLower(servKey);
157            String infoClass = GetterSetterNameCalculator.calcInitUpper(xmlType.getName());
158            String serviceClass = GetterSetterNameCalculator.calcInitUpper(service.getName());
159            String serviceVar = GetterSetterNameCalculator.calcInitLower(service.getName());
160            importsAdd(service.getImplProject() + "." + service.getName());
161            importsAdd("org.apache.log4j.Logger");
162            indentPrintln("private static final Logger LOG = Logger.getLogger(" + calcClassName(servKey, xmlType) + ".class);");
163            indentPrintln("private transient " + serviceClass + " " + serviceVar + ";");
164            MessageStructure pk = this.getPrimaryKey(xmlType.getName());
165            indentPrintln("private final static String PRIMARY_KEY = \"" + pk.getShortName() + "\";");
166            indentPrintln ("private static final long serialVersionUID = 1L;");
167    
168            println("");
169            indentPrintln("@Override");
170            importsAdd(xmlType.getJavaPackage() + "." + infoClass);
171            importsAdd(List.class.getName());
172            importsAdd(Map.class.getName());
173    //        importsAdd(LookupForm.class.getName());
174    //        importsAdd(QueryByCriteria.class.getName());
175    //        importsAdd(Predicate.class.getName());
176    //        importsAdd(PredicateFactory.class.getName());
177            importsAdd(GlobalResourceLoader.class.getName());
178            XmlType contextInfo = finder.findXmlType("contextInfo");
179            importsAdd(contextInfo.getJavaPackage() + "." + contextInfo.getName());
180            importsAdd("org.kuali.student.common.util.ContextBuilder");
181    //        importsAdd(PredicateFactory.class.getName());
182            importsAdd(ArrayList.class.getName());
183            importsAdd(QName.class.getName());
184    //        importsAdd (PredicateFactory.class.getName());
185            indentPrintln("public " + infoClass + " retrieveDataObject(Map<String, String> parameters)");
186            openBrace();
187            indentPrintln("String key = parameters.get(PRIMARY_KEY);");
188            indentPrintln("try");
189            openBrace();
190            String getMethod = calcGetMethod();
191            if (getMethod == null) {
192                indentPrintln("// WARNING: Missing get method please add it to the service contract: " + servKey + "." + xmlType.getName());
193                getMethod = "get" + GetterSetterNameCalculator.calcInitUpper(xmlType.getName());
194            }
195            indentPrintln("" + infoClass + " info = this.get" + serviceClass + "()." + getMethod + "(key, getContextInfo());");
196            indentPrintln("return info;");
197            closeBrace();
198            indentPrintln("catch (Exception ex) {");
199            indentPrintln("    throw new RuntimeException(ex);");
200            indentPrintln("}");
201            closeBrace();
202            writeServiceGetterAndSetter(this, serviceClass, serviceVar, xmlType);
203        }
204    
205        private MessageStructure getPrimaryKey(String xmlTypeName) {
206            for (MessageStructure ms : finder.findMessageStructures(xmlTypeName)) {
207                if (ms.isPrimaryKey()) {
208                    return ms;
209                }
210            }
211            return null;
212        }
213    
214        public static void writeServiceGetterAndSetter(JavaClassWriter out, String serviceClass, String serviceVar, XmlType xmlType) {
215    
216            out.println("");
217            out.indentPrintln("public void set" + serviceClass + "(" + serviceClass + " " + serviceVar + ")");
218            out.openBrace();
219            out.indentPrintln("    this." + serviceVar + " = " + serviceVar + ";");
220            out.closeBrace();
221            out.println("");
222            out.indentPrintln("public " + serviceClass + " get" + serviceClass + "()");
223            out.openBrace();
224            out.indentPrintln("if (" + serviceVar + " == null)");
225            out.openBrace();
226            String serviceConstants = calcServiceContantsName(serviceClass);
227            out.importsAdd(calcServiceConstantsPackage(xmlType) + "." + serviceConstants);
228            out.indentPrintln("QName qname = new QName(" + serviceConstants + ".NAMESPACE," + serviceConstants + ".SERVICE_NAME_LOCAL_PART);");
229            out.indentPrintln(serviceVar + " = (" + serviceClass + ") GlobalResourceLoader.getService(qname);");
230            out.closeBrace();
231            out.indentPrintln("return this." + serviceVar + ";");
232            out.closeBrace();
233            out.println("");
234            out.indentPrintln("private ContextInfo getContextInfo() {");
235            out.indentPrintln("    return ContextBuilder.loadContextInfo();");
236            out.indentPrintln("}");
237        }
238    
239        public static String calcServiceContantsName(String serviceClass) {
240            if (serviceClass.equals("LRCService")) {
241                return "LrcServiceConstants";
242            }
243            return serviceClass + "Constants";
244        }
245        private static Map<String, String> SERVICE_CLASS_PACKAGE;
246    
247        {
248            SERVICE_CLASS_PACKAGE = new HashMap<String, String>();
249            SERVICE_CLASS_PACKAGE.put("organization", "org.kuali.student.r2.core.constants");
250            SERVICE_CLASS_PACKAGE.put("lum", "org.kuali.student.r2.lum.util.constants");
251            SERVICE_CLASS_PACKAGE.put("lum", "org.kuali.student.r2.lum.util.constants");
252            SERVICE_CLASS_PACKAGE.put("lum", "org.kuali.student.r2.lum.util.constants");
253            SERVICE_CLASS_PACKAGE.put("core", "org.kuali.student.r2.core.constants");
254            SERVICE_CLASS_PACKAGE.put("enrollment", "org.kuali.student.r2.common.util.constants");
255        }
256    
257        public static String calcServiceConstantsPackage(XmlType xmlType) {
258            String pkg = SERVICE_CLASS_PACKAGE.get(xmlType.getService().toLowerCase());
259            if (pkg != null) {
260                return pkg;
261            }
262            String module = calcModulePartOfPackage(xmlType);
263            if (module != null) {
264                return SERVICE_CLASS_PACKAGE.get(module);
265            }
266            return "org.kuali.student.r2.common.util.constants";
267        }
268    
269        private String calcGetMethod() {
270            ServiceMethod method = this.findGetMethod();
271            if (method != null) {
272                return method.getName();
273            }
274            return null;
275        }
276    
277        private ServiceMethod findGetMethod() {
278            String infoClass = GetterSetterNameCalculator.calcInitUpper(xmlType.getName());
279            for (ServiceMethod method : methods) {
280                if (method.getName().startsWith("get")) {
281                    if (method.getReturnValue().getType().equalsIgnoreCase(infoClass)) {
282                        if (method.getParameters().size() == 2) {
283                            if (method.getParameters().get(0).getType().equalsIgnoreCase("String")) {
284                                return method;
285                            }
286                        }
287                    }
288                }
289            }
290            return null;
291        }
292    }