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.List;
020import java.util.Map;
021import javax.xml.namespace.QName;
022import org.kuali.rice.core.api.criteria.Predicate;
023import org.kuali.rice.core.api.criteria.PredicateFactory;
024import org.kuali.rice.core.api.criteria.QueryByCriteria;
025import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
026import org.kuali.rice.krad.web.form.LookupForm;
027import org.kuali.student.contract.model.Service;
028
029import org.kuali.student.contract.model.ServiceContractModel;
030import org.kuali.student.contract.model.ServiceMethod;
031import org.kuali.student.contract.model.ServiceMethodParameter;
032import org.kuali.student.contract.model.XmlType;
033import org.kuali.student.contract.model.util.ModelFinder;
034import org.kuali.student.contract.writer.JavaClassWriter;
035import org.kuali.student.contract.writer.service.GetterSetterNameCalculator;
036
037/**
038 *
039 * @author nwright
040 */
041public class AdminUiLookupableWriter extends JavaClassWriter {
042
043    private ServiceContractModel model;
044    private ModelFinder finder;
045    private String directory;
046    private String rootPackage;
047    private String servKey;
048    private Service service;
049    private XmlType xmlType;
050    private List<ServiceMethod> methods;
051
052    public AdminUiLookupableWriter(ServiceContractModel model,
053            String directory,
054            String rootPackage,
055            String servKey,
056            XmlType xmlType,
057            List<ServiceMethod> methods) {
058        super(directory + "/" + "java", calcPackage(servKey, rootPackage, xmlType), calcClassName(servKey, xmlType));
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    public static String calcPackage(String servKey, String rootPackage, XmlType xmlType) {
070        return AdminUiInquirableWriter.calcPackage(servKey, rootPackage, xmlType);
071    }
072
073    public static String calcClassName(String servKey, String xmlTypeName) {
074        return GetterSetterNameCalculator.calcInitUpper(xmlTypeName) + "AdminLookupableImpl";
075    }
076
077    public static String calcClassName(String servKey, XmlType xmlType) {
078        return calcClassName(servKey, xmlType.getName());
079    }
080
081    public static String calcDecoratorClassName(String servKey) {
082        return GetterSetterNameCalculator.calcInitUpper(servKey + "ServiceDecorator");
083    }
084
085    private static enum MethodType {
086
087        VALIDATE, CREATE, UPDATE
088    };
089
090    private MethodType calcMethodType(ServiceMethod method) {
091        if (method.getName().startsWith("validate")) {
092            return MethodType.VALIDATE;
093        }
094        if (method.getName().startsWith("create")) {
095            return MethodType.CREATE;
096        }
097        if (method.getName().startsWith("update")) {
098            return MethodType.UPDATE;
099        }
100        return null;
101    }
102
103    /**
104     * Write out the entire file
105     *
106     * @param out
107     */
108    public void write() {
109        indentPrint("public class " + calcClassName(servKey, xmlType));
110        println(" extends LookupableImpl");
111        importsAdd("org.kuali.rice.krad.lookup.LookupableImpl");
112        openBrace();
113        writeLogic();
114        closeBrace();
115
116        this.writeJavaClassAndImportsOutToFile();
117        this.getOut().close();
118    }
119
120    private void writeLogic() {
121
122        String initUpper = GetterSetterNameCalculator.calcInitUpper(servKey);
123        String initLower = GetterSetterNameCalculator.calcInitLower(servKey);
124        String infoClass = GetterSetterNameCalculator.calcInitUpper(xmlType.getName());
125        String serviceClass = GetterSetterNameCalculator.calcInitUpper(service.getName());
126        String serviceVar = GetterSetterNameCalculator.calcInitLower(service.getName());
127        importsAdd(service.getImplProject() + "." + service.getName());
128        importsAdd("org.apache.log4j.Logger");
129        indentPrintln("private static final Logger LOG = Logger.getLogger(" + calcClassName(servKey, xmlType) + ".class);");
130        indentPrintln("private transient " + serviceClass + " " + serviceVar + ";");
131        indentPrintln ("private static final long serialVersionUID = 1L;");
132
133        println("");
134        indentPrintln("@Override");
135        importsAdd(xmlType.getJavaPackage() + "." + infoClass);
136        importsAdd(List.class.getName());
137        importsAdd(Map.class.getName());
138        importsAdd(LookupForm.class.getName());
139        importsAdd(QueryByCriteria.class.getName());
140        importsAdd(Predicate.class.getName());
141        importsAdd(PredicateFactory.class.getName());
142        importsAdd(GlobalResourceLoader.class.getName());
143        XmlType contextInfo = finder.findXmlType("contextInfo");
144        importsAdd(contextInfo.getJavaPackage() + "." + contextInfo.getName());
145        importsAdd("org.kuali.student.common.util.ContextBuilder");
146        importsAdd(PredicateFactory.class.getName());
147        importsAdd(ArrayList.class.getName());
148        importsAdd(QName.class.getName());
149//        importsAdd (PredicateFactory.class.getName());
150        indentPrintln("protected List<" + infoClass + "> getSearchResults(LookupForm lookupForm, Map<String, String> fieldValues, boolean unbounded)");
151        openBrace();
152        indentPrintln("QueryByCriteria.Builder qBuilder = QueryByCriteria.Builder.create();");
153        indentPrintln("List<Predicate> pList = new ArrayList<Predicate>();");
154        indentPrintln("for (String fieldName : fieldValues.keySet())");
155        openBrace();
156        indentPrintln("String value = fieldValues.get(fieldName);");
157        indentPrintln("if (value != null && !value.isEmpty())");
158        openBrace();
159        indentPrintln("if (fieldName.equals(\"maxResultsToReturn\"))");
160        openBrace();
161        indentPrintln("qBuilder.setMaxResults (Integer.parseInt(value));");
162        indentPrintln("continue;");
163        closeBrace();
164        indentPrintln("pList.add(PredicateFactory.equal(fieldName, value));");
165        closeBrace();
166        closeBrace();
167        indentPrintln("if (!pList.isEmpty())");
168        openBrace();
169        indentPrintln("qBuilder.setPredicates(PredicateFactory.and(pList.toArray(new Predicate[pList.size()])));");
170        closeBrace();
171        indentPrintln("try");
172        openBrace();
173        String searchMethodName = calcSearchMethodName();
174        if (searchMethodName == null) {
175            indentPrintln("// WARNING: Missing searchMethod please add it to the service contract: " + servKey + "." + xmlType.getName());
176            searchMethodName = "searchFor" + GetterSetterNameCalculator.calcInitUpper(xmlType.getName()) + "s";
177        }
178        indentPrintln("List<" + infoClass + "> list = this.get" + serviceClass + "()." + searchMethodName + "(qBuilder.build(), getContextInfo());");
179        indentPrintln("return list;");
180        closeBrace();
181        indentPrintln("catch (Exception ex) {");
182        indentPrintln("    throw new RuntimeException(ex);");
183        indentPrintln("}");
184        closeBrace();
185
186        AdminUiInquirableWriter.writeServiceGetterAndSetter(this, serviceClass, serviceVar, xmlType);
187    }
188
189    private String calcSearchMethodName() {
190        ServiceMethod method = this.findSearchMethod();
191        if (method != null) {
192            return method.getName();
193        }
194        return null;
195    }
196
197    private ServiceMethod findSearchMethod() {
198        return findSearchMethod(xmlType, methods);
199    }
200
201    public static ServiceMethod findSearchMethod(XmlType xmlType, List<ServiceMethod> methods) {
202        for (ServiceMethod method : methods) {
203            if (hasProperReturnTypeForSearchMethod(xmlType, method)) {
204                if (hasProperParameterForSearchMethod(xmlType, method)) {
205                    return method;
206                }
207            }
208        }
209        return null;
210    }
211
212    private static boolean hasProperReturnTypeForSearchMethod(XmlType xmlType, ServiceMethod method) {
213        String returnValueTypeLower = method.getReturnValue().getType().toLowerCase();
214        if (returnValueTypeLower.endsWith("List".toLowerCase())) {
215            if (returnValueTypeLower.startsWith(xmlType.getName().toLowerCase())) {
216                return true;
217            }
218        }
219        if (returnValueTypeLower.endsWith("QueryResults".toLowerCase())) {
220            if (returnValueTypeLower.startsWith(xmlType.getName().toLowerCase())) {
221                return true;
222            }
223        }
224        return false;
225    }
226
227    private static boolean hasProperParameterForSearchMethod(XmlType xmlType, ServiceMethod method) {
228        for (ServiceMethodParameter parameter : method.getParameters()) {
229            if (parameter.getType().equals("QueryByCriteria")) {
230                return true;
231            }
232        }
233        return false;
234    }
235}