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    }