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