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