001/**
002 * Copyright 2004-2014 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 */
016package org.kuali.student.admin.ui.mojo;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022import javax.xml.namespace.QName;
023import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
024import org.kuali.student.contract.model.MessageStructure;
025import org.kuali.student.contract.model.Service;
026
027import org.kuali.student.contract.model.ServiceContractModel;
028import org.kuali.student.contract.model.ServiceMethod;
029import org.kuali.student.contract.model.XmlType;
030import org.kuali.student.contract.model.util.ModelFinder;
031import org.kuali.student.contract.writer.JavaClassWriter;
032import org.kuali.student.contract.writer.service.GetterSetterNameCalculator;
033
034/**
035 *
036 * @author nwright
037 */
038public 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}