View Javadoc

1   /*
2    * Copyright 2009 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may	obtain a copy of the License at
7    *
8    * 	http://www.osedu.org/licenses/ECL-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.student.remote.impl.mojo;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  import org.kuali.student.contract.model.Service;
21  
22  import org.kuali.student.contract.model.ServiceContractModel;
23  import org.kuali.student.contract.model.ServiceMethod;
24  import org.kuali.student.contract.model.ServiceMethodError;
25  import org.kuali.student.contract.model.ServiceMethodParameter;
26  import org.kuali.student.contract.model.XmlType;
27  import org.kuali.student.contract.model.util.ModelFinder;
28  import org.kuali.student.contract.writer.JavaClassWriter;
29  import org.kuali.student.contract.writer.service.GetterSetterNameCalculator;
30  import org.kuali.student.contract.writer.service.MessageStructureTypeCalculator;
31  import org.kuali.student.contract.writer.service.ServiceExceptionWriter;
32  
33  /**
34   *
35   * @author nwright
36   */
37  public class RemoteImplServiceWriter extends JavaClassWriter {
38  
39      private ServiceContractModel model;
40      private ModelFinder finder;
41      private String directory;
42      private String rootPackage;
43      private String servKey;
44      private List<ServiceMethod> methods;
45  
46      public RemoteImplServiceWriter(ServiceContractModel model,
47              String directory,
48              String rootPackage,
49              String servKey,
50              List<ServiceMethod> methods) {
51          super(directory + "/main/java", calcPackage(servKey, rootPackage), calcClassName(servKey));
52          this.model = model;
53          this.finder = new ModelFinder(model);
54          this.directory = directory;
55          this.rootPackage = rootPackage;
56          this.servKey = servKey;
57          this.methods = methods;
58      }
59  
60      public static String calcPackage(String servKey, String rootPackage) {
61  //        String pack = rootPackage + "." + servKey.toLowerCase() + ".";
62  //  StringBuffer buf = new StringBuffer (service.getVersion ().length ());
63  //  for (int i = 0; i < service.getVersion ().length (); i ++)
64  //  {
65  //   char c = service.getVersion ().charAt (i);
66  //   c = Character.toLowerCase (c);
67  //   if (Character.isLetter (c))
68  //   {
69  //    buf.append (c);
70  //    continue;
71  //   }
72  //   if (Character.isDigit (c))
73  //   {
74  //    buf.append (c);
75  //   }
76  //  }
77  //  pack = pack + buf.toString ();
78  //        pack = pack + "service.decorators";
79  //        return pack;
80          return rootPackage;
81      }
82  
83      public static String calcClassName(String servKey) {
84          return GetterSetterNameCalculator.calcInitUpper(servKey + "ServiceRemoteImpl");
85      }
86  
87      public static String calcDecoratorClassName(String servKey) {
88          return GetterSetterNameCalculator.calcInitUpper(servKey + "ServiceDecorator");
89      }
90  
91      private static enum MethodType {
92  
93          VALIDATE, CREATE, UPDATE
94      };
95  
96      private MethodType calcMethodType(ServiceMethod method) {
97          if (method.getName().startsWith("validate")) {
98              return MethodType.VALIDATE;
99          }
100         if (method.getName().startsWith("create")) {
101             return MethodType.CREATE;
102         }
103         if (method.getName().startsWith("update")) {
104             return MethodType.UPDATE;
105         }
106         return null;
107     }
108 
109     /**
110      * Write out the entire file
111      *
112      * @param out
113      */
114     public void write() {
115         indentPrint("public class " + calcClassName(servKey));
116         println(" extends " + calcDecoratorClassName(servKey));
117         // TODO: figure out how to add import for the decorator
118         openBrace();
119         writeHostUrlGetterSetter();
120 
121         indentPrintln("//");
122         indentPrintln("// Have to override and check for null because of a bug in CXF 2.3.8 our current version");
123         indentPrintln("// It was fixed in 2.6.1 but 2.3.8 still renders empty lists as null when transported by soap");
124         indentPrintln("// see http://stackoverflow.com/questions/11384986/apache-cxf-web-services-problems");
125         indentPrintln("//");
126         for (ServiceMethod method : methods) {
127             if (!method.getReturnValue().getType().endsWith("List")) {
128                 continue;
129             }
130 
131             indentPrintln("");
132 //            indentPrintln("/**");
133 //            indentPrintWrappedComment(method.getDescription());
134 //            indentPrintln("* ");
135 //            for (ServiceMethodParameter param : method.getParameters()) {
136 //                indentPrintWrappedComment("@param " + param.getName() + " - "
137 //                        + param.getType() + " - "
138 //                        + param.getDescription());
139 //            }
140 //            indentPrintWrappedComment("@return " + method.getReturnValue().
141 //                    getDescription());
142 //            indentPrintln("*/");
143             indentPrintln("@Override");
144             String type = method.getReturnValue().getType();
145             String realType = stripList(type);
146             indentPrint("public " + calcType(type, realType) + " " + method.getName()
147                     + "(");
148             // now do parameters
149             String comma = "";
150             for (ServiceMethodParameter param : method.getParameters()) {
151                 type = param.getType();
152                 realType = stripList(type);
153                 print(comma);
154                 print(calcType(type, realType));
155                 print(" ");
156                 print(param.getName());
157                 comma = ", ";
158             }
159             println(")");
160             // now do exceptions
161             comma = "throws ";
162             incrementIndent();
163             for (ServiceMethodError error : method.getErrors()) {
164                 indentPrint(comma);
165                 String exceptionClassName = calcExceptionClassName(error);
166                 String exceptionPackageName = this.calcExceptionPackageName(error);
167                 println(exceptionClassName);
168                 this.importsAdd(exceptionPackageName + "." + exceptionClassName);
169                 comma = "      ,";
170             }
171             decrementIndent();
172             openBrace();
173             type = method.getReturnValue().getType();
174             realType = stripList(type);
175             XmlType retValXmlType = finder.findXmlType(realType);
176             importsAdd(retValXmlType.getJavaPackage() + "." + retValXmlType.getName());
177             indentPrint("List<" + retValXmlType.getName() + "> list = this.getNextDecorator ()." + method.getName() + "(");
178             comma = "";
179             for (ServiceMethodParameter param : method.getParameters()) {
180                 type = param.getType();
181                 realType = stripList(type);
182                 print(comma);
183                 print(param.getName());
184                 comma = ", ";
185             }
186             println(");");
187             indentPrintln("if (list == null)");
188             openBrace();
189             importsAdd(ArrayList.class.getName());
190             indentPrintln("return new ArrayList<" + retValXmlType.getName() + "> ();");
191             closeBrace();
192             indentPrintln("return list;");
193             closeBrace();
194         }
195         closeBrace();
196 
197         this.writeJavaClassAndImportsOutToFile();
198         this.getOut().close();
199     }
200 
201     private String calcType(String type, String realType) {
202         XmlType t = finder.findXmlType(this.stripList(type));
203         return MessageStructureTypeCalculator.calculate(this, model, type, realType,
204                 t.getJavaPackage());
205     }
206 
207     private String stripList(String str) {
208         return GetterSetterNameCalculator.stripList(str);
209     }
210 
211     private String calcExceptionClassName(ServiceMethodError error) {
212         if (error.getClassName() == null) {
213             return ServiceExceptionWriter.calcClassName(error.getType());
214         }
215         return error.getClassName();
216     }
217 
218     private String calcExceptionPackageName(ServiceMethodError error) {
219         if (error.getClassName() == null) {
220             return ServiceExceptionWriter.calcPackage(rootPackage);
221         }
222         return error.getPackageName();
223     }
224 
225     private void writeHostUrlGetterSetter() {
226 
227         String initUpper = GetterSetterNameCalculator.calcInitUpper(servKey);
228 
229         indentPrintln("private String hostUrl;");
230         println("");
231         indentPrintln("public String getHostUrl()");
232         openBrace();
233         indentPrintln("return hostUrl;");
234         closeBrace();
235         indentPrintln("public void setHostUrl(String hostUrl)");
236         openBrace();
237         indentPrintln("this.hostUrl = hostUrl;");
238         indentPrintln("if (hostUrl == null)");
239         openBrace();
240         indentPrintln("this.setNextDecorator(null);");
241         indentPrintln("return;");
242         closeBrace();
243         indentPrintln("URL wsdlURL;");
244         indentPrintln("try");
245         openBrace();
246         String constantsFile = initUpper + "ServiceConstants";
247         // TODO: figure out how to add import for the service constants
248         indentPrintln("String urlStr = hostUrl + \"/services/\" + " + constantsFile + ".SERVICE_NAME_LOCAL_PART + \"?wsdl\";");
249         indentPrintln("wsdlURL = new URL(urlStr);");
250         closeBrace();
251         indentPrintln("catch (MalformedURLException ex)");
252         openBrace();
253         indentPrintln("throw new IllegalArgumentException(ex);");
254         closeBrace();
255 
256         importsAdd("java.net.MalformedURLException");
257         importsAdd("java.net.URL");
258         importsAdd("javax.xml.namespace.QName");
259         importsAdd("javax.xml.ws.Service");
260         Service service = finder.findService(servKey);
261         importsAdd(service.getImplProject() + "." + service.getName());
262 
263         indentPrintln("QName qname = new QName(" + constantsFile + ".NAMESPACE, " + constantsFile + ".SERVICE_NAME_LOCAL_PART);");
264         indentPrintln("Service factory = Service.create(wsdlURL, qname);");
265         indentPrintln(service.getName() + " port = factory.getPort(" + service.getName() + ".class);");
266         indentPrintln("this.setNextDecorator(port);");
267         closeBrace();
268 
269     }
270 }