0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans.modules.j2ee.ejbjarproject;
0043:
0044: import com.sun.source.tree.AnnotationTree;
0045: import com.sun.source.tree.ClassTree;
0046: import com.sun.source.tree.ExpressionTree;
0047: import com.sun.source.tree.IdentifierTree;
0048: import com.sun.source.tree.MemberSelectTree;
0049: import com.sun.source.tree.MethodTree;
0050: import com.sun.source.tree.ModifiersTree;
0051: import com.sun.source.tree.Tree;
0052: import com.sun.source.tree.Tree.Kind;
0053: import com.sun.source.tree.TypeParameterTree;
0054: import com.sun.source.tree.VariableTree;
0055: import java.util.ArrayList;
0056: import java.util.Arrays;
0057: import java.util.HashSet;
0058: import java.util.Iterator;
0059: import java.util.List;
0060: import java.io.IOException;
0061: import javax.lang.model.element.Modifier;
0062: import java.util.Collections;
0063: import java.util.logging.Level;
0064: import java.util.logging.Logger;
0065: import org.netbeans.api.java.classpath.ClassPath;
0066: import org.netbeans.modules.j2ee.core.api.support.java.SourceUtils;
0067: import org.netbeans.modules.websvc.api.client.WebServicesClientConstants;
0068: import org.w3c.dom.Document;
0069: import org.w3c.dom.Element;
0070: import org.w3c.dom.Node;
0071: import org.w3c.dom.NodeList;
0072: import org.netbeans.spi.project.support.ant.AntProjectHelper;
0073: import org.netbeans.modules.websvc.spi.webservices.WebServicesSupportImpl;
0074: import org.netbeans.spi.project.support.ant.EditableProperties;
0075: import org.netbeans.spi.project.support.ant.PropertyUtils;
0076: import org.netbeans.modules.j2ee.dd.api.ejb.DDProvider;
0077: import org.netbeans.modules.j2ee.dd.api.ejb.EjbJar;
0078: import org.netbeans.modules.j2ee.dd.api.ejb.EnterpriseBeans;
0079: import org.netbeans.modules.j2ee.dd.api.ejb.Session;
0080: import org.netbeans.api.project.Project;
0081: import org.netbeans.api.project.ProjectManager;
0082: import org.netbeans.api.project.ProjectUtils;
0083: import org.netbeans.api.project.SourceGroup;
0084: import org.netbeans.api.project.Sources;
0085: import org.openide.DialogDisplayer;
0086: import org.openide.NotifyDescriptor;
0087: import org.openide.filesystems.FileObject;
0088: import org.openide.filesystems.FileUtil;
0089: import org.openide.util.NbBundle;
0090: import org.netbeans.modules.j2ee.dd.api.webservices.ServiceImplBean;
0091: import org.netbeans.api.java.project.JavaProjectConstants;
0092: import org.netbeans.api.java.source.CancellableTask;
0093: import org.netbeans.api.java.source.JavaSource;
0094: import org.netbeans.api.java.source.JavaSource.Phase;
0095: import org.netbeans.api.java.source.TreeMaker;
0096: import org.netbeans.api.java.source.WorkingCopy;
0097: import org.netbeans.modules.websvc.spi.webservices.WebServicesConstants;
0098: import org.netbeans.modules.websvc.api.webservices.WsCompileEditorSupport;
0099: import org.netbeans.modules.websvc.api.webservices.StubDescriptor;
0100: import org.netbeans.spi.project.support.ant.ReferenceHelper;
0101: import static org.netbeans.modules.websvc.spi.webservices.WebServicesConstants.*;
0102: import org.netbeans.modules.j2ee.ejbjarproject.classpath.ClassPathProviderImpl;
0103: import org.netbeans.spi.java.classpath.support.ClassPathSupport;
0104: import org.openide.ErrorManager;
0105:
0106: /**
0107: *
0108: * @author rico
0109: * Implementation of WebServicesSupportImpl
0110: */
0111: public class EjbJarWebServicesSupport implements WebServicesSupportImpl {
0112:
0113: private EjbJarProject project;
0114: private AntProjectHelper helper;
0115: private ReferenceHelper referenceHelper;
0116: private ClassPath projectSourcesClassPath;
0117:
0118: /** Creates a new instance of EjbJarWebServicesSupport */
0119: public EjbJarWebServicesSupport(EjbJarProject project,
0120: AntProjectHelper helper, ReferenceHelper referenceHelper) {
0121: this .project = project;
0122: this .helper = helper;
0123: this .referenceHelper = referenceHelper;
0124: }
0125:
0126: //implementation of WebServicesSupportImpl
0127: public String generateImplementationBean(String wsName,
0128: FileObject pkg, Project project, String delegateData)
0129: throws java.io.IOException {
0130: //TODO: RETOUCHE waiting for ejbcore
0131: // SessionGenerator sessionGenerator = new SessionGenerator();
0132: // return sessionGenerator.generateWebServiceImplBean(wsName, pkg, project, delegateData);
0133: return null;
0134: }
0135:
0136: public void addServiceImpl(String serviceName,
0137: FileObject configFile, boolean fromWSDL) {
0138: this .addServiceImpl(serviceName, configFile, fromWSDL, null);
0139: }
0140:
0141: public void addServiceImpl(String serviceName,
0142: FileObject configFile, boolean fromWSDL,
0143: String[] wscompileFeatures) {
0144:
0145: //Add properties to project.properties file
0146: EditableProperties ep = helper
0147: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
0148: String packageName = getPackageName(configFile);
0149: ep.put(serviceName + CONFIG_PROP_SUFFIX, packageName
0150: + (packageName.equals("") ? "" : "/")
0151: + configFile.getNameExt()); //NOI18N
0152: ep.put(serviceName + MAPPING_PROP_SUFFIX, serviceName
0153: + MAPPING_FILE_SUFFIX); //NOI18N
0154: // Add property for wscompile
0155: String featurePropertyName = "wscompile.service." + serviceName
0156: + ".features"; // NOI18N
0157: JAXRPCStubDescriptor stubDesc = null;
0158: if (fromWSDL) {
0159: if (wscompileFeatures != null) {
0160: stubDesc = new JAXRPCStubDescriptor(
0161: StubDescriptor.WSDL_SERVICE_STUB, NbBundle
0162: .getMessage(
0163: EjbJarWebServicesSupport.class,
0164: "LBL_WSDLServiceStub"),
0165: wscompileFeatures);
0166: } else {
0167: stubDesc = wsdlServiceStub;
0168: }
0169: } else {
0170: stubDesc = seiServiceStub;
0171: }
0172: String defaultFeatures = stubDesc
0173: .getDefaultFeaturesAsArgument();
0174: ep.put(featurePropertyName, defaultFeatures);
0175: helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,
0176: ep);
0177:
0178: //Add web-services information in project.xml
0179: Element data = helper.getPrimaryConfigurationData(true);
0180: Document doc = data.getOwnerDocument();
0181: NodeList nodes = data.getElementsByTagName(WEB_SERVICES); //NOI18N
0182: Element webservices = null;
0183: if (nodes.getLength() == 0) {
0184: webservices = doc.createElementNS(
0185: EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0186: WEB_SERVICES); //NOI18N
0187: NodeList insertBefore = data.getElementsByTagNameNS(
0188: EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0189: WebServicesClientConstants.WEB_SERVICE_CLIENTS);
0190: if (insertBefore.getLength() <= 0) {
0191: insertBefore = data
0192: .getElementsByTagNameNS(
0193: EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0194: "source-roots"); // NOI18N
0195: assert insertBefore.getLength() == 1 : "Invalid project.xml file."; // NOI18N
0196: }
0197: data.insertBefore(webservices, insertBefore.item(0));
0198: } else {
0199: webservices = (Element) nodes.item(0);
0200: }
0201: Element webservice = doc.createElementNS(
0202: EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0203: WEB_SERVICE); //NOI18N
0204: webservices.appendChild(webservice);
0205: Element webserviceName = doc.createElementNS(
0206: EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0207: WEB_SERVICE_NAME); //NOI18N
0208: webservice.appendChild(webserviceName);
0209: webserviceName.appendChild(doc.createTextNode(serviceName));
0210: if (fromWSDL) {
0211: Element fromWSDLElem = doc.createElementNS(
0212: EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0213: "from-wsdl");
0214: webservice.appendChild(fromWSDLElem);
0215: }
0216: helper.putPrimaryConfigurationData(data, true);
0217:
0218: // Update wscompile related properties. boolean return indicates whether
0219: // any changes were made.
0220: updateWsCompileProperties(serviceName);
0221:
0222: try {
0223: ProjectManager.getDefault().saveProject(project);
0224: } catch (java.io.IOException ioe) {
0225: ErrorManager.getDefault().notify(ioe);
0226: }
0227: }
0228:
0229: public void addServiceEntriesToDD(String serviceName,
0230: String serviceEndpointInterface, String servantClassName) {
0231: //add service endpoint entry to ejb-jar.xml
0232: DDProvider provider = DDProvider.getDefault();
0233: org.netbeans.modules.j2ee.api.ejbjar.EjbJar ejbJarModule = org.netbeans.modules.j2ee.api.ejbjar.EjbJar
0234: .getEjbJars(project)[0];
0235: org.netbeans.modules.j2ee.dd.api.ejb.EjbJar ejbJar = null;
0236: try {
0237: ejbJar = provider.getDDRoot(ejbJarModule
0238: .getDeploymentDescriptor());
0239: } catch (java.io.IOException e) {
0240: ErrorManager.getDefault().notify(e);
0241: }
0242:
0243: if (ejbJar == null) {
0244: Logger.getLogger("global").log(
0245: Level.SEVERE,
0246: NbBundle.getMessage(EjbJarWebServicesSupport.class,
0247: "MSG_MissingMetadata"));
0248: return;
0249: }
0250:
0251: EjbJarProvider pwm = project.getLookup().lookup(
0252: EjbJarProvider.class);
0253: pwm.getConfigSupport().ensureConfigurationReady();
0254: EnterpriseBeans beans = ejbJar.getEnterpriseBeans();
0255: Session s = null;
0256: if (beans == null) {
0257: beans = ejbJar.newEnterpriseBeans();
0258: ejbJar.setEnterpriseBeans(beans);
0259: }
0260: s = beans.newSession();
0261: s.setEjbName(serviceName);
0262: s.setDisplayName(serviceName + "SB"); // NOI18N
0263: s.setEjbClass(servantClassName);
0264: try {
0265: s.setServiceEndpoint(serviceEndpointInterface);
0266: } catch (org.netbeans.modules.j2ee.dd.api.common.VersionNotSupportedException e) {
0267: ErrorManager.getDefault().notify(e);
0268: }
0269: s.setSessionType("Stateless"); // NOI18N
0270: s.setTransactionType("Container"); // NOI18N
0271: beans.addSession(s);
0272: try {
0273: // This also saves server specific configuration, if necessary.
0274: ejbJar.write(ejbJarModule.getDeploymentDescriptor());
0275: } catch (java.io.IOException e) {
0276: ErrorManager.getDefault().notify(e);
0277: }
0278: }
0279:
0280: public void addServiceImplLinkEntry(
0281: ServiceImplBean serviceImplBean, String wsName) {
0282: serviceImplBean.setEjbLink(wsName);
0283: }
0284:
0285: /**
0286: * Get the webservices.xml file object
0287: */
0288: public FileObject getWebservicesDD() {
0289: FileObject metaInfFo = getMetaInf();
0290: if (metaInfFo == null) {
0291: return null;
0292: }
0293: return getMetaInf().getFileObject(WEBSERVICES_DD, "xml");
0294: }
0295:
0296: /**
0297: * Returns the directory that contains webservices.xml in the project
0298: */
0299: public FileObject getWsDDFolder() {
0300: return getMetaInf();
0301: }
0302:
0303: /**
0304: * Returns the name of the directory that contains the webservices.xml in
0305: * the archive
0306: */
0307: public String getArchiveDDFolderName() {
0308: return "META-INF"; // NOI18N
0309: }
0310:
0311: /**
0312: * Returns the name of the implementation bean class
0313: * given the ejb-link name
0314: */
0315: public String getImplementationBean(String linkName) {
0316: EjbJar ejbJar = getEjbJar();
0317: EnterpriseBeans beans = ejbJar.getEnterpriseBeans();
0318: Session[] sessionBeans = beans.getSession();
0319: for (int i = 0; i < sessionBeans.length; i++) {
0320: Session sessionBean = sessionBeans[i];
0321: if (sessionBean.getEjbName().equals(linkName)) {
0322: return sessionBean.getEjbClass();
0323: }
0324:
0325: }
0326: return null;
0327: }
0328:
0329: public boolean isFromWSDL(String serviceName) {
0330: Element data = helper.getPrimaryConfigurationData(true);
0331: NodeList nodes = data.getElementsByTagNameNS(
0332: EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0333: WEB_SERVICES); //NOI18N
0334: Element webservices = null;
0335: Element wsNameNode = null;
0336: if (nodes.getLength() == 1) {
0337: webservices = (Element) nodes.item(0);
0338: NodeList wsNodes = webservices.getElementsByTagNameNS(
0339: EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0340: WEB_SERVICE); //NOI18N
0341: for (int j = 0; j < wsNodes.getLength(); j++) {
0342: Element wsNode = (Element) wsNodes.item(j);
0343: NodeList wsNameNodes = wsNode
0344: .getElementsByTagNameNS(
0345: EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0346: WEB_SERVICE_NAME); //NOI18N
0347: if (wsNameNodes.getLength() == 1) {
0348: wsNameNode = (Element) wsNameNodes.item(0);
0349: NodeList nl = wsNameNode.getChildNodes();
0350: if (nl.getLength() == 1) {
0351: Node n = nl.item(0);
0352: if (n.getNodeType() == Node.TEXT_NODE) {
0353: if (serviceName.equals(n.getNodeValue())) {
0354: NodeList fromWSDLNodes = wsNode
0355: .getElementsByTagNameNS(
0356: EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0357: WebServicesConstants.WEB_SERVICE_FROM_WSDL); //NOI18N
0358: if (fromWSDLNodes.getLength() == 1) {
0359: return true;
0360: }
0361: }
0362: }
0363: }
0364: }
0365: }
0366: }
0367: return false;
0368: }
0369:
0370: public void removeProjectEntries(String serviceName) {
0371: boolean needsSave = false;
0372:
0373: //Remove entries in the project.properties file
0374: //FIX-ME:we should move this to websvc
0375: EditableProperties ep = helper
0376: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
0377: String configProperty = serviceName + CONFIG_PROP_SUFFIX;
0378: String mappingProperty = serviceName + MAPPING_PROP_SUFFIX;
0379: if (ep.getProperty(configProperty) != null) {
0380: ep.remove(configProperty);
0381: needsSave = true;
0382: }
0383: if (ep.getProperty(mappingProperty) != null) {
0384: ep.remove(mappingProperty);
0385: needsSave = true;
0386: }
0387: String featureProperty = "wscompile.service." + serviceName
0388: + ".features"; // NOI18N
0389: if (ep.getProperty(featureProperty) != null) {
0390: ep.remove(featureProperty);
0391: needsSave = true;
0392: }
0393: if (needsSave) {
0394: helper.putProperties(
0395: AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
0396: }
0397: //Remove entry in the project.xml file (we should move this to websvc)
0398: Element data = helper.getPrimaryConfigurationData(true);
0399: NodeList nodes = data.getElementsByTagNameNS(
0400: EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0401: WEB_SERVICES); //NOI18N
0402: Element webservices = null;
0403: Element wsNameNode = null;
0404: if (nodes.getLength() == 1) {
0405: webservices = (Element) nodes.item(0);
0406: NodeList wsNodes = webservices.getElementsByTagNameNS(
0407: EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0408: WEB_SERVICE); //NOI18N
0409: for (int j = 0; j < wsNodes.getLength(); j++) {
0410: Element wsNode = (Element) wsNodes.item(j);
0411: NodeList wsNameNodes = wsNode
0412: .getElementsByTagNameNS(
0413: EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0414: WEB_SERVICE_NAME); //NOI18N
0415: if (wsNameNodes.getLength() == 1) {
0416: wsNameNode = (Element) wsNameNodes.item(0);
0417: NodeList nl = wsNameNode.getChildNodes();
0418: if (nl.getLength() == 1) {
0419: Node n = nl.item(0);
0420: if (n.getNodeType() == Node.TEXT_NODE) {
0421: if (serviceName.equals(n.getNodeValue())) {
0422: webservices.removeChild(wsNode);
0423: //if there are no more children, remove the web-services node
0424: NodeList children = webservices
0425: .getChildNodes();
0426: if (children.getLength() == 0) {
0427: data.removeChild(webservices);
0428: }
0429: needsSave = true;
0430: break;
0431: }
0432: }
0433: }
0434: }
0435: }
0436: }
0437: if (needsSave) {
0438: helper.putPrimaryConfigurationData(data, true);
0439: try {
0440: ProjectManager.getDefault().saveProject(project);
0441: } catch (java.io.IOException ex) {
0442: String mes = NbBundle.getMessage(this .getClass(),
0443: "MSG_ErrorSavingOnWSRemove")
0444: + serviceName // NOI18N
0445: + "'\r\n" + ex.getMessage(); // NOI18N
0446: NotifyDescriptor desc = new NotifyDescriptor.Message(
0447: mes, NotifyDescriptor.Message.ERROR_MESSAGE);
0448: DialogDisplayer.getDefault().notify(desc);
0449: }
0450: }
0451: }
0452:
0453: public void removeServiceEntry(String linkName) {
0454: //remove ejb entry in ejb-jar.xml
0455: org.netbeans.modules.j2ee.api.ejbjar.EjbJar ejbJarModule = org.netbeans.modules.j2ee.api.ejbjar.EjbJar
0456: .getEjbJars(project)[0];
0457: EjbJar ejbJar = getEjbJar();
0458: EnterpriseBeans beans = ejbJar.getEnterpriseBeans();
0459: Session[] sessionBeans = beans.getSession();
0460: for (int i = 0; i < sessionBeans.length; i++) {
0461: Session sessionBean = sessionBeans[i];
0462: if (sessionBean.getEjbName().equals(linkName)) {
0463: EjbJarProvider pwm = project.getLookup().lookup(
0464: EjbJarProvider.class);
0465: pwm.getConfigSupport().ensureConfigurationReady();
0466: beans.removeSession(sessionBean);
0467: break;
0468: }
0469: }
0470: try {
0471: ejbJar.write(ejbJarModule.getDeploymentDescriptor());
0472: } catch (java.io.IOException e) {
0473: NotifyDescriptor ndd = new NotifyDescriptor.Message(
0474: NbBundle.getMessage(this .getClass(),
0475: "MSG_Unable_WRITE_EJB_DD"), // NOI18N
0476: NotifyDescriptor.ERROR_MESSAGE);
0477: DialogDisplayer.getDefault().notify(ndd);
0478: }
0479: }
0480:
0481: public AntProjectHelper getAntProjectHelper() {
0482: return helper;
0483: }
0484:
0485: public ReferenceHelper getReferenceHelper() {
0486: return referenceHelper;
0487: }
0488:
0489: /** !PW This method is exposed in the service support API. Though it's
0490: * implementation makes more sense here than anywhere else, perhaps this
0491: * and the other project.xml/project.properties related methods in this
0492: * object should be refactored into another object that this one delegates
0493: * to. That way, this method would be directly available within the web or
0494: * ejb module, as it is needed, and remain missing from the API (where it
0495: * probably does not belong at this time.
0496: */
0497: private static final String[] WSCOMPILE_SEI_SERVICE_FEATURES = {
0498: // "datahandleronly", // WSDL - portable
0499: "documentliteral", // SEI ONLY - portable
0500: "rpcliteral", // SEI ONLY - portable
0501: // "explicitcontext", // WSDL - portable
0502: // "infix:<name>", // difficult handle with current API
0503: // "jaxbenumtype", // WSDL
0504: // "nodatabinding", // WSDL - portable
0505: "noencodedtypes", "nomultirefs",
0506: // "norpcstructures", // import only - portable
0507: // "novalidation", // WSDL - portable
0508: // "resolveidref", // WSDL
0509: // "searchschema", // WSDL - portable
0510: "serializeinterfaces", "strict", // - portable
0511: "useonewayoperations", // SEI ONLY - portable
0512: // "wsi", // WSDL - portable
0513: // "unwrap", // WSDL - portable
0514: "donotoverride", // - portable
0515: // "donotunwrap", // WSDL - portable
0516: };
0517:
0518: private static final List allSeiServiceFeatures = Arrays
0519: .asList(WSCOMPILE_SEI_SERVICE_FEATURES);
0520:
0521: private static final String[] WSCOMPILE_KEY_SEI_SERVICE_FEATURES = {
0522: "documentliteral", "rpcliteral", "strict",
0523: "useonewayoperations", "donotoverride" };
0524:
0525: private static final List importantSeiServiceFeatures = Arrays
0526: .asList(WSCOMPILE_KEY_SEI_SERVICE_FEATURES);
0527:
0528: private static final String[] WSCOMPILE_WSDL_SERVICE_FEATURES = {
0529: "datahandleronly", // WSDL - portable
0530: // "documentliteral", // SEI ONLY - portable
0531: // "rpcliteral", // SEI ONLY - portable
0532: "explicitcontext", // WSDL - portable
0533: // "infix:<name>", // difficult handle with current API
0534: "jaxbenumtype", // WSDL
0535: "nodatabinding", // WSDL - portable
0536: "noencodedtypes", "nomultirefs", "norpcstructures", // import only - portable
0537: "novalidation", // WSDL - portable
0538: "resolveidref", // WSDL
0539: "searchschema", // WSDL - portable
0540: "serializeinterfaces", "strict", // - portable
0541: // "useonewayoperations", // SEI ONLY - portable
0542: "wsi", // WSDL - portable
0543: "unwrap", // WSDL - portable
0544: "donotoverride", // - portable
0545: "donotunwrap", // WSDL - portable
0546: };
0547:
0548: private static final List allWsdlServiceFeatures = Arrays
0549: .asList(WSCOMPILE_WSDL_SERVICE_FEATURES);
0550:
0551: private static final String[] WSCOMPILE_KEY_WSDL_SERVICE_FEATURES = {
0552: "datahandleronly", "explicitcontext", "nodatabinding",
0553: "novalidation", "searchschema", "strict", "wsi", "unwrap",
0554: "donotoverride", "donotunwrap" };
0555:
0556: private static final List importantWsdlServiceFeatures = Arrays
0557: .asList(WSCOMPILE_KEY_WSDL_SERVICE_FEATURES);
0558:
0559: public List/*WsCompileEditorSupport.ServiceSettings*/getServices() {
0560: List<WsCompileEditorSupport.ServiceSettings> serviceList = new ArrayList<WsCompileEditorSupport.ServiceSettings>();
0561:
0562: // Implementation from getServiceClients() -- FIXME
0563: Element data = helper.getPrimaryConfigurationData(true);
0564: NodeList nodes = data
0565: .getElementsByTagName(WebServicesConstants.WEB_SERVICES);
0566: EditableProperties projectProperties = helper
0567: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
0568:
0569: if (nodes.getLength() != 0) {
0570: Element serviceElements = (Element) nodes.item(0);
0571: NodeList serviceNameList = serviceElements
0572: .getElementsByTagNameNS(
0573: EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0574: WebServicesConstants.WEB_SERVICE_NAME);
0575: for (int i = 0; i < serviceNameList.getLength(); i++) {
0576: Element serviceNameElement = (Element) serviceNameList
0577: .item(i);
0578: NodeList nl = serviceNameElement.getChildNodes();
0579: if (nl.getLength() == 1) {
0580: org.w3c.dom.Node n = nl.item(0);
0581: if (n.getNodeType() == org.w3c.dom.Node.TEXT_NODE) {
0582: String serviceName = n.getNodeValue();
0583: String currentFeatures = projectProperties
0584: .getProperty("wscompile.service."
0585: + serviceName + ".features"); // NOI18N
0586: StubDescriptor stubType = getServiceStubDescriptor(serviceNameElement
0587: .getParentNode());
0588: WsCompileEditorSupport.ServiceSettings settings;
0589:
0590: // !PW The logic for managing wscompile options needs refactoring badly.
0591: if (seiServiceStub == stubType) {
0592: if (currentFeatures == null) {
0593: // default for SEI generation
0594: currentFeatures = seiServiceStub
0595: .getDefaultFeaturesAsArgument();
0596: }
0597: settings = new WsCompileEditorSupport.ServiceSettings(
0598: serviceName, stubType,
0599: currentFeatures,
0600: allSeiServiceFeatures,
0601: importantSeiServiceFeatures);
0602: } else {
0603: if (currentFeatures == null) {
0604: // default for WSDL generation
0605: currentFeatures = wsdlServiceStub
0606: .getDefaultFeaturesAsArgument();
0607: }
0608: settings = new WsCompileEditorSupport.ServiceSettings(
0609: serviceName, stubType,
0610: currentFeatures,
0611: allWsdlServiceFeatures,
0612: importantWsdlServiceFeatures);
0613: }
0614: serviceList.add(settings);
0615: } else {
0616: // !PW FIXME node is wrong type?! - log message or trace?
0617: }
0618: } else {
0619: // !PW FIXME no name for this service entry - notify user
0620: }
0621: }
0622: }
0623:
0624: return serviceList;
0625: }
0626:
0627: private StubDescriptor getServiceStubDescriptor(
0628: org.w3c.dom.Node parentNode) {
0629: StubDescriptor result = null;
0630:
0631: if (parentNode instanceof Element) {
0632: Element parentElement = (Element) parentNode;
0633: NodeList fromWsdlList = parentElement
0634: .getElementsByTagNameNS(
0635: EjbJarProjectType.PROJECT_CONFIGURATION_NAMESPACE,
0636: WebServicesConstants.WEB_SERVICE_FROM_WSDL);
0637: if (fromWsdlList.getLength() == 1) {
0638: result = wsdlServiceStub;
0639: } else {
0640: result = seiServiceStub;
0641: }
0642: }
0643:
0644: return result;
0645: }
0646:
0647: private boolean updateWsCompileProperties(String serviceName) {
0648: /** Ensure wscompile.classpath and wscompile.tools.classpath are
0649: * properly defined.
0650: *
0651: * wscompile.classpath goes in project properties and includes
0652: * jaxrpc and qname right now.
0653: *
0654: * wscompile.tools.classpath is for tools.jar which is needed when
0655: * running under the Sun JDK to invoke javac. It is placed in
0656: * user.properties so that if we compute it incorrectly (say on a mac)
0657: * the user can change it and we will not blow away the change.
0658: * Hopefully we can do this better for release.
0659: */
0660: boolean globalPropertiesChanged = false;
0661:
0662: EditableProperties globalProperties = PropertyUtils
0663: .getGlobalProperties();
0664: if (globalProperties.getProperty(WSCOMPILE_TOOLS_CLASSPATH) == null) {
0665: globalProperties.setProperty(WSCOMPILE_TOOLS_CLASSPATH,
0666: "${java.home}\\..\\lib\\tools.jar");
0667:
0668: try {
0669: PropertyUtils.putGlobalProperties(globalProperties);
0670: } catch (java.io.IOException ex) {
0671: String mes = "Error saving global properties when adding wscompile.tools.classpath for service '"
0672: + serviceName + "'\r\n" + ex.getMessage();
0673: NotifyDescriptor desc = new NotifyDescriptor.Message(
0674: mes, NotifyDescriptor.Message.ERROR_MESSAGE);
0675: DialogDisplayer.getDefault().notify(desc);
0676: }
0677:
0678: globalPropertiesChanged = true;
0679: }
0680:
0681: boolean projectPropertiesChanged = false;
0682: EditableProperties projectProperties = helper
0683: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
0684:
0685: { // Block that adjusts wscompile.client.classpath as necessary.
0686: HashSet<String> wscJars = new HashSet<String>();
0687: boolean newWscJars = false;
0688: String wscClientClasspath = projectProperties
0689: .getProperty(WSCOMPILE_CLASSPATH);
0690: if (wscClientClasspath != null) {
0691: String[] libs = PropertyUtils
0692: .tokenizePath(wscClientClasspath);
0693: for (int i = 0; i < libs.length; i++) {
0694: wscJars.add(libs[i]);
0695: }
0696: }
0697:
0698: for (int i = 0; i < WSCOMPILE_JARS.length; i++) {
0699: if (!wscJars.contains(WSCOMPILE_JARS[i])) {
0700: wscJars.add(WSCOMPILE_JARS[i]);
0701: newWscJars = true;
0702: }
0703: }
0704:
0705: if (newWscJars) {
0706: StringBuffer newClasspathBuf = new StringBuffer(256);
0707: for (Iterator iter = wscJars.iterator(); iter.hasNext();) {
0708: newClasspathBuf.append(iter.next().toString());
0709: if (iter.hasNext()) {
0710: newClasspathBuf.append(":");
0711: }
0712: }
0713: projectProperties.put(WSCOMPILE_CLASSPATH,
0714: newClasspathBuf.toString());
0715: projectPropertiesChanged = true;
0716: }
0717: }
0718:
0719: // set tools.jar property if not set
0720: if (projectProperties.getProperty(WSCOMPILE_TOOLS_CLASSPATH) == null) {
0721: projectProperties.setProperty(WSCOMPILE_TOOLS_CLASSPATH,
0722: "${java.home}\\..\\lib\\tools.jar"); // NOI18N
0723: projectPropertiesChanged = true;
0724: }
0725:
0726: if (projectPropertiesChanged) {
0727: helper.putProperties(
0728: AntProjectHelper.PROJECT_PROPERTIES_PATH,
0729: projectProperties);
0730: }
0731: return globalPropertiesChanged || projectPropertiesChanged;
0732: }
0733:
0734: public void addInfrastructure(String implBeanClass, FileObject pkg) {
0735: FileObject implClassFo = pkg.getFileObject(implBeanClass,
0736: "java");
0737: if (implClassFo == null) {
0738: return;
0739: }
0740: JavaSource targetSource = JavaSource.forFileObject(implClassFo);
0741: final CancellableTask<WorkingCopy> modificationTask = new CancellableTask<WorkingCopy>() {
0742: public void run(WorkingCopy workingCopy) throws IOException {
0743: workingCopy.toPhase(Phase.RESOLVED);
0744: TreeMaker make = workingCopy.getTreeMaker();
0745: ClassTree javaClass = SourceUtils
0746: .getPublicTopLevelTree(workingCopy);
0747: IdentifierTree id = make
0748: .Identifier("javax.ejb.SessionBean");
0749: ClassTree modifiedClass = make
0750: .addClassImplementsClause(javaClass, id);
0751:
0752: List<? extends Tree> implClauses = javaClass
0753: .getImplementsClause();
0754: for (Tree implClause : implClauses) {
0755: if (implClause.getKind() == Kind.MEMBER_SELECT) {
0756: if (((MemberSelectTree) implClause)
0757: .getIdentifier()
0758: .contentEquals("Remote")) {
0759: modifiedClass = make
0760: .removeClassImplementsClause(
0761: modifiedClass, implClause);
0762: break;
0763: }
0764: }
0765: }
0766:
0767: VariableTree var = make
0768: .Variable(
0769: make
0770: .Modifiers(
0771: Collections
0772: .<Modifier> singleton(Modifier.PRIVATE),
0773: Collections
0774: .<AnnotationTree> emptyList()),
0775: "context",
0776: make
0777: .Identifier("javax.ejb.SessionContext"),
0778: null);
0779: modifiedClass = make.insertClassMember(modifiedClass,
0780: 0, var);
0781:
0782: ModifiersTree modifiersTree = make.Modifiers(
0783: Collections
0784: .<Modifier> singleton(Modifier.PUBLIC),
0785: Collections.<AnnotationTree> emptyList());
0786: List<VariableTree> params = new ArrayList<VariableTree>();
0787: params.add(make.Variable(make.Modifiers(Collections
0788: .<Modifier> emptySet(), Collections
0789: .<AnnotationTree> emptyList()), "aContext",
0790: make.Identifier("javax.ejb.SessionContext"), // parameter type
0791: null // initializer - does not make sense in parameters.
0792: ));
0793: MethodTree infMethod = make.Method(modifiersTree,
0794: "setSessionContext", make.Identifier("void"),
0795: Collections.<TypeParameterTree> emptyList(),
0796: params, Collections
0797: .<ExpressionTree> emptyList(),
0798: "{context = aContext;}", null);
0799: modifiedClass = make.addClassMember(modifiedClass,
0800: infMethod);
0801:
0802: params.clear();
0803: infMethod = make.Method(modifiersTree, "ejbActivate",
0804: make.Identifier("void"), Collections
0805: .<TypeParameterTree> emptyList(),
0806: params, Collections
0807: .<ExpressionTree> emptyList(), "{}",
0808: null);
0809: modifiedClass = make.addClassMember(modifiedClass,
0810: infMethod);
0811:
0812: infMethod = make.Method(modifiersTree, "ejbPassivate",
0813: make.Identifier("void"), Collections
0814: .<TypeParameterTree> emptyList(),
0815: params, Collections
0816: .<ExpressionTree> emptyList(), "{}",
0817: null);
0818: modifiedClass = make.addClassMember(modifiedClass,
0819: infMethod);
0820:
0821: infMethod = make.Method(modifiersTree, "ejbRemove",
0822: make.Identifier("void"), Collections
0823: .<TypeParameterTree> emptyList(),
0824: params, Collections
0825: .<ExpressionTree> emptyList(), "{}",
0826: null);
0827: modifiedClass = make.addClassMember(modifiedClass,
0828: infMethod);
0829:
0830: infMethod = make.Method(modifiersTree, "ejbCreate",
0831: make.Identifier("void"), Collections
0832: .<TypeParameterTree> emptyList(),
0833: params, Collections
0834: .<ExpressionTree> emptyList(), "{}",
0835: null);
0836: modifiedClass = make.addClassMember(modifiedClass,
0837: infMethod);
0838: workingCopy.rewrite(javaClass, modifiedClass);
0839: }
0840:
0841: public void cancel() {
0842: }
0843: };
0844:
0845: try {
0846: targetSource.runModificationTask(modificationTask).commit();
0847: } catch (IOException e) {
0848: ErrorManager.getDefault().notify(e);
0849: }
0850: //TODO: RETOUCHE webservices
0851: // boolean rollbackFlag = true; // rollback the transaction by default
0852: // JavaModel.getJavaRepository().beginTrans(true);
0853: // try {
0854: // JavaModel.setClassPath(pkg);
0855: // JavaMetamodel.getManager().waitScanFinished();
0856: // JavaClass clazz = Utils.findClass(implBeanClass);
0857: //
0858: // if (clazz == null) {
0859: // ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL,
0860: // "EjbJarWSSupport.addInfrastructure: Class not found: " + implBeanClass + " for package: " + pkg); //NOI18N
0861: // return;
0862: // }
0863: //
0864: // //remove java.rmi.Remote interface
0865: // List interfaces = clazz.getInterfaceNames();
0866: // for (Iterator it = interfaces.iterator(); it.hasNext();) {
0867: // MultipartId interfaceId = (MultipartId) it.next();
0868: // if (interfaceId.getElement().getName().equals("java.rmi.Remote")) {
0869: // interfaces.remove(interfaceId);
0870: // break;
0871: // }
0872: // }
0873: //
0874: // MultipartId id = JavaModelUtil.resolveImportsForClass(clazz, Utils.findClass("javax.ejb.SessionBean"));
0875: // if (id!=null) interfaces.add(id);
0876: //
0877: // JavaModelPackage jmp = (JavaModelPackage) clazz.refImmediatePackage();
0878: //
0879: // //add javax.ejb.SessionContext field
0880: // JavaClass sessionCtx = Utils.findClass("javax.ejb.SessionContext");
0881: // Field field = jmp.getField().createField();
0882: // field.setType(sessionCtx);
0883: // field.setName("context");
0884: // clazz.getContents().add(0,field);
0885: //
0886: // //add setSessionContext(javax.ejb.SessionContext aContext) method
0887: // Method sessionCtxMethod = jmp.getMethod().createMethod();
0888: // sessionCtxMethod.setName("setSessionContext");
0889: // Parameter ctxParam = jmp.getParameter().createParameter(
0890: // "aContext",
0891: // Collections.EMPTY_LIST,
0892: // false,
0893: // jmp.getMultipartId().createMultipartId(sessionCtx.getName(), null, null), // type name
0894: // 0,
0895: // false);
0896: // sessionCtxMethod.getParameters().add(ctxParam);
0897: // sessionCtxMethod.setType(Utils.resolveType("void"));
0898: // sessionCtxMethod.setModifiers(Modifier.PUBLIC);
0899: // sessionCtxMethod.setBodyText("context = aContext;");
0900: // sessionCtxMethod.setJavadocText("@see javax.ejb.SessionBean#setSessionContext(javax.ejb.SessionContext)");
0901: // clazz.getContents().add(sessionCtxMethod);
0902: //
0903: // //add ejbActivate method
0904: // Method ejbActivateMethod = jmp.getMethod().createMethod();
0905: // ejbActivateMethod.setName("ejbActivate");
0906: // ejbActivateMethod.setType(Utils.resolveType("void"));
0907: // ejbActivateMethod.setModifiers(Modifier.PUBLIC);
0908: // ejbActivateMethod.setJavadocText("@see javax.ejb.SessionBean#ejbActivate()");
0909: // clazz.getContents().add(ejbActivateMethod);
0910: //
0911: // //add ejbPassivate method
0912: // Method ejbPassivateMethod = jmp.getMethod().createMethod();
0913: // ejbPassivateMethod.setName("ejbPassivate");
0914: // ejbPassivateMethod.setType(Utils.resolveType("void"));
0915: // ejbPassivateMethod.setModifiers(Modifier.PUBLIC);
0916: // ejbPassivateMethod.setJavadocText("@see javax.ejb.SessionBean#ejbPassivate()");
0917: // clazz.getContents().add(ejbPassivateMethod);
0918: //
0919: // //add ejbRemove method
0920: // Method ejbRemoveMethod = jmp.getMethod().createMethod();
0921: // ejbRemoveMethod.setName("ejbRemove");
0922: // ejbRemoveMethod.setType(Utils.resolveType("void"));
0923: // ejbRemoveMethod.setModifiers(Modifier.PUBLIC);
0924: // ejbRemoveMethod.setJavadocText("@see javax.ejb.SessionBean#ejbRemove()");
0925: // clazz.getContents().add(ejbRemoveMethod);
0926: //
0927: // //add ejbCreate method
0928: // Method ejbCreateMethod = jmp.getMethod().createMethod();
0929: // ejbCreateMethod.setName("ejbCreate");
0930: // ejbCreateMethod.setType(Utils.resolveType("void"));
0931: // ejbCreateMethod.setModifiers(Modifier.PUBLIC);
0932: // ejbCreateMethod.setJavadocText("See section 7.10.3 of the EJB 2.0 specification\nSee section 7.11.3 of the EJB 2.1 specification");
0933: // clazz.getContents().add(ejbCreateMethod);
0934: //
0935: // rollbackFlag=false;
0936: // } finally {
0937: // JavaModel.getJavaRepository().endTrans(rollbackFlag);
0938: // }
0939: }
0940:
0941: private EjbJar getEjbJar() {
0942: try {
0943: // TODO: first one API EjbJar from project is taken... this should be fixed
0944: return DDProvider.getDefault().getDDRoot(
0945: org.netbeans.modules.j2ee.api.ejbjar.EjbJar
0946: .getEjbJars(project)[0]
0947: .getDeploymentDescriptor());
0948: } catch (java.io.IOException e) {
0949: Logger.getLogger("global").log(Level.INFO,
0950: e.getLocalizedMessage());
0951: }
0952: return null;
0953: }
0954:
0955: public FileObject getMetaInf() {
0956: EjbJarProvider provider = project.getLookup().lookup(
0957: EjbJarProvider.class);
0958: return provider.getMetaInf();
0959: }
0960:
0961: public FileObject getDeploymentDescriptor() {
0962: FileObject metaInfFo = getMetaInf();
0963: if (metaInfFo == null) {
0964: return null;
0965: }
0966: return metaInfFo.getFileObject(EjbJarProvider.FILE_DD);
0967: }
0968:
0969: private String getPackageName(FileObject file) {
0970: FileObject parent = file.getParent();
0971: Sources sources = ProjectUtils.getSources(project);
0972: SourceGroup[] groups = sources
0973: .getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
0974: String packageName = null;
0975: for (int i = 0; i < groups.length && packageName == null; i++) {
0976: packageName = FileUtil.getRelativePath(groups[i]
0977: .getRootFolder(), parent);
0978: if (packageName != null) {
0979: packageName = groups[i].getName() + "/" + packageName;
0980: }
0981: }
0982: return packageName + "";
0983: }
0984:
0985: private FileObject getFileObject(String propname) {
0986: String prop = helper.getStandardPropertyEvaluator()
0987: .getProperty(propname);
0988: if (prop != null) {
0989: return helper.resolveFileObject(prop);
0990: }
0991:
0992: return null;
0993: }
0994:
0995: public FileObject getWsdlFolder(boolean create) throws IOException {
0996: FileObject wsdlFolder = null;
0997: FileObject metaInf = getMetaInf();
0998:
0999: if (metaInf != null) {
1000: wsdlFolder = metaInf.getFileObject(WSDL_FOLDER);
1001: if (wsdlFolder == null && create) {
1002: wsdlFolder = metaInf.createFolder(WSDL_FOLDER);
1003: }
1004: } else if (create) {
1005: // Create was specified, but no META-INF was found, so how do we create it?
1006: // Expect an NPE if we return null for this case, but log it anyway.
1007: Logger.getLogger("global").log(
1008: Level.INFO,
1009: NbBundle.getMessage(EjbJarWebServicesSupport.class,
1010: "MSG_MetaInfNotFoundForWsdlFolder"));
1011: }
1012:
1013: return wsdlFolder;
1014: }
1015:
1016: public ClassPath getClassPath() {
1017: synchronized (this ) {
1018: if (projectSourcesClassPath == null) {
1019: ClassPathProviderImpl cpProvider = project
1020: .getClassPathProvider();
1021: projectSourcesClassPath = ClassPathSupport
1022: .createProxyClassPath(new ClassPath[] {
1023: cpProvider
1024: .getProjectSourcesClassPath(ClassPath.SOURCE),
1025: cpProvider.getJ2eePlatformClassPath(), });
1026: }
1027: return projectSourcesClassPath;
1028: }
1029: }
1030:
1031: // Service stub descriptors
1032: private static final JAXRPCStubDescriptor seiServiceStub = new JAXRPCStubDescriptor(
1033: StubDescriptor.SEI_SERVICE_STUB, NbBundle.getMessage(
1034: EjbJarWebServicesSupport.class,
1035: "LBL_SEIServiceStub"), // NOI18N
1036: new String[] { "documentliteral", "strict",
1037: "useonewayoperations" });
1038:
1039: private static final JAXRPCStubDescriptor wsdlServiceStub = new JAXRPCStubDescriptor(
1040: StubDescriptor.WSDL_SERVICE_STUB, NbBundle.getMessage(
1041: EjbJarWebServicesSupport.class,
1042: "LBL_WSDLServiceStub"), // NOI18N
1043: new String[] { "wsi", "strict" }); // NOI18N
1044:
1045: /** Stub descriptor for services supported by this project type.
1046: */
1047: private static class JAXRPCStubDescriptor extends StubDescriptor {
1048:
1049: private String[] defaultFeatures;
1050:
1051: public JAXRPCStubDescriptor(String name, String displayName,
1052: String[] defaultFeatures) {
1053: super (name, displayName);
1054:
1055: this .defaultFeatures = defaultFeatures;
1056: }
1057:
1058: public String[] getDefaultFeatures() {
1059: return defaultFeatures;
1060: }
1061:
1062: public String getDefaultFeaturesAsArgument() {
1063: StringBuffer buf = new StringBuffer(
1064: defaultFeatures.length * 32);
1065: for (int i = 0; i < defaultFeatures.length; i++) {
1066: if (i > 0) {
1067: buf.append(",");
1068: }
1069:
1070: buf.append(defaultFeatures[i]);
1071: }
1072: return buf.toString();
1073: }
1074: }
1075: }
|