| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.netbeans.modules.websvc.rest.client; |
| |
| import com.sun.source.tree.AnnotationTree; |
| import com.sun.source.tree.ClassTree; |
| import com.sun.source.tree.ExpressionTree; |
| import com.sun.source.tree.MethodTree; |
| import com.sun.source.tree.ModifiersTree; |
| import com.sun.source.tree.Tree; |
| import com.sun.source.tree.TypeParameterTree; |
| import com.sun.source.tree.VariableTree; |
| import java.io.InputStreamReader; |
| import java.io.StringWriter; |
| import java.nio.charset.Charset; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.Set; |
| import java.util.StringTokenizer; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import javax.lang.model.element.Modifier; |
| import javax.lang.model.element.TypeElement; |
| import javax.xml.bind.JAXBElement; |
| import javax.xml.parsers.ParserConfigurationException; |
| import javax.xml.stream.XMLStreamException; |
| import org.apache.tools.ant.module.api.support.ActionUtils; |
| import org.netbeans.api.java.source.Comment; |
| import org.netbeans.api.java.source.Comment.Style; |
| import org.netbeans.api.java.source.TreeMaker; |
| import org.netbeans.api.java.source.WorkingCopy; |
| import org.netbeans.api.project.FileOwnerQuery; |
| import org.netbeans.api.project.Project; |
| import org.netbeans.api.project.ProjectUtils; |
| import org.netbeans.api.project.SourceGroup; |
| import org.netbeans.modules.websvc.rest.client.ClientJavaSourceHelper.HttpMimeType; |
| import org.netbeans.modules.websvc.rest.model.api.RestConstants; |
| import org.netbeans.modules.websvc.rest.spi.RestSupport; |
| import org.netbeans.modules.websvc.rest.support.JavaSourceHelper; |
| import org.netbeans.modules.websvc.rest.support.SourceGroupSupport; |
| import org.netbeans.modules.websvc.saas.model.WadlSaas; |
| import org.netbeans.modules.websvc.saas.model.WadlSaasMethod; |
| import org.netbeans.modules.websvc.saas.model.WadlSaasResource; |
| import org.netbeans.modules.websvc.saas.model.jaxb.FieldDescriptor; |
| import org.netbeans.modules.websvc.saas.model.jaxb.MethodDescriptor; |
| import org.netbeans.modules.websvc.saas.model.jaxb.ServletDescriptor; |
| import org.netbeans.modules.websvc.saas.model.wadl.Method; |
| import org.netbeans.modules.websvc.saas.model.wadl.Representation; |
| import org.netbeans.modules.websvc.saas.model.wadl.Request; |
| import org.netbeans.modules.websvc.saas.model.wadl.Response; |
| import org.netbeans.modules.websvc.saas.util.SaasUtil; |
| import org.netbeans.spi.project.AuxiliaryConfiguration; |
| import org.netbeans.spi.project.support.ant.GeneratedFilesHelper; |
| import org.openide.DialogDisplayer; |
| import org.openide.NotifyDescriptor; |
| import org.openide.execution.ExecutorTask; |
| import org.openide.filesystems.FileObject; |
| import org.openide.filesystems.FileUtil; |
| import org.openide.util.NbBundle; |
| import org.xml.sax.SAXException; |
| |
| /** |
| * |
| * @author mkuchtiak |
| */ |
| class Wadl2JavaHelper { |
| |
| private static final String PROP_XML_SCHEMA="xml_schema"; //NOI18N |
| private static final String PROP_PACKAGE_NAME="package_name"; //NOI18N |
| private static final String PROP_SOURCE_ROOT="source_root"; //NOI18N |
| private static final String SIGN_PARAMS_METHOD="signParams"; //NOI18N |
| static final String PROJEC_TYPE_WEB="web"; //NOI18N |
| static final String PROJEC_TYPE_WEB_EE7="web-ee7"; //NOI18N |
| static final String PROJEC_TYPE_DESKTOP="desktop"; //NOI18N |
| static final String PROJEC_TYPE_NB_MODULE="nb-module"; //NOI18N |
| |
| static Pair<String> getParamList(List<String> requiredParams, |
| Map<String,String> fixedParams) |
| { |
| StringBuilder paramNames = new StringBuilder(); |
| StringBuilder paramValues = new StringBuilder(); |
| boolean first = true; |
| for (String p : requiredParams) { |
| if (first) { |
| first = false; |
| } else { |
| paramNames.append(","); |
| paramValues.append(","); |
| } |
| paramNames.append("\""); |
| paramNames.append(p); |
| paramNames.append("\""); |
| paramValues.append(makeJavaIdentifier(p)); |
| } |
| for(Entry<String,String> entry: fixedParams.entrySet()){ |
| String p = entry.getKey(); |
| if (first) { |
| first = false; |
| } else { |
| paramNames.append(","); |
| paramValues.append(","); |
| |
| } |
| paramNames.append("\""); |
| paramNames.append(p); |
| paramNames.append("\""); |
| paramValues.append("\""); |
| paramNames.append(entry.getValue()); |
| paramNames.append("\""); |
| } |
| |
| return new Pair<String>(paramNames.toString(), paramValues.toString()); |
| } |
| |
| static Pair<String> getParamList(List<String> requiredParams, |
| Map<String,String> fixedParams, SecurityParams securityParams) |
| { |
| StringBuffer paramNames = new StringBuffer(); |
| StringBuffer paramValues = new StringBuffer(); |
| boolean first = true; |
| for (String p : requiredParams) { |
| if (!isSignatureParam(p, securityParams)) { |
| if (first) { |
| first = false; |
| } else { |
| paramNames.append(","); |
| paramValues.append(","); |
| } |
| paramNames.append("\""+p+"\""); |
| if (isSecurityParam(p, securityParams)) { |
| paramValues.append(findGetterForParam(p, securityParams.getMethodDescriptors())); |
| } else { |
| paramValues.append(makeJavaIdentifier(p)); |
| } |
| } |
| } |
| for (String p : fixedParams.keySet()) { |
| if (!isSignatureParam(p, securityParams)) { |
| if (first) { |
| first = false; |
| } else { |
| paramNames.append(","); |
| paramValues.append(","); |
| |
| } |
| paramNames.append("\""+p+"\""); |
| if (isSecurityParam(p, securityParams)) { |
| paramValues.append(findGetterForParam(p, securityParams.getMethodDescriptors())); |
| } else { |
| paramValues.append("\""+fixedParams.get(p)+"\""); |
| } |
| |
| } |
| } |
| return new Pair<String>(paramNames.toString(), paramValues.toString()); |
| } |
| |
| static String makeJavaIdentifier(String s) { |
| int len = s.length(); |
| String result = s; |
| for (int i=0; i<len; i++) { |
| char ch = result.charAt(i); |
| if (!Character.isJavaIdentifierPart(ch)) { |
| result = result.replace(ch, '_'); |
| } |
| } |
| if (len>0) { |
| if (!Character.isJavaIdentifierStart(result.charAt(0))) { |
| result = "_"+result; |
| } |
| result = result.substring(0,1).toLowerCase()+result.substring(1); |
| } |
| return result; |
| } |
| |
| static String getClientClassName(WadlSaasResource saasResource) { |
| String path = saasResource.getResource().getPath(); |
| int len = path.length(); |
| for (int i=0; i<len; i++) { |
| char ch = path.charAt(i); |
| if (!Character.isJavaIdentifierPart(ch)) { |
| path = path.replace(ch, '_'); //NOI18N |
| } |
| } |
| while (path.startsWith("_")) { //NOI18N |
| path = path.substring(1); |
| } |
| while (path.endsWith("_")) { //NOI18N |
| path = path.substring(0, path.length()-1); |
| } |
| String saasName = saasResource.getSaas().getDisplayName(); |
| saasName = saasName.replace(" ", "_"); //NOI18N |
| |
| if (saasName.length() == 0) { |
| saasName = "Resource"; //NOI18N |
| } else if (!Character.isJavaIdentifierStart(saasName.charAt(0))) { |
| saasName= "Resource_"+saasName; //NOI18N |
| } else if (Character.isLowerCase(saasName.charAt(0))) { |
| saasName = saasName.substring(0,1).toUpperCase()+saasName.substring(1); |
| } |
| |
| return saasName+(path.length() == 0 ? "" : "_"+path)+"_JerseyClient"; //NOI18N |
| } |
| |
| static class Pair<T> { |
| private T key; |
| private T value; |
| |
| public Pair(T key, T value) { |
| this.key = key; |
| this.value = value; |
| } |
| |
| public T getKey() { |
| return key; |
| } |
| |
| public T getValue() { |
| return value; |
| } |
| } |
| |
| static void generateJaxb(FileObject targetFo, WadlSaas wadlSaas) throws java.io.IOException { |
| Project project = FileOwnerQuery.getOwner(targetFo); |
| if (project != null) { |
| FileObject buildXml = project.getProjectDirectory().getFileObject(GeneratedFilesHelper.BUILD_XML_PATH); |
| if (buildXml != null) { |
| List<FileObject> schemaFiles = wadlSaas.getLocalSchemaFiles(); |
| if (schemaFiles.size() > 0) { |
| FileObject srcRoot = findSourceRootForFile(project, targetFo); |
| if (srcRoot != null) { |
| XmlStaxUtils staxUtils = new XmlStaxUtils(); |
| String saasDir = getSourceRootPath(project, srcRoot); |
| String packagePrefix = wadlSaas.getPackageName(); |
| String targetName = "saas.xjc."+packagePrefix; //NOI18N |
| try { |
| boolean isXjcTarget = staxUtils.isTarget(buildXml, targetName); //NOI18N |
| if (!isXjcTarget) { |
| NotifyDescriptor dd = new NotifyDescriptor.Confirmation( |
| NbBundle.getMessage(Wadl2JavaHelper.class, "MSG_CreateJaxbArtifacts", new Object[]{targetName, saasDir}), |
| NotifyDescriptor.YES_NO_OPTION); |
| DialogDisplayer.getDefault().notify(dd); |
| if (NotifyDescriptor.OK_OPTION.equals(dd.getValue())) { |
| // create META-INF if missing |
| FileObject metaInf = srcRoot.getFileObject("META-INF"); //NOI18N |
| if (metaInf == null) { |
| metaInf = srcRoot.createFolder("META-INF"); //NOI18N |
| } |
| //try { |
| String[] xmlSchemas = new String[schemaFiles.size()]; |
| String[] packageNames = new String[schemaFiles.size()]; |
| boolean isInitTarget = staxUtils.isTarget(buildXml, "saas-init-xjc"); //NOI18N |
| int i=0; |
| for (FileObject schemaFile : schemaFiles) { |
| if (metaInf != null && metaInf.isFolder() && metaInf.getFileObject(schemaFile.getNameExt()) == null) { |
| // copy schema to META-INF |
| FileUtil.copyFile(schemaFile, metaInf, schemaFile.getName()); |
| xmlSchemas[i] = saasDir+"/META-INF/"+schemaFile.getNameExt(); //NOI18N |
| } else { |
| xmlSchemas[i] = schemaFile.getPath(); |
| } |
| packageNames[i++] = packagePrefix+"."+SaasUtil.toValidJavaName(schemaFile.getName()).toLowerCase(); |
| } |
| XmlDomUtils.addJaxbXjcTargets(buildXml, targetName, saasDir, xmlSchemas, packageNames, isInitTarget, PROJEC_TYPE_NB_MODULE.equals(getProjectType(project))); |
| for (FileObject schemaFile : schemaFiles) { |
| ExecutorTask executorTask = ActionUtils.runTarget(buildXml, new String[] {targetName}, null); |
| } |
| } |
| } |
| } catch (XMLStreamException ex) { |
| Logger.getLogger(Wadl2JavaHelper.class.getName()).log(Level.WARNING, "Can not parse wadl file", ex); |
| } catch (ParserConfigurationException ex) { |
| Logger.getLogger(Wadl2JavaHelper.class.getName()).log(Level.WARNING, "Can not configure parser for wadl file", ex); |
| } catch (SAXException ex) { |
| Logger.getLogger(Wadl2JavaHelper.class.getName()).log(Level.WARNING, "Can not parse wadl file", ex); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| static String getProjectType(Project project) { |
| RestSupport restSupport = project.getLookup().lookup(RestSupport.class); |
| |
| if (restSupport != null) { |
| int projectType = restSupport.getProjectType(); |
| if (projectType == RestSupport.PROJECT_TYPE_WEB) { |
| return PROJEC_TYPE_WEB; |
| } else if (projectType == RestSupport.PROJECT_TYPE_NB_MODULE) { |
| return PROJEC_TYPE_NB_MODULE; |
| } |
| } else { |
| AuxiliaryConfiguration aux = ProjectUtils.getAuxiliaryConfiguration(project); |
| for (int i=1;i<10;i++) { |
| // be prepared for namespace upgrade |
| if (aux.getConfigurationFragment("data", //NOI18N |
| "http://www.netbeans.org/ns/nb-module-project/"+String.valueOf(i), //NOI18N |
| true) != null) { |
| return PROJEC_TYPE_NB_MODULE; |
| } else if (aux.getConfigurationFragment("data", //NOI18N |
| "http://www.netbeans.org/ns/web-project/"+String.valueOf(i), //NOI18N |
| true) != null) { |
| return PROJEC_TYPE_WEB; |
| } |
| } |
| } |
| return PROJEC_TYPE_DESKTOP; |
| } |
| |
| private static FileObject findSourceRootForFile(Project project, FileObject fo) { |
| SourceGroup[] sourceGroups = SourceGroupSupport.getJavaSourceGroups(project); |
| for (SourceGroup sourceGroup : sourceGroups) { |
| FileObject srcRoot = sourceGroup.getRootFolder(); |
| if (FileUtil.isParentOf(srcRoot, fo)) { |
| return srcRoot; |
| } |
| } |
| return null; |
| } |
| |
| private static String getSourceRootPath(Project project, FileObject srcRoot) { |
| return FileUtil.getRelativePath(project.getProjectDirectory(), srcRoot); |
| } |
| |
| static boolean isSecurityParam(String param, SecurityParams securityParams) { |
| if (securityParams.getParams().contains(param)) { |
| return true; |
| } |
| return false; |
| } |
| |
| static boolean isSignatureParam(String param, SecurityParams securityParams) { |
| if (param.equals(securityParams.getSignature())) { |
| return true; |
| } |
| return false; |
| } |
| |
| private static String findGetterForParam(String param, List<MethodDescriptor> methodDescriptors) { |
| for (MethodDescriptor method : methodDescriptors) { |
| if (param.equals(method.getId())) { |
| return method.getName()+"()"; //NOI18N |
| } |
| } |
| return makeJavaIdentifier(param); |
| } |
| |
| static ClassTree addSessionAuthMethods(WorkingCopy copy, ClassTree originalClass, SecurityParams securityParams) { |
| ClassTree modifiedClass = originalClass; |
| TreeMaker maker = copy.getTreeMaker(); |
| |
| for (FieldDescriptor field : securityParams.getFieldDescriptors()) { |
| |
| ModifiersTree fieldModifiers = maker.Modifiers(getModifiers(field.getModifiers())); |
| ExpressionTree fieldType = JavaSourceHelper.createTypeTree(copy, field.getType()); |
| VariableTree fieldTree = maker.Variable(fieldModifiers, field.getName(), fieldType, null); //NOI18N |
| modifiedClass = maker.addClassMember(modifiedClass, fieldTree); |
| } |
| |
| for (MethodDescriptor m : securityParams.getMethodDescriptors()) { |
| ModifiersTree methodModifiers = maker.Modifiers(getModifiers(m.getModifiers())); |
| // add params |
| List<VariableTree> paramList = new ArrayList<VariableTree>(); |
| String pList = m.getParamNames(); |
| if (pList != null) { |
| List<String> paramN = getList(pList); |
| List<String> paramT = getList(m.getParamTypes()); |
| ModifiersTree paramModifier = maker.Modifiers(Collections.<Modifier>emptySet()); |
| for (int i=0; i<paramN.size(); i++) { |
| Tree paramTypeTree = JavaSourceHelper.createTypeTree(copy, paramT.get(i)); //NOI18N |
| VariableTree paramTree = maker.Variable(paramModifier, paramN.get(i), paramTypeTree, null); //NOI18N |
| paramList.add(paramTree); |
| } |
| } |
| |
| // add throws |
| List<ExpressionTree> throwsList = new ArrayList<ExpressionTree>(); |
| String tList = m.getThrows(); |
| if (tList != null) { |
| for (String thr : getList(tList)) { |
| throwsList.add(JavaSourceHelper.createTypeTree(copy, thr)); |
| } |
| } |
| |
| String body = m.getBody(); |
| if (body == null) { |
| String bodyTemplate = m.getBodyRef(); |
| if (bodyTemplate != null) { |
| body = getMethodBody(bodyTemplate); |
| } |
| if (body == null) { |
| body = ("void".equals(m.getReturnType())? "{}" : "{return null;}"); //NOI18N |
| } |
| } |
| MethodTree methodTree = maker.Method ( |
| methodModifiers, |
| m.getName(), //NOI18N |
| JavaSourceHelper.createTypeTree(copy, m.getReturnType()), //NOI18N |
| Collections.<TypeParameterTree>emptyList(), |
| paramList, |
| throwsList, |
| body, |
| null); //NOI18N |
| modifiedClass = maker.addClassMember(modifiedClass, methodTree); |
| |
| } |
| return modifiedClass; |
| } |
| |
| private static List<String> getList(String s) { |
| List<String> list = new ArrayList<String>(); |
| StringTokenizer tokens = new StringTokenizer(s, ","); |
| while (tokens.hasMoreTokens()) { |
| list.add(tokens.nextToken().trim()); |
| } |
| return list; |
| } |
| |
| static String getMethodBody(String templatePath) { |
| FileObject templateFo = FileUtil.getConfigFile(templatePath); |
| if (templateFo != null) { |
| try { |
| InputStreamReader is = null; |
| StringWriter writer = null; |
| try { |
| is = new InputStreamReader(templateFo.getInputStream(), |
| Charset.forName("UTF-8")); // NOI18N |
| writer = new StringWriter(); |
| char[] buffer = new char[1024]; |
| int b; |
| while((b=is.read(buffer)) != -1) { |
| writer.write(buffer,0,b); |
| } |
| return writer.toString(); |
| } finally { |
| if (is != null) is.close(); |
| if (writer != null) writer.close(); |
| } |
| } catch(java.io.IOException ex) { |
| return null; |
| } |
| } |
| return null; |
| } |
| |
| private static Set<Modifier> getModifiers(String modif) { |
| Set<Modifier> modifs = new HashSet<Modifier>(); |
| if (modif != null) { |
| if (modif.contains("public")) { //NOI18N |
| modifs.add(Modifier.PUBLIC); |
| } else if (modif.contains("protected")) { //NOI18N |
| modifs.add(Modifier.PROTECTED); |
| } else if (modif.contains("private")) { //NOI18N |
| modifs.add(Modifier.PRIVATE); |
| } |
| if (modif.contains("static")) { //NOI18N |
| modifs.add(Modifier.STATIC); |
| } |
| if (modif.contains("final")) { //NOI18N |
| modifs.add(Modifier.FINAL); |
| } |
| } |
| return modifs; |
| } |
| |
| static ClassTree addSessionAuthServlets(WorkingCopy copy, ClassTree originalClass, SecurityParams securityParams, boolean annotateServlet) { |
| ClassTree modifiedClass = originalClass; |
| TreeMaker maker = copy.getTreeMaker(); |
| TypeElement servletAn = copy.getElements().getTypeElement("javax.servlet.annotation.WebServlet"); |
| for (ServletDescriptor classDescriptor : securityParams.getServletDescriptors()) { |
| String className = classDescriptor.getClassName(); |
| ModifiersTree classModifiers = maker.Modifiers(getModifiers(classDescriptor.getModifiers())); |
| if (annotateServlet && servletAn != null) { |
| List<ExpressionTree> attrs = new ArrayList<ExpressionTree>(); |
| attrs.add( |
| maker.Assignment(maker.Identifier("name"), maker.Literal(className))); //NOI18N |
| attrs.add( |
| maker.Assignment(maker.Identifier("urlPatterns"), maker.Literal(classDescriptor.getServletMapping()))); //NOI18N |
| |
| AnnotationTree servletAnnotation = maker.Annotation( |
| maker.QualIdent(servletAn), |
| attrs); |
| classModifiers = |
| maker.addModifiersAnnotation(classModifiers, servletAnnotation); |
| } |
| Tree extendsTree = JavaSourceHelper.createTypeTree(copy, "javax.servlet.http.HttpServlet"); //NOI18N |
| ClassTree innerClass = maker.Class ( |
| classModifiers, |
| className, |
| Collections.<TypeParameterTree>emptyList(), |
| extendsTree, |
| Collections.<Tree>emptyList(), |
| Collections.<Tree>emptyList()); |
| |
| ClassTree modifiedInnerClass = innerClass; |
| for (MethodDescriptor m : classDescriptor.getMethodDescriptor()) { |
| ModifiersTree methodModifiers = maker.Modifiers(getModifiers(m.getModifiers())); |
| // add params |
| List<VariableTree> paramList = new ArrayList<VariableTree>(); |
| String pList = m.getParamNames(); |
| if (pList != null) { |
| List<String> paramN = getList(pList); |
| List<String> paramT = getList(m.getParamTypes()); |
| ModifiersTree paramModifier = maker.Modifiers(Collections.<Modifier>emptySet()); |
| for (int i=0; i<paramN.size(); i++) { |
| Tree paramTypeTree = JavaSourceHelper.createTypeTree(copy, paramT.get(i)); //NOI18N |
| VariableTree paramTree = maker.Variable(paramModifier, paramN.get(i), paramTypeTree, null); //NOI18N |
| paramList.add(paramTree); |
| } |
| } |
| |
| // add throws |
| List<ExpressionTree> throwsList = new ArrayList<ExpressionTree>(); |
| String tList = m.getThrows(); |
| if (tList != null) { |
| for (String thr : getList(tList)) { |
| throwsList.add(JavaSourceHelper.createTypeTree(copy, thr)); |
| } |
| } |
| |
| String body = m.getBody(); |
| if (body == null) { |
| body = getMethodBody(m.getBodyRef()); |
| if (body == null) { |
| body = ("void".equals(m.getReturnType())? "{}" : "{return null;}"); //NOI18N |
| } |
| } |
| MethodTree methodTree = maker.Method ( |
| methodModifiers, |
| m.getName(), //NOI18N |
| JavaSourceHelper.createTypeTree(copy, m.getReturnType()), //NOI18N |
| Collections.<TypeParameterTree>emptyList(), |
| paramList, |
| throwsList, |
| body, |
| null); //NOI18N |
| modifiedInnerClass = maker.addClassMember(modifiedInnerClass, methodTree); |
| |
| |
| } |
| modifiedClass = maker.addClassMember(modifiedClass, modifiedInnerClass); |
| } |
| return modifiedClass; |
| } |
| |
| } |