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.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        public static String calcPackage(String servKey, String rootPackage, XmlType xmlType) {
067            String pack = rootPackage + "." + servKey.toLowerCase();
068    //  StringBuffer buf = new StringBuffer (service.getVersion ().length ());
069    //  for (int i = 0; i < service.getVersion ().length (); i ++)
070    //  {
071    //   char c = service.getVersion ().charAt (i);
072    //   c = Character.toLowerCase (c);
073    //   if (Character.isLetter (c))
074    //   {
075    //    buf.append (c);
076    //    continue;
077    //   }
078    //   if (Character.isDigit (c))
079    //   {
080    //    buf.append (c);
081    //   }
082    //  }
083    //  pack = pack + buf.toString ();
084    //        pack = pack + "service.decorators";
085            return pack;
086    //        return rootPackage;
087        }
088    
089        public static String calcClassName(String servKey, String xmlTypeName) {
090            return GetterSetterNameCalculator.calcInitUpper(xmlTypeName) + "AdminInquirableImpl";
091        }
092    
093        public static String calcClassName(String servKey, XmlType xmlType) {
094            return calcClassName(servKey, xmlType.getName());
095        }
096    
097        public static String calcDecoratorClassName(String servKey) {
098            return GetterSetterNameCalculator.calcInitUpper(servKey + "ServiceDecorator");
099        }
100    
101        private static enum MethodType {
102    
103            VALIDATE, CREATE, UPDATE
104        };
105    
106        private MethodType calcMethodType(ServiceMethod method) {
107            if (method.getName().startsWith("validate")) {
108                return MethodType.VALIDATE;
109            }
110            if (method.getName().startsWith("create")) {
111                return MethodType.CREATE;
112            }
113            if (method.getName().startsWith("update")) {
114                return MethodType.UPDATE;
115            }
116            return null;
117        }
118    
119        /**
120         * Write out the entire file
121         *
122         * @param out
123         */
124        public void write() {
125            indentPrint("public class " + calcClassName(servKey, xmlType));
126            println(" extends InquirableImpl");
127            importsAdd("org.kuali.rice.krad.inquiry.InquirableImpl");
128            openBrace();
129            writeLogic();
130            closeBrace();
131    
132            this.writeJavaClassAndImportsOutToFile();
133            this.getOut().close();
134        }
135    
136        private void writeLogic() {
137    
138            String initUpper = GetterSetterNameCalculator.calcInitUpper(servKey);
139            String initLower = GetterSetterNameCalculator.calcInitLower(servKey);
140            String infoClass = GetterSetterNameCalculator.calcInitUpper(xmlType.getName());
141            String serviceClass = GetterSetterNameCalculator.calcInitUpper(service.getName());
142            String serviceVar = GetterSetterNameCalculator.calcInitLower(service.getName());
143            importsAdd(service.getImplProject() + "." + service.getName());
144            importsAdd("org.apache.log4j.Logger");
145            indentPrintln("private static final Logger LOG = Logger.getLogger(" + calcClassName(servKey, xmlType) + ".class);");
146            indentPrintln("private transient " + serviceClass + " " + serviceVar + ";");
147            MessageStructure pk = this.getPrimaryKey(xmlType.getName());
148            indentPrintln("private final static String PRIMARY_KEY = \"" + pk.getShortName() + "\";");
149    
150            println("");
151            indentPrintln("@Override");
152            importsAdd(xmlType.getJavaPackage() + "." + infoClass);
153            importsAdd(List.class.getName());
154            importsAdd(Map.class.getName());
155    //        importsAdd(LookupForm.class.getName());
156    //        importsAdd(QueryByCriteria.class.getName());
157    //        importsAdd(Predicate.class.getName());
158    //        importsAdd(PredicateFactory.class.getName());
159            importsAdd(GlobalResourceLoader.class.getName());
160            XmlType contextInfo = finder.findXmlType("contextInfo");
161            importsAdd(contextInfo.getJavaPackage() + "." + contextInfo.getName());
162            importsAdd("org.kuali.student.common.util.ContextBuilder");
163    //        importsAdd(PredicateFactory.class.getName());
164            importsAdd(ArrayList.class.getName());
165            importsAdd(QName.class.getName());
166    //        importsAdd (PredicateFactory.class.getName());
167            indentPrintln("public " + infoClass + " retrieveDataObject(Map<String, String> parameters)");
168            openBrace();
169            indentPrintln("String key = parameters.get(PRIMARY_KEY);");
170            indentPrintln("try");
171            openBrace();
172            String getMethod = calcGetMethod();
173            if (getMethod == null) {
174                indentPrintln("// WARNING: Missing get method please add it to the service contract: " + servKey + "." + xmlType.getName());
175                getMethod = "get" + GetterSetterNameCalculator.calcInitUpper(xmlType.getName());
176            }
177            indentPrintln("" + infoClass + " info = this.get" + serviceClass + "()." + getMethod + "(key, getContextInfo());");
178            indentPrintln("return info;");
179            closeBrace();
180            indentPrintln("catch (Exception ex) {");
181            indentPrintln("    throw new RuntimeException(ex);");
182            indentPrintln("}");
183            closeBrace();
184            writeServiceGetterAndSetter (this, serviceClass, serviceVar, xmlType);
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            return null;
194        }
195        public static void writeServiceGetterAndSetter (JavaClassWriter out, String serviceClass, String serviceVar, XmlType xmlType) {
196            
197            out.println ("");
198            out.indentPrintln("public void set" + serviceClass + "(" + serviceClass + " " + serviceVar + ")");
199            out.openBrace();
200            out.indentPrintln("    this." + serviceVar + " = " + serviceVar + ";");
201            out.closeBrace();
202            out.println("");
203            out.indentPrintln("public " + serviceClass + " get" + serviceClass + "()");
204            out.openBrace();
205            out.indentPrintln("if (" + serviceVar + " == null)");
206            out.openBrace();
207            String serviceConstants = calcServiceContantsName(serviceClass);
208            out.importsAdd(calcServiceContantsPackage(xmlType) + "." + serviceConstants);
209            out.indentPrintln("QName qname = new QName(" + serviceConstants + ".NAMESPACE," + serviceConstants + ".SERVICE_NAME_LOCAL_PART);");
210            out.indentPrintln(serviceVar + " = (" + serviceClass + ") GlobalResourceLoader.getService(qname);");
211            out.closeBrace();
212            out.indentPrintln("return this." + serviceVar + ";");
213            out.closeBrace();
214            out.println("");
215            out.indentPrintln("private ContextInfo getContextInfo() {");
216            out.indentPrintln("    return ContextBuilder.loadContextInfo();");
217            out.indentPrintln("}");
218        }
219    
220        public static String calcServiceContantsName(String serviceClass) {
221            if (serviceClass.equals("LRCService")) {
222                return "LrcServiceConstants";
223            }
224            return serviceClass + "Constants";
225        }
226        private static Map<String, String> SERVICE_CLASS_PACKAGE;
227    
228        {
229            SERVICE_CLASS_PACKAGE = new HashMap<String, String>();
230            SERVICE_CLASS_PACKAGE.put("lum", "org.kuali.student.r2.lum.util.constants");
231            SERVICE_CLASS_PACKAGE.put("lum", "org.kuali.student.r2.lum.util.constants");
232            SERVICE_CLASS_PACKAGE.put("core", "org.kuali.student.r2.core.constants");
233            SERVICE_CLASS_PACKAGE.put("enrollment", "org.kuali.student.r2.common.util.constants");
234        }
235    
236        public static String calcServiceContantsPackage(XmlType xmlType) {
237            if (xmlType.getJavaPackage().contains(".enrollment.")) {
238                return SERVICE_CLASS_PACKAGE.get("enrollment");
239            }
240            if (xmlType.getJavaPackage().contains(".core.")) {
241                return SERVICE_CLASS_PACKAGE.get("core");
242            }
243            if (xmlType.getJavaPackage().contains(".lum.")) {
244                return SERVICE_CLASS_PACKAGE.get("lum");
245            }
246            return "org.kuali.student.r2.common.util.constants";
247        }
248    
249        private String calcGetMethod() {
250            ServiceMethod method = this.findGetMethod();
251            if (method != null) {
252                return method.getName();
253            }
254            return null;
255        }
256    
257        private ServiceMethod findGetMethod() {
258            String infoClass = GetterSetterNameCalculator.calcInitUpper(xmlType.getName());
259            for (ServiceMethod method : methods) {
260                if (method.getName().startsWith("get")) {
261                    if (method.getReturnValue().getType().equalsIgnoreCase(infoClass)) {
262                        if (method.getParameters().size() == 2) {
263                            if (method.getParameters().get(0).getType().equalsIgnoreCase("String")) {
264                                return method;
265                            }
266                        }
267                    }
268                }
269            }
270            return null;
271        }
272    }