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 }