| /* |
| * 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.maven.jaxws.nodes; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Map.Entry; |
| import java.util.Set; |
| import java.util.StringTokenizer; |
| import javax.lang.model.element.AnnotationMirror; |
| import javax.lang.model.element.AnnotationValue; |
| import javax.lang.model.element.Element; |
| import javax.lang.model.element.ExecutableElement; |
| import javax.lang.model.element.Modifier; |
| import javax.lang.model.element.TypeElement; |
| import javax.lang.model.element.VariableElement; |
| import javax.lang.model.type.DeclaredType; |
| import javax.lang.model.type.TypeMirror; |
| import javax.lang.model.util.ElementFilter; |
| import javax.swing.Action; |
| import javax.swing.SwingUtilities; |
| import org.netbeans.api.java.source.CancellableTask; |
| import org.netbeans.api.java.source.CompilationController; |
| import org.netbeans.api.java.source.JavaSource; |
| import org.netbeans.modules.maven.jaxws._RetoucheUtil; |
| import org.netbeans.modules.websvc.api.support.java.SourceUtils; |
| import org.netbeans.modules.websvc.jaxws.light.api.JaxWsService; |
| import org.openide.actions.PropertiesAction; |
| import org.openide.filesystems.FileChangeAdapter; |
| import org.openide.filesystems.FileChangeListener; |
| import org.openide.filesystems.FileEvent; |
| import org.openide.nodes.AbstractNode; |
| import org.openide.util.ImageUtilities; |
| import org.openide.util.actions.SystemAction; |
| import static org.netbeans.api.java.source.JavaSource.Phase; |
| import org.openide.ErrorManager; |
| import org.openide.filesystems.FileObject; |
| import org.openide.nodes.Children; |
| import org.openide.nodes.Node; |
| import org.openide.util.NbBundle; |
| public class JaxWsChildren extends Children.Keys<Object>/* implements MDRChangeListener */{ |
| private java.awt.Image cachedIcon; |
| private static final String OPERATION_ICON = "org/netbeans/modules/websvc/core/webservices/ui/resources/wsoperation.png"; //NOI18N |
| |
| private FileObject implClass; |
| private JaxWsService service; |
| private FileObject srcRoot; |
| |
| |
| private FileChangeListener fcl; |
| |
| public JaxWsChildren(JaxWsService service, FileObject srcRoot, FileObject implClass) { |
| super(); |
| this.service = service; |
| this.srcRoot=srcRoot; |
| this.implClass = implClass; |
| } |
| |
| private List<ExecutableElement> getPublicMethods(CompilationController controller, TypeElement classElement) throws IOException { |
| List<? extends Element> members = classElement.getEnclosedElements(); |
| List<ExecutableElement> methods = ElementFilter.methodsIn(members); |
| List<ExecutableElement> publicMethods = new ArrayList<ExecutableElement>(); |
| for (ExecutableElement method:methods) { |
| Set<Modifier> modifiers = method.getModifiers(); |
| if (modifiers.contains(Modifier.PUBLIC)) { |
| publicMethods.add(method); |
| } |
| } |
| return publicMethods; |
| } |
| |
| @Override |
| protected void addNotify() { |
| assert(implClass != null); |
| if (fcl == null) { |
| fcl = new FileChangeAdapter() { |
| @Override |
| public void fileChanged(FileEvent fe) { |
| updateKeys(); |
| ((JaxWsNode)getNode()).fireShortDescriptionChange(); |
| ((JaxWsNode)getNode()).setServiceUrl(); |
| } |
| }; |
| implClass.addFileChangeListener(fcl); |
| } |
| |
| updateKeys(); |
| } |
| |
| @Override |
| protected void removeNotify() { |
| if (fcl != null) { |
| implClass.removeFileChangeListener(fcl); |
| fcl = null; |
| } |
| setKeys(Collections.<Object>emptySet()); |
| } |
| |
| private void updateKeys() { |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| final List<?>[] keys = new List<?>[1]; |
| if (implClass != null) { |
| JavaSource javaSource = JavaSource.forFileObject(implClass); |
| if (javaSource!=null) { |
| CancellableTask<CompilationController> task = |
| new CancellableTask<CompilationController>() |
| { |
| @Override |
| public void run(CompilationController controller) throws IOException { |
| controller.toPhase(Phase.ELEMENTS_RESOLVED); |
| TypeElement typeElement = SourceUtils. |
| getPublicTopLevelElement(controller); |
| // find WS operations |
| // excluding @WebMethod(exclude=true). See the issue 228292. |
| List<ExecutableElement> publicMethods = |
| getPublicMethods(controller, typeElement); |
| List<ExecutableElement> webMethods = |
| new ArrayList<ExecutableElement>(); |
| // map for storing @WebMethod annotation mirror |
| java.util.Map<ExecutableElement, AnnotationMirror> webMethodAnnMap = |
| new java.util.HashMap<ExecutableElement, AnnotationMirror>(); |
| for(ExecutableElement method:publicMethods) { |
| AnnotationMirror webMethodAnn = |
| _RetoucheUtil.getAnnotation(controller, |
| method, "javax.jws.WebMethod"); |
| if (webMethodAnn != null) { |
| boolean exclude = false; |
| java.util.Map<? extends ExecutableElement, |
| ? extends AnnotationValue> expressions = webMethodAnn.getElementValues(); |
| for(Entry<? extends ExecutableElement, |
| ? extends AnnotationValue> entry: |
| expressions.entrySet()) |
| { |
| if (entry.getKey().getSimpleName(). |
| contentEquals("exclude"))//NOI18N |
| { |
| Object value = expressions.get(entry.getKey()).getValue(); |
| if (Boolean.TRUE.equals(value)) { |
| exclude = true; |
| } |
| break; |
| } |
| } |
| if (!exclude) { |
| webMethods.add(method); |
| webMethodAnnMap.put(method, webMethodAnn); |
| } |
| } |
| else { |
| // add un-annotated public method by default (issue 228292) |
| webMethods.add(method); |
| } |
| } // for |
| |
| |
| // create list of operations; |
| List<WebOperationInfo> webOperations = |
| new ArrayList<WebOperationInfo>(); |
| |
| for (ExecutableElement webMethod:webMethods) { |
| // web operation name |
| WebOperationInfo webOperation = |
| new WebOperationInfo(); |
| // get @WebMethod annotation from the map |
| AnnotationMirror webMethodAnn = webMethodAnnMap.get(webMethod); |
| if (webMethodAnn != null) { |
| java.util.Map<? extends ExecutableElement, |
| ? extends AnnotationValue> expressions = webMethodAnn.getElementValues(); |
| for(Entry<? extends ExecutableElement, |
| ? extends AnnotationValue> entry: |
| expressions.entrySet()) |
| { |
| if (entry.getKey().getSimpleName(). |
| contentEquals("operationName"))//NOI18N |
| { |
| webOperation.setOperationName( |
| (String)expressions.get( |
| entry.getKey()). |
| getValue()); |
| } |
| } |
| } |
| if (webOperation.getOperationName() == null) |
| { |
| webOperation.setOperationName( |
| webMethod.getSimpleName(). |
| toString()); |
| } |
| |
| // return type |
| TypeMirror returnType = webMethod. |
| getReturnType(); |
| if (returnType instanceof DeclaredType ) |
| { |
| TypeElement element = (TypeElement)( |
| (DeclaredType)returnType). |
| asElement(); |
| webOperation.setReturnType( |
| element.getQualifiedName().toString()); |
| } else { // for primitive type |
| webOperation.setReturnType( |
| returnType.toString()); |
| } |
| |
| // parameter types |
| List<? extends VariableElement> params = |
| webMethod.getParameters(); |
| List<String> paramTypes = |
| new ArrayList<String>(); |
| for (VariableElement param:params) { |
| TypeMirror type = param.asType(); |
| if (type instanceof DeclaredType ) { |
| TypeElement element = |
| (TypeElement)((DeclaredType)type). |
| asElement(); |
| paramTypes.add( |
| element.getQualifiedName(). |
| toString()); |
| } else { // for primitive type |
| paramTypes.add(type.toString()); |
| } |
| } |
| webOperation.setParamTypes(paramTypes); |
| |
| webOperations.add(webOperation); |
| } |
| keys[0] = webOperations; |
| } |
| |
| @Override |
| public void cancel() { |
| } |
| }; |
| try { |
| javaSource.runUserActionTask(task, true); |
| } catch (IOException ex) { |
| ErrorManager.getDefault().notify(ex); |
| } |
| } |
| } |
| |
| if (keys[0] == null) { |
| keys[0] = Collections.emptyList(); |
| } |
| setKeys(keys[0]); |
| } |
| }); |
| } |
| |
| @Override |
| protected Node[] createNodes(Object key) { |
| if(key instanceof WebOperationInfo) { |
| final WebOperationInfo method = (WebOperationInfo)key; |
| Node n = new AbstractNode(Children.LEAF) { |
| |
| @java.lang.Override |
| public java.awt.Image getIcon(int type) { |
| if (cachedIcon == null) { |
| cachedIcon = ImageUtilities.loadImage(OPERATION_ICON); |
| } |
| return cachedIcon; |
| } |
| |
| @Override |
| public Action[] getActions(boolean context) { |
| return new Action[]{SystemAction.get(PropertiesAction.class)}; |
| } |
| |
| @Override |
| public Action getPreferredAction() { |
| return SystemAction.get(PropertiesAction.class); |
| } |
| |
| @Override |
| public String getDisplayName() { |
| return method.getOperationName()+": "+getClassName(method.getReturnType()); //NOI18N |
| } |
| }; |
| StringBuffer buf = new StringBuffer(); |
| for (String paramType:method.getParamTypes()) { |
| buf.append(buf.length() == 0 ? paramType : ", "+paramType); |
| } |
| n.setShortDescription( |
| NbBundle.getMessage(JaxWsChildren.class,"TXT_operationDesc",method.getReturnType(),method.getOperationName(),buf.toString())); |
| return new Node[]{n}; |
| } |
| return new Node[0]; |
| } |
| |
| // private boolean isFromWsdl() { |
| // return service.getWsdlUrl()!=null; |
| // } |
| |
| private String getClassName(String fullClassName) { |
| StringTokenizer tok = new StringTokenizer(fullClassName,"."); //NOI18N |
| String token = ""; |
| while (tok.hasMoreTokens()) { |
| token = tok.nextToken(); |
| } |
| return token; |
| } |
| |
| // private void setBindings(JAXWSSupport support, WsdlModeler wsdlModeler, Service service) { |
| // Binding[] extbindings = service.getBindings(); |
| // if (extbindings==null || extbindings.length==0) { |
| // wsdlModeler.setJAXBBindings(null); |
| // return; |
| // } |
| // String[] bindingFiles = new String[extbindings.length]; |
| // for(int i = 0; i < extbindings.length; i++){ |
| // bindingFiles[i] = extbindings[i].getFileName(); |
| // } |
| // |
| // FileObject bindingsFolder = support.getBindingsFolderForService(getNode().getName(),true); |
| // List<URL> list = new ArrayList<URL>(); |
| // for (int i=0;i<bindingFiles.length;i++) { |
| // FileObject fo = bindingsFolder.getFileObject(bindingFiles[i]); |
| // try { |
| // list.add(fo.getURL()); |
| // } catch (FileStateInvalidException ex) { |
| // // if there is problem no bindings will be added |
| // } |
| // } |
| // URL[] bindings = new URL[list.size()]; |
| // list.<URL>toArray(bindings); |
| // wsdlModeler.setJAXBBindings(bindings); |
| // } |
| |
| // void refreshKeys(boolean downloadWsdl, final boolean refreshImplClass, String newWsdlUrl) { |
| // if (!isFromWsdl()) return; |
| // super.addNotify(); |
| // try { |
| // // copy to local wsdl first |
| // JAXWSSupport support = getJAXWSSupport(); |
| // |
| // if (downloadWsdl) { |
| // String serviceName = getNode().getName(); |
| // FileObject xmlResorcesFo = support.getLocalWsdlFolderForService(serviceName,true); |
| // FileObject localWsdl = null; |
| // try { |
| // String oldWsdlUrl = service.getWsdlUrl(); |
| // boolean jaxWsModelChanged = false; |
| // if (newWsdlUrl.length()>0 && !oldWsdlUrl.equals(newWsdlUrl)) { |
| // localWsdl = WSUtils.retrieveResource( |
| // xmlResorcesFo, |
| // new URI(newWsdlUrl)); |
| // jaxWsModelChanged = true; |
| // } else { |
| // localWsdl = WSUtils.retrieveResource( |
| // xmlResorcesFo, |
| // new URI(oldWsdlUrl)); |
| // } |
| // if (jaxWsModelChanged) { |
| // service.setWsdlUrl(newWsdlUrl); |
| // FileObject xmlResourcesFo = support.getLocalWsdlFolderForService(serviceName,false); |
| // if (xmlResourcesFo!=null) { |
| // String localWsdlUrl = FileUtil.getRelativePath(xmlResourcesFo, localWsdl); |
| // service.setLocalWsdlFile(localWsdlUrl); |
| // } |
| // Project project = FileOwnerQuery.getOwner(srcRoot); |
| // JaxWsModel jaxWsModel = (JaxWsModel)project.getLookup().lookup(JaxWsModel.class); |
| // if (jaxWsModel!=null) jaxWsModel.write(); |
| // } |
| // // copy resources to WEB-INF/wsdl/${serviceName} |
| // FileObject wsdlFolder = getWsdlFolderForService(support, serviceName); |
| // WSUtils.copyFiles(xmlResorcesFo, wsdlFolder); |
| // } catch (URISyntaxException ex) { |
| // ErrorManager.getDefault().notify(ex); |
| // } catch (UnknownHostException ex) { |
| // ErrorManager.getDefault().annotate(ex, |
| // NbBundle.getMessage(JaxWsChildren.class,"MSG_ConnectionProblem")); |
| // return; |
| // } catch (IOException ex) { |
| // ErrorManager.getDefault().annotate(ex, |
| // NbBundle.getMessage(JaxWsChildren.class,"MSG_ConnectionProblem")); |
| // return; |
| // } |
| // |
| // // re-generate also wrapper wsdl file if necessary |
| // if (localWsdl!=null) { |
| // WsdlWrapperHandler handler = null; |
| // try { |
| // handler = WsdlWrapperGenerator.parse(localWsdl.getURL().toExternalForm()); |
| // } catch (ParserConfigurationException ex) { |
| // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,ex); |
| // } catch (SAXException ex) { |
| // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,ex); |
| // } catch (IOException ex) { |
| // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,ex); |
| // } |
| // if (!handler.isServiceElement()) { |
| // StreamSource source = new StreamSource(localWsdl.getURL().toExternalForm()); |
| // try { |
| // File wrapperWsdlFile = new File(FileUtil.toFile(localWsdl.getParent()), WsdlWrapperGenerator.getWrapperName(localWsdl.getURL())); //NOI18N |
| // |
| // if(!wrapperWsdlFile.exists()) { |
| // try { |
| // wrapperWsdlFile.createNewFile(); |
| // } catch(IOException ex) { |
| // ErrorManager.getDefault().notify(ErrorManager.EXCEPTION,ex); |
| // } |
| // } |
| // if (wrapperWsdlFile.exists()) { |
| // WsdlWrapperGenerator.generateWrapperWSDLContent(wrapperWsdlFile, source, handler.getTargetNsPrefix(),localWsdl.getNameExt()); |
| // } |
| // } catch (IOException ex) { |
| // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,ex); |
| // } |
| // } |
| // } |
| // } |
| // FileObject localWsdlFolder = getJAXWSSupport().getLocalWsdlFolderForService(service.getName(),false); |
| // if (localWsdlFolder == null) { |
| // DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( |
| // NbBundle.getMessage(JaxWsChildren.class,"MSG_RefreshWithReplaceWsdl"), //NOI18N |
| // NotifyDescriptor.WARNING_MESSAGE)); |
| // return; |
| // } |
| // FileObject wsdlFo = |
| // localWsdlFolder.getFileObject(service.getLocalWsdlFile()); |
| // wsdlModeler = WsdlModelerFactory.getDefault().getWsdlModeler(wsdlFo.getURL()); |
| // String packageName = service.getPackageName(); |
| // if (packageName!=null && service.isPackageNameForceReplace()) { |
| // // set the package name for the modeler |
| // wsdlModeler.setPackageName(packageName); |
| // } else { |
| // wsdlModeler.setPackageName(null); |
| // } |
| // wsdlModeler.setCatalog(support.getCatalog()); |
| // setBindings(support, wsdlModeler, service); |
| // |
| // // re-generate java artifacts |
| // regenerateJavaArtifacts(); |
| // // update nodes and implementation class |
| // |
| // modelGenerationFinished=false; |
| // ((JaxWsNode)getNode()).changeIcon(); |
| // wsdlModeler.generateWsdlModel(new WsdlModelListener() { |
| // public void modelCreated(WsdlModel model) { |
| // wsdlModel=model; |
| // modelGenerationFinished=true; |
| // ((JaxWsNode)getNode()).changeIcon(); |
| // if (model==null) { |
| // DialogDisplayer.getDefault().notify( |
| // new JaxWsUtils.WsImportServiceFailedMessage(wsdlModeler.getCreationException())); |
| // } |
| // if (model!=null) { |
| // try { |
| // // test if serviceName, portName are the same, change if necessary |
| // String serviceName = service.getServiceName(); |
| // String portName = service.getPortName(); |
| // WsdlService wsdlService = model.getServiceByName(serviceName); |
| // boolean jaxWsModelChanged=false; |
| // if (wsdlService==null) { |
| // wsdlService = (WsdlService)model.getServices().get(0); |
| // service.setServiceName(wsdlService.getName()); |
| // jaxWsModelChanged=true; |
| // } |
| // WsdlPort wsdlPort = wsdlService.getPortByName(portName); |
| // if (wsdlPort==null) { |
| // wsdlPort = (WsdlPort)wsdlService.getPorts().get(0); |
| // service.setPortName(wsdlPort.getName()); |
| // jaxWsModelChanged=true; |
| // } |
| // |
| // // test if package name for java artifacts hasn't changed |
| // String oldPkgName = service.getPackageName(); |
| // if (wsdlService!=null && oldPkgName!=null && !service.isPackageNameForceReplace()) { |
| // String javaName = wsdlService.getJavaName(); |
| // int dotPosition = javaName.lastIndexOf("."); |
| // if (dotPosition>=0) { |
| // String newPkgName = javaName.substring(0,dotPosition); |
| // if (!oldPkgName.equals(newPkgName)) { |
| // service.setPackageName(newPkgName); |
| // jaxWsModelChanged=true; |
| // } |
| // } |
| // } |
| // |
| // // save jax-ws model |
| // if (jaxWsModelChanged) { |
| // Project project = FileOwnerQuery.getOwner(srcRoot); |
| // if (project!=null) { |
| // JaxWsModel jaxWsModel = (JaxWsModel)project.getLookup().lookup(JaxWsModel.class); |
| // if (jaxWsModel!=null) jaxWsModel.write(); |
| // } |
| // |
| // } |
| // if (refreshImplClass) { |
| // // re-generate implementation class |
| // String implClass = service.getImplementationClass(); |
| // FileObject oldImplClass = srcRoot.getFileObject(implClass.replace('.','/')+".java"); //NOI18N |
| // FileObject oldCopy = srcRoot.getFileObject(implClass.replace('.','/')+".java.old"); //NOI18N |
| // int index = implClass.lastIndexOf("."); |
| // FileObject folder = index>0?srcRoot.getFileObject(implClass.substring(0,index).replace('.','/')):srcRoot; |
| // if (folder!=null) { |
| // String name = (index>=0?implClass.substring(index+1):implClass); |
| // if (oldImplClass!=null) { |
| // if (oldCopy!=null) oldCopy.delete(); |
| // FileUtil.copyFile(oldImplClass, folder, name+".java", "old"); //NOI18N |
| // oldImplClass.delete(); |
| // } |
| // // close the editor representing old impl bean |
| // JaxWsNode parent = (JaxWsNode)getNode(); |
| // JaxWsUtils.generateJaxWsImplementationClass(FileOwnerQuery.getOwner(srcRoot), |
| // folder, name, model, service); |
| // FileObject newImplClass = srcRoot.getFileObject(implClass.replace('.','/')+".java"); //NOI18N |
| // if (newImplClass!=null) { |
| // JaxWsChildren.this.implClass=newImplClass; |
| // } |
| // parent.refreshImplClass(); |
| // } |
| // } |
| // } catch (Exception ex) { |
| // ErrorManager.getDefault().notify(ErrorManager.ERROR,ex); |
| // } |
| // } |
| // } |
| // }); |
| // } catch (FileStateInvalidException ex) { |
| // ErrorManager.getDefault().log(ex.getLocalizedMessage()); |
| // } |
| // } |
| |
| // private void regenerateJavaArtifacts() { |
| // Project project = FileOwnerQuery.getOwner(srcRoot); |
| // if (project!=null) { |
| // FileObject buildImplFo = project.getProjectDirectory().getFileObject(GeneratedFilesHelper.BUILD_XML_PATH); |
| // try { |
| // String name = service.getName(); |
| // ExecutorTask wsimportTask = |
| // ActionUtils.runTarget(buildImplFo, |
| // new String[]{"wsimport-service-clean-"+name,"wsimport-service-"+name},null); //NOI18N |
| // wsimportTask.waitFinished(); |
| // } catch (IOException ex) { |
| // ErrorManager.getDefault().log(ex.getLocalizedMessage()); |
| // } catch (IllegalArgumentException ex) { |
| // ErrorManager.getDefault().log(ex.getLocalizedMessage()); |
| // } |
| // } |
| // } |
| |
| |
| // private FileObject getWsdlFolderForService(JAXWSSupport support, String name) throws IOException { |
| // FileObject globalWsdlFolder = support.getWsdlFolder(true); |
| // FileObject oldWsdlFolder = globalWsdlFolder.getFileObject(name); |
| // if (oldWsdlFolder!=null) { |
| // FileLock lock = oldWsdlFolder.lock(); |
| // try { |
| // oldWsdlFolder.delete(lock); |
| // } finally { |
| // lock.releaseLock(); |
| // } |
| // } |
| // return globalWsdlFolder.createFolder(name); |
| // } |
| |
| private static class WebOperationInfo { |
| private String operationName; |
| private List<String> paramTypes; |
| private String returnType; |
| |
| String getOperationName() { |
| return operationName; |
| } |
| |
| void setOperationName(String operationName) { |
| this.operationName = operationName; |
| } |
| |
| List<String> getParamTypes() { |
| return paramTypes; |
| } |
| |
| void setParamTypes(List<String> paramTypes) { |
| this.paramTypes = paramTypes; |
| } |
| |
| String getReturnType() { |
| return returnType; |
| } |
| |
| void setReturnType(String returnType) { |
| this.returnType = returnType; |
| } |
| } |
| |
| } |