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.remote.impl.mojo; 017 018 import java.util.ArrayList; 019 import java.util.List; 020 import org.kuali.student.contract.model.Service; 021 022 import org.kuali.student.contract.model.ServiceContractModel; 023 import org.kuali.student.contract.model.ServiceMethod; 024 import org.kuali.student.contract.model.ServiceMethodError; 025 import org.kuali.student.contract.model.ServiceMethodParameter; 026 import org.kuali.student.contract.model.XmlType; 027 import org.kuali.student.contract.model.util.ModelFinder; 028 import org.kuali.student.contract.writer.JavaClassWriter; 029 import org.kuali.student.contract.writer.service.GetterSetterNameCalculator; 030 import org.kuali.student.contract.writer.service.MessageStructureTypeCalculator; 031 import org.kuali.student.contract.writer.service.ServiceExceptionWriter; 032 033 /** 034 * 035 * @author nwright 036 */ 037 public class RemoteImplServiceWriter extends JavaClassWriter { 038 039 private ServiceContractModel model; 040 private ModelFinder finder; 041 private String directory; 042 private String rootPackage; 043 private String servKey; 044 private List<ServiceMethod> methods; 045 046 public RemoteImplServiceWriter(ServiceContractModel model, 047 String directory, 048 String rootPackage, 049 String servKey, 050 List<ServiceMethod> methods) { 051 super(directory + "/main/java", calcPackage(servKey, rootPackage), calcClassName(servKey)); 052 this.model = model; 053 this.finder = new ModelFinder(model); 054 this.directory = directory; 055 this.rootPackage = rootPackage; 056 this.servKey = servKey; 057 this.methods = methods; 058 } 059 060 public static String calcPackage(String servKey, String rootPackage) { 061 // String pack = rootPackage + "." + servKey.toLowerCase() + "."; 062 // StringBuffer buf = new StringBuffer (service.getVersion ().length ()); 063 // for (int i = 0; i < service.getVersion ().length (); i ++) 064 // { 065 // char c = service.getVersion ().charAt (i); 066 // c = Character.toLowerCase (c); 067 // if (Character.isLetter (c)) 068 // { 069 // buf.append (c); 070 // continue; 071 // } 072 // if (Character.isDigit (c)) 073 // { 074 // buf.append (c); 075 // } 076 // } 077 // pack = pack + buf.toString (); 078 // pack = pack + "service.decorators"; 079 // return pack; 080 return rootPackage; 081 } 082 083 public static String calcClassName(String servKey) { 084 String name = GetterSetterNameCalculator.calcInitUpper(servKey + "ServiceRemoteImpl"); 085 if (name.startsWith("RICE.")) { 086 name = name.substring("RICE.".length()); 087 } 088 return name; 089 } 090 091 public static String calcDecoratorClassName(String servKey) { 092 String name = GetterSetterNameCalculator.calcInitUpper(servKey + "ServiceDecorator"); 093 if (name.startsWith("RICE.")) { 094 name = name.substring("RICE.".length()); 095 } 096 return name; 097 } 098 099 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 }