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          String name = GetterSetterNameCalculator.calcInitUpper(servKey + "ServiceRemoteImpl");
85          if (name.startsWith("RICE.")) {
86           name = name.substring("RICE.".length());   
87          }
88          return name;
89      }
90  
91      public static String calcDecoratorClassName(String servKey) {
92          String name = GetterSetterNameCalculator.calcInitUpper(servKey + "ServiceDecorator");
93          if (name.startsWith("RICE.")) {
94           name = name.substring("RICE.".length());   
95          }
96          return name;
97      }
98  
99      private static enum MethodType {
100 
101         VALIDATE, CREATE, UPDATE
102     };
103 
104     private MethodType calcMethodType(ServiceMethod method) {
105         if (method.getName().startsWith("validate")) {
106             return MethodType.VALIDATE;
107         }
108         if (method.getName().startsWith("create")) {
109             return MethodType.CREATE;
110         }
111         if (method.getName().startsWith("update")) {
112             return MethodType.UPDATE;
113         }
114         return null;
115     }
116 
117     /**
118      * Write out the entire file
119      *
120      * @param out
121      */
122     public void write() {
123         indentPrint("public class " + calcClassName(servKey));
124         println(" extends " + calcDecoratorClassName(servKey));
125         // TODO: figure out how to add import for the decorator
126         openBrace();
127         writeHostUrlGetterSetter();
128 
129         indentPrintln("//");
130         indentPrintln("// Have to override and check for null because of a bug in CXF 2.3.8 our current version");
131         indentPrintln("// It was fixed in 2.6.1 but 2.3.8 still renders empty lists as null when transported by soap");
132         indentPrintln("// see http://stackoverflow.com/questions/11384986/apache-cxf-web-services-problems");
133         indentPrintln("//");
134         for (ServiceMethod method : methods) {
135             if (!method.getReturnValue().getType().endsWith("List")) {
136                 continue;
137             }
138 
139             indentPrintln("");
140 //            indentPrintln("/**");
141 //            indentPrintWrappedComment(method.getDescription());
142 //            indentPrintln("* ");
143 //            for (ServiceMethodParameter param : method.getParameters()) {
144 //                indentPrintWrappedComment("@param " + param.getName() + " - "
145 //                        + param.getType() + " - "
146 //                        + param.getDescription());
147 //            }
148 //            indentPrintWrappedComment("@return " + method.getReturnValue().
149 //                    getDescription());
150 //            indentPrintln("*/");
151             indentPrintln("@Override");
152             String type = method.getReturnValue().getType();
153             String realType = stripList(type);
154             indentPrint("public " + calcType(type, realType) + " " + method.getName()
155                     + "(");
156             // now do parameters
157             String comma = "";
158             for (ServiceMethodParameter param : method.getParameters()) {
159                 type = param.getType();
160                 realType = stripList(type);
161                 print(comma);
162                 print(calcType(type, realType));
163                 print(" ");
164                 print(param.getName());
165                 comma = ", ";
166             }
167             println(")");
168             // now do exceptions
169             comma = "throws ";
170             incrementIndent();
171             for (ServiceMethodError error : method.getErrors()) {
172                 indentPrint(comma);
173                 String exceptionClassName = calcExceptionClassName(error);
174                 String exceptionPackageName = this.calcExceptionPackageName(error);
175                 println(exceptionClassName);
176                 this.importsAdd(exceptionPackageName + "." + exceptionClassName);
177                 comma = "      ,";
178             }
179             decrementIndent();
180             openBrace();
181             type = method.getReturnValue().getType();
182             realType = stripList(type);
183             XmlType retValXmlType = finder.findXmlType(realType);
184             importsAdd(retValXmlType.getJavaPackage() + "." + retValXmlType.getName());
185             indentPrint("List<" + retValXmlType.getName() + "> list = this.getNextDecorator ()." + method.getName() + "(");
186             comma = "";
187             for (ServiceMethodParameter param : method.getParameters()) {
188                 type = param.getType();
189                 realType = stripList(type);
190                 print(comma);
191                 print(param.getName());
192                 comma = ", ";
193             }
194             println(");");
195             indentPrintln("if (list == null)");
196             openBrace();
197             importsAdd(ArrayList.class.getName());
198             indentPrintln("return new ArrayList<" + retValXmlType.getName() + "> ();");
199             closeBrace();
200             indentPrintln("return list;");
201             closeBrace();
202         }
203         closeBrace();
204 
205         this.writeJavaClassAndImportsOutToFile();
206         this.getOut().close();
207     }
208 
209     private String calcType(String type, String realType) {
210         XmlType t = finder.findXmlType(this.stripList(type));
211         return MessageStructureTypeCalculator.calculate(this, model, type, realType,
212                 t.getJavaPackage());
213     }
214 
215     private String stripList(String str) {
216         return GetterSetterNameCalculator.stripList(str);
217     }
218 
219     private String calcExceptionClassName(ServiceMethodError error) {
220         if (error.getClassName() == null) {
221             return ServiceExceptionWriter.calcClassName(error.getType());
222         }
223         return error.getClassName();
224     }
225 
226     private String calcExceptionPackageName(ServiceMethodError error) {
227         if (error.getClassName() == null) {
228             return ServiceExceptionWriter.calcPackage(rootPackage);
229         }
230         return error.getPackageName();
231     }
232 
233     private void writeHostUrlGetterSetter() {
234 
235         String initUpper = GetterSetterNameCalculator.calcInitUpper(servKey);
236         if (initUpper.startsWith("RICE.")) {
237             initUpper = initUpper.substring("RICE.".length());
238         }
239 
240         indentPrintln("private String hostUrl;");
241         println("");
242         indentPrintln("public String getHostUrl()");
243         openBrace();
244         indentPrintln("return hostUrl;");
245         closeBrace();
246         indentPrintln("public void setHostUrl(String hostUrl)");
247         openBrace();
248         indentPrintln("this.hostUrl = hostUrl;");
249         indentPrintln("if (hostUrl == null)");
250         openBrace();
251         indentPrintln("this.setNextDecorator(null);");
252         indentPrintln("return;");
253         closeBrace();
254         indentPrintln("URL wsdlURL;");
255         indentPrintln("try");
256         openBrace();
257         String constantsFile = initUpper + "ServiceConstants";
258         // TODO: figure out how to add import for the service constants
259         indentPrintln("String urlStr = hostUrl + \"/services/\" + " + constantsFile + ".SERVICE_NAME_LOCAL_PART + \"?wsdl\";");
260         indentPrintln("wsdlURL = new URL(urlStr);");
261         closeBrace();
262         indentPrintln("catch (MalformedURLException ex)");
263         openBrace();
264         indentPrintln("throw new IllegalArgumentException(ex);");
265         closeBrace();
266 
267         importsAdd("java.net.MalformedURLException");
268         importsAdd("java.net.URL");
269         importsAdd("javax.xml.namespace.QName");
270         importsAdd("javax.xml.ws.Service");
271         Service service = finder.findService(servKey);
272         importsAdd(service.getImplProject() + "." + service.getName());
273 
274         indentPrintln("QName qname = new QName(" + constantsFile + ".NAMESPACE, " + constantsFile + ".SERVICE_NAME_LOCAL_PART);");
275         indentPrintln("Service factory = Service.create(wsdlURL, qname);");
276         indentPrintln(service.getName() + " port = factory.getPort(" + service.getName() + ".class);");
277         indentPrintln("this.setNextDecorator(port);");
278         closeBrace();
279 
280     }
281 }