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.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 String pack = rootPackage + "." + servKey.toLowerCase(); 071 // StringBuffer buf = new StringBuffer (service.getVersion ().length ()); 072 // for (int i = 0; i < service.getVersion ().length (); i ++) 073 // { 074 // char c = service.getVersion ().charAt (i); 075 // c = Character.toLowerCase (c); 076 // if (Character.isLetter (c)) 077 // { 078 // buf.append (c); 079 // continue; 080 // } 081 // if (Character.isDigit (c)) 082 // { 083 // buf.append (c); 084 // } 085 // } 086 // pack = pack + buf.toString (); 087 // pack = pack + "service.decorators"; 088 return pack; 089 // return rootPackage; 090 } 091 092 public static String calcClassName(String servKey, String xmlTypeName) { 093 return GetterSetterNameCalculator.calcInitUpper(xmlTypeName) + "AdminLookupableImpl"; 094 } 095 096 public static String calcClassName(String servKey, XmlType xmlType) { 097 return calcClassName(servKey, xmlType.getName()); 098 } 099 100 public static String calcDecoratorClassName(String servKey) { 101 return GetterSetterNameCalculator.calcInitUpper(servKey + "ServiceDecorator"); 102 } 103 104 private static enum MethodType { 105 106 VALIDATE, CREATE, UPDATE 107 }; 108 109 private MethodType calcMethodType(ServiceMethod method) { 110 if (method.getName().startsWith("validate")) { 111 return MethodType.VALIDATE; 112 } 113 if (method.getName().startsWith("create")) { 114 return MethodType.CREATE; 115 } 116 if (method.getName().startsWith("update")) { 117 return MethodType.UPDATE; 118 } 119 return null; 120 } 121 122 /** 123 * Write out the entire file 124 * 125 * @param out 126 */ 127 public void write() { 128 indentPrint("public class " + calcClassName(servKey, xmlType)); 129 println(" extends LookupableImpl"); 130 importsAdd("org.kuali.rice.krad.lookup.LookupableImpl"); 131 openBrace(); 132 writeLogic(); 133 closeBrace(); 134 135 this.writeJavaClassAndImportsOutToFile(); 136 this.getOut().close(); 137 } 138 139 private void writeLogic() { 140 141 String initUpper = GetterSetterNameCalculator.calcInitUpper(servKey); 142 String initLower = GetterSetterNameCalculator.calcInitLower(servKey); 143 String infoClass = GetterSetterNameCalculator.calcInitUpper(xmlType.getName()); 144 String serviceClass = GetterSetterNameCalculator.calcInitUpper(service.getName()); 145 String serviceVar = GetterSetterNameCalculator.calcInitLower(service.getName()); 146 importsAdd(service.getImplProject() + "." + service.getName()); 147 importsAdd("org.apache.log4j.Logger"); 148 indentPrintln("private static final Logger LOG = Logger.getLogger(" + calcClassName(servKey, xmlType) + ".class);"); 149 indentPrintln("private transient " + serviceClass + " " + serviceVar + ";"); 150 151 println(""); 152 indentPrintln("@Override"); 153 importsAdd(xmlType.getJavaPackage() + "." + infoClass); 154 importsAdd(List.class.getName()); 155 importsAdd(Map.class.getName()); 156 importsAdd(LookupForm.class.getName()); 157 importsAdd(QueryByCriteria.class.getName()); 158 importsAdd(Predicate.class.getName()); 159 importsAdd(PredicateFactory.class.getName()); 160 importsAdd(GlobalResourceLoader.class.getName()); 161 XmlType contextInfo = finder.findXmlType("contextInfo"); 162 importsAdd(contextInfo.getJavaPackage() + "." + contextInfo.getName()); 163 importsAdd("org.kuali.student.common.util.ContextBuilder"); 164 importsAdd(PredicateFactory.class.getName()); 165 importsAdd(ArrayList.class.getName()); 166 importsAdd(QName.class.getName()); 167 // importsAdd (PredicateFactory.class.getName()); 168 indentPrintln("protected List<" + infoClass + "> getSearchResults(LookupForm lookupForm, Map<String, String> fieldValues, boolean unbounded)"); 169 openBrace(); 170 indentPrintln("QueryByCriteria.Builder qBuilder = QueryByCriteria.Builder.create();"); 171 indentPrintln("List<Predicate> pList = new ArrayList<Predicate>();"); 172 indentPrintln("for (String fieldName : fieldValues.keySet())"); 173 openBrace(); 174 indentPrintln("String value = fieldValues.get(fieldName);"); 175 indentPrintln("if (value != null && !value.isEmpty())"); 176 openBrace(); 177 indentPrintln("if (fieldName.equals(\"maxResultsToReturn\"))"); 178 openBrace(); 179 indentPrintln("qBuilder.setMaxResults (Integer.parseInt(value));"); 180 indentPrintln("continue;"); 181 closeBrace(); 182 indentPrintln("pList.add(PredicateFactory.equal(fieldName, value));"); 183 closeBrace(); 184 closeBrace(); 185 indentPrintln("if (!pList.isEmpty())"); 186 openBrace(); 187 indentPrintln("qBuilder.setPredicates(PredicateFactory.and(pList.toArray(new Predicate[pList.size()])));"); 188 closeBrace(); 189 indentPrintln("try"); 190 openBrace(); 191 String searchMethodName = calcSearchMethodName(); 192 if (searchMethodName == null) { 193 indentPrintln("// WARNING: Missing searchMethod please add it to the service contract: " + servKey + "." + xmlType.getName()); 194 searchMethodName = "searchFor" + GetterSetterNameCalculator.calcInitUpper(xmlType.getName()) + "s"; 195 } 196 indentPrintln("List<" + infoClass + "> list = this.get" + serviceClass + "()." + searchMethodName + "(qBuilder.build(), getContextInfo());"); 197 indentPrintln("return list;"); 198 closeBrace(); 199 indentPrintln("catch (Exception ex) {"); 200 indentPrintln(" throw new RuntimeException(ex);"); 201 indentPrintln("}"); 202 closeBrace(); 203 204 AdminUiInquirableWriter.writeServiceGetterAndSetter(this, serviceClass, serviceVar, xmlType); 205 } 206 207 private String calcSearchMethodName() { 208 ServiceMethod method = this.findSearchMethod(); 209 if (method != null) { 210 return method.getName(); 211 } 212 return null; 213 } 214 215 private ServiceMethod findSearchMethod() { 216 return findSearchMethod(xmlType, methods); 217 } 218 219 public static ServiceMethod findSearchMethod(XmlType xmlType, List<ServiceMethod> methods) { 220 for (ServiceMethod method : methods) { 221 if (hasProperReturnTypeForSearchMethod(xmlType, method)) { 222 if (hasProperParameterForSearchMethod(xmlType, method)) { 223 return method; 224 } 225 } 226 } 227 return null; 228 } 229 230 private static boolean hasProperReturnTypeForSearchMethod(XmlType xmlType, ServiceMethod method) { 231 String returnValueTypeLower = method.getReturnValue().getType().toLowerCase(); 232 if (returnValueTypeLower.endsWith("List".toLowerCase())) { 233 if (returnValueTypeLower.startsWith(xmlType.getName().toLowerCase())) { 234 return true; 235 } 236 } 237 if (returnValueTypeLower.endsWith("QueryResults".toLowerCase())) { 238 if (returnValueTypeLower.startsWith(xmlType.getName().toLowerCase())) { 239 return true; 240 } 241 } 242 return false; 243 } 244 245 private static boolean hasProperParameterForSearchMethod(XmlType xmlType, ServiceMethod method) { 246 for (ServiceMethodParameter parameter : method.getParameters()) { 247 if (parameter.getType().equals("QueryByCriteria")) { 248 return true; 249 } 250 } 251 return false; 252 } 253 }