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 */ 016 package org.kuali.student.admin.ui.mojo; 017 018 import java.util.ArrayList; 019 import java.util.List; 020 import java.util.Map; 021 import javax.xml.namespace.QName; 022 import org.kuali.rice.core.api.criteria.Predicate; 023 import org.kuali.rice.core.api.criteria.PredicateFactory; 024 import org.kuali.rice.core.api.criteria.QueryByCriteria; 025 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader; 026 import org.kuali.rice.krad.web.form.LookupForm; 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.ServiceMethodParameter; 032 import org.kuali.student.contract.model.XmlType; 033 import org.kuali.student.contract.model.util.ModelFinder; 034 import org.kuali.student.contract.writer.JavaClassWriter; 035 import org.kuali.student.contract.writer.service.GetterSetterNameCalculator; 036 037 /** 038 * 039 * @author nwright 040 */ 041 public 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 }