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: package org.netbeans.modules.compapp.casaeditor.model.casa;
0042:
0043: import java.beans.PropertyChangeEvent;
0044: import java.beans.PropertyChangeListener;
0045: import java.beans.PropertyChangeSupport;
0046: import java.beans.PropertyVetoException;
0047: import java.io.*;
0048: import java.net.URI;
0049: import java.net.URISyntaxException;
0050: import java.util.*;
0051: import java.util.List;
0052: import java.util.regex.Matcher;
0053: import java.util.regex.Pattern;
0054: import java.awt.*;
0055: import javax.swing.SwingUtilities;
0056: import javax.xml.namespace.QName;
0057: import javax.xml.xpath.XPathExpressionException;
0058: import org.netbeans.api.project.Project;
0059: import org.netbeans.api.project.ProjectManager;
0060: import org.netbeans.api.project.ProjectUtils;
0061: import org.netbeans.api.project.ant.AntArtifact;
0062: import org.netbeans.api.progress.ProgressHandle;
0063: import org.netbeans.api.progress.ProgressHandleFactory;
0064: import org.netbeans.modules.compapp.casaeditor.model.casa.impl.CasaAttribute;
0065: import org.netbeans.modules.compapp.casaeditor.model.jbi.impl.JBIAttributes;
0066: import org.netbeans.modules.compapp.casaeditor.nodes.actions.CasaValidationController;
0067: import org.netbeans.modules.compapp.casaeditor.api.WizardPropertiesTemp;
0068: import org.netbeans.modules.compapp.casaeditor.model.casa.impl.CasaComponentFactoryImpl;
0069: import org.netbeans.modules.compapp.casaeditor.model.casa.impl.CasaImpl;
0070: import org.netbeans.modules.compapp.casaeditor.model.casa.impl.CasaSyncUpdateVisitor;
0071: import org.netbeans.modules.compapp.projects.jbi.api.*;
0072: import org.netbeans.modules.compapp.projects.jbi.ui.actions.AddProjectAction;
0073: import org.netbeans.modules.compapp.projects.jbi.ui.actions.DeleteModuleAction;
0074: import org.netbeans.modules.xml.wsdl.model.visitor.FindWSDLComponent;
0075: import org.netbeans.modules.xml.wsdl.bindingsupport.template.ExtensibilityElementTemplateFactory;
0076: import org.netbeans.modules.xml.wsdl.bindingsupport.template.TemplateGroup;
0077: import org.netbeans.modules.xml.wsdl.bindingsupport.template.localized.LocalizedTemplate;
0078: import org.netbeans.modules.xml.wsdl.bindingsupport.template.localized.LocalizedTemplateGroup;
0079: import org.netbeans.modules.xml.wsdl.ui.wizard.BindingGenerator;
0080: import org.netbeans.modules.xml.wsdl.ui.wizard.WizardBindingConfigurationStep;
0081: import org.netbeans.modules.xml.wsdl.bindingsupport.spi.ValidationInfo;
0082: import org.netbeans.modules.xml.wsdl.model.Binding;
0083: import org.netbeans.modules.xml.wsdl.model.BindingOperation;
0084: import org.netbeans.modules.xml.wsdl.model.Definitions;
0085: import org.netbeans.modules.xml.wsdl.model.ExtensibilityElement;
0086: import org.netbeans.modules.xml.wsdl.model.Import;
0087: import org.netbeans.modules.xml.wsdl.model.Port;
0088: import org.netbeans.modules.xml.wsdl.model.PortType;
0089: import org.netbeans.modules.xml.wsdl.model.Service;
0090: import org.netbeans.modules.xml.wsdl.model.WSDLComponent;
0091: import org.netbeans.modules.xml.wsdl.model.WSDLComponentFactory;
0092: import org.netbeans.modules.xml.wsdl.model.WSDLModel;
0093: import org.netbeans.modules.xml.wsdl.model.WSDLModelFactory;
0094: import org.netbeans.modules.xml.xam.ComponentUpdater;
0095: import org.netbeans.modules.xml.xam.Model;
0096: import org.netbeans.modules.xml.xam.ModelSource;
0097: import org.netbeans.modules.xml.xam.dom.AbstractDocumentModel;
0098: import org.netbeans.modules.xml.xam.locator.CatalogModel;
0099: import org.netbeans.modules.xml.xam.locator.CatalogModelException;
0100: import org.netbeans.modules.xml.xam.spi.Validation;
0101: import org.netbeans.modules.xml.xam.spi.Validation.ValidationType;
0102: import org.netbeans.modules.xml.xam.spi.Validator.ResultItem;
0103: import org.netbeans.spi.project.ant.AntArtifactProvider;
0104: import org.openide.DialogDisplayer;
0105: import org.openide.ErrorManager;
0106: import org.openide.NotifyDescriptor;
0107: import org.openide.WizardDescriptor;
0108: import org.openide.cookies.SaveCookie;
0109: import org.openide.filesystems.FileObject;
0110: import org.openide.filesystems.FileUtil;
0111: import org.openide.loaders.DataObject;
0112: import org.openide.loaders.DataObjectNotFoundException;
0113: import org.openide.util.Lookup;
0114: import org.openide.util.NbBundle;
0115: import org.openide.util.RequestProcessor;
0116: import org.openide.util.actions.SystemAction;
0117: import org.w3c.dom.Element;
0118: import org.w3c.dom.NamedNodeMap;
0119: import org.w3c.dom.Node;
0120:
0121: import static org.netbeans.modules.compapp.projects.jbi.api.JbiEndpointExtensionConstants.*;
0122:
0123: /**
0124: *
0125: * @author jqian
0126: */
0127: public class CasaWrapperModel extends CasaModel {
0128:
0129: public static final String PROPERTY_PREFIX = "model_property_"; // NOI18N
0130: public static final String PROPERTY_MODEL_RELOAD = PROPERTY_PREFIX
0131: + "reload"; // NOI18N
0132: public static final String PROPERTY_CONNECTION_REMOVED = PROPERTY_PREFIX
0133: + "connection_removed"; // NOI18N
0134: public static final String PROPERTY_CONNECTION_ADDED = PROPERTY_PREFIX
0135: + "connection_added"; // NOI18N
0136: public static final String PROPERTY_CASA_PORT_REMOVED = PROPERTY_PREFIX
0137: + "casa_port_removed"; // NOI18N
0138: public static final String PROPERTY_CASA_PORT_ADDED = PROPERTY_PREFIX
0139: + "casa_port_added"; // NOI18N
0140: public static final String PROPERTY_CASA_PORT_REFRESH = PROPERTY_PREFIX
0141: + "casa_port_refresh"; // NOI18N
0142: public static final String PROPERTY_ENDPOINT_REMOVED = PROPERTY_PREFIX
0143: + "endpoint_removed"; // NOI18N
0144: public static final String PROPERTY_ENDPOINT_ADDED = PROPERTY_PREFIX
0145: + "endpoint_added"; // NOI18N
0146: public static final String PROPERTY_ENDPOINT_NAME_CHANGED = PROPERTY_PREFIX
0147: + "endpoint_renamed"; // NOI18N
0148: public static final String PROPERTY_ENDPOINT_EXTENSION_CHANGED = PROPERTY_PREFIX
0149: + "endpoint_extension_changed"; // NOI18N
0150: public static final String PROPERTY_ENDPOINT_INTERFACE_QNAME_CHANGED = PROPERTY_PREFIX
0151: + "endpoint_interface_qname_changed"; // NOI18N
0152: public static final String PROPERTY_ENDPOINT_SERVICE_QNAME_CHANGED = PROPERTY_PREFIX
0153: + "endpoint_service_qname_changed"; // NOI18N
0154: public static final String PROPERTY_SERVICE_UNIT_RENAMED = PROPERTY_PREFIX
0155: + "service_unit_renamed"; // NOI18N
0156: public static final String PROPERTY_SERVICE_ENGINE_SERVICE_UNIT_ADDED = PROPERTY_PREFIX
0157: + "service_unit_added"; // NOI18N
0158: public static final String PROPERTY_SERVICE_ENGINE_SERVICE_UNIT_REMOVED = PROPERTY_PREFIX
0159: + "service_unit_removed"; // NOI18N
0160: private static final String CASA_WSDL_RELATIVE_LOCATION = "../jbiasa/"; // NOI18N
0161: private static final String JBI_SERVICE_UNITS_DIR = "jbiServiceUnits"; // NOI18N
0162: private static final String JBI_SOURCE_DIR = "jbiasa"; // NOI18N
0163: private static final String DUMMY_PORTTYPE_NAME = "dummyCasaPortType"; // NOI18N
0164:
0165: private CasaComponentFactory factory;
0166: private Casa casa;
0167:
0168: private PropertyChangeSupport mSupport = new PropertyChangeSupport(
0169: this );
0170:
0171: // 01/24/07, added to support add/del SU projects
0172: // mapping project names to projects for pending projects to be added
0173: private Map<String, Project> mAddProjects = new HashMap<String, Project>();
0174: // mapping project names to project artifact names for pending projects to be deleted.
0175: private Map<String, String> mDeleteProjects = new HashMap<String, String>();
0176:
0177: // mapping WSDL port link hrefs to WSDL components
0178: private Map<String, WSDLComponent> cachedWSDLComponents = new HashMap<String, WSDLComponent>();
0179: private List<String> artifactTypes = new ArrayList<String>();
0180:
0181: // // mapping binding component name to binding type,
0182: // // e.x, "sun-smtp-binding" -> "smtp".
0183: // private Map<String, String> bcName2BindingType;
0184: //
0185: // // mapping binding type to binding component name,
0186: // // e.x, "smtp" -> "sun-smtp-binding".
0187: // private Map<String, String> bindingType2BcName;
0188:
0189: // Any CompApp WSDL change should mark CASA "dirty" (IZ 96390)
0190: private PropertyChangeListener markCasaDirtyListener;
0191:
0192: // // a flag that can be used to avoid endless error messages for the same
0193: // // reason of unavailable WSDL model (IZ 117533)
0194: // private boolean mayShowUnavailableWSDLModelError = true;
0195:
0196: /** Creates a new instance of CasaWrapperModel */
0197: public CasaWrapperModel(ModelSource source) {
0198: super (source);
0199: factory = new CasaComponentFactoryImpl(this );
0200:
0201: artifactTypes.add(JbiProjectConstants.ARTIFACT_TYPE_JBI_ASA);
0202:
0203: markCasaDirtyListener = new PropertyChangeListener() {
0204:
0205: public void propertyChange(PropertyChangeEvent evt) {
0206: DataObject dataObject = getDataObject(CasaWrapperModel.this );
0207: if (!dataObject.isModified()) {
0208: dataObject.setModified(true);
0209: }
0210: }
0211: };
0212: }
0213:
0214: @Override
0215: public void removePropertyChangeListener(
0216: final PropertyChangeListener pcl) {
0217: super .removePropertyChangeListener(pcl);
0218: mSupport.removePropertyChangeListener(pcl);
0219: }
0220:
0221: /**
0222: * Add property change listener which will receive events for any element
0223: * in the underlying sa jbi model.
0224: */
0225: @Override
0226: public void addPropertyChangeListener(
0227: final PropertyChangeListener pcl) {
0228: super .addPropertyChangeListener(pcl);
0229: mSupport.addPropertyChangeListener(pcl);
0230: }
0231:
0232: /**
0233: * Gets a list of binding component service units.
0234: */
0235: public List<CasaBindingComponentServiceUnit> getBindingComponentServiceUnits() {
0236: CasaServiceUnits serviceUnits = getRootComponent()
0237: .getServiceUnits();
0238: return serviceUnits.getBindingComponentServiceUnits();
0239: }
0240:
0241: /**
0242: * Gets a list of service engine service units.
0243: */
0244: public List<CasaServiceEngineServiceUnit> getServiceEngineServiceUnits() {
0245: CasaServiceUnits serviceUnits = getRootComponent()
0246: .getServiceUnits();
0247: return serviceUnits.getServiceEngineServiceUnits();
0248: }
0249:
0250: /**
0251: * Tests if a service engine service unit with the given unit name exists.
0252: */
0253: public boolean existingServiceEngineServiceUnit(String unitName) {
0254: for (CasaServiceEngineServiceUnit serviceUnit : getServiceEngineServiceUnits()) {
0255: if (unitName.equalsIgnoreCase(serviceUnit.getUnitName())) {
0256: return true;
0257: }
0258: }
0259:
0260: return false;
0261: }
0262:
0263: /**
0264: * Gets all the visible WSDL endpoints in the CASA model.
0265: */
0266: public List<CasaPort> getCasaPorts() {
0267: List<CasaPort> ret = new ArrayList<CasaPort>();
0268: for (CasaBindingComponentServiceUnit bcSU : getBindingComponentServiceUnits()) {
0269: for (CasaPort casaPort : bcSU.getPorts().getPorts()) {
0270: if (!CasaPortState.DELETED.getState().equals(
0271: casaPort.getState())) {
0272: ret.add(casaPort);
0273: }
0274: }
0275: }
0276: return ret;
0277: }
0278:
0279: /**
0280: * Gets the name of the target binding component for a casa port.
0281: * For example, "sun-http-binding".
0282: */
0283: public String getBindingComponentName(final CasaPort casaPort) {
0284: CasaBindingComponentServiceUnit bcSU = (CasaBindingComponentServiceUnit) casaPort
0285: .getParent().getParent();
0286: return bcSU.getComponentName();
0287: }
0288:
0289: /**
0290: * Gets the binding type of the given casa port.
0291: * For example, "http" or "soap".
0292: */
0293: public String getBindingType(final CasaPort casaPort) {
0294: String bindingType = casaPort.getBindingType();
0295: if (bindingType == null) {
0296: //IZ: 113545
0297: try {
0298: Port port = getLinkedWSDLPort(casaPort);
0299: JbiBindingInfo bi = JbiDefaultComponentInfo
0300: .getBindingInfo(port);
0301: if (bi != null) {
0302: return bi.getBindingType();
0303: }
0304: } catch (Exception ex) {
0305: // skip to use the default one..
0306: }
0307: String bcCompName = getBindingComponentName(casaPort);
0308: bindingType = getDefaultBindingComponents().get(bcCompName);
0309: }
0310: return bindingType;
0311: }
0312:
0313: /**
0314: * Sets the endpoint name of a user-defined casa port in the compapp project.
0315: * The corresponding WSDL port's name will also be updated.
0316: */
0317: // TRANSACTION BOUNDARY
0318: // USE CASE: from property sheet
0319: // AFFECT: CASA, COMPAPP.WSDL
0320: public void setEndpointName(final CasaPort casaPort,
0321: String endpointName) {
0322: if (!isNCName(endpointName)) {
0323: String msg = NbBundle.getMessage(CasaWrapperModel.class,
0324: "MSG_INVALID_ENDPOINT_NAME", endpointName); // NOI18N
0325: NotifyDescriptor d = new NotifyDescriptor.Message(msg,
0326: NotifyDescriptor.ERROR_MESSAGE);
0327: DialogDisplayer.getDefault().notify(d);
0328: return;
0329: }
0330:
0331: assert isDefinedInCompApp(casaPort);
0332:
0333: CasaEndpointRef endpointRef = casaPort.getConsumes();
0334: if (endpointRef == null) {
0335: endpointRef = casaPort.getProvides();
0336: }
0337: assert endpointRef != null;
0338:
0339: setEndpointName(casaPort, endpointRef, endpointName);
0340: }
0341:
0342: /**
0343: * Sets the endpoint name of a casa consumes or casa provides.
0344: * The endpoint is either a external endpoint or a user-defined endpoint in
0345: * compapp project.
0346: */
0347: // TRANSACTION BOUNDARY
0348: // USE CASE: from property sheet
0349: // AFFECT: CASA, COMPAPP.WSDL
0350: public void setEndpointName(final CasaEndpointRef endpointRef,
0351: String endpointName) {
0352: if (!isNCName(endpointName)) {
0353: String msg = NbBundle.getMessage(CasaWrapperModel.class,
0354: "MSG_INVALID_ENDPOINT_NAME", endpointName); // NOI18N
0355: NotifyDescriptor d = new NotifyDescriptor.Message(msg,
0356: NotifyDescriptor.ERROR_MESSAGE);
0357: DialogDisplayer.getDefault().notify(d);
0358: return;
0359: }
0360:
0361: CasaPort casaPort = getCasaPort(endpointRef);
0362: if (casaPort == null) {
0363: CasaServiceEngineServiceUnit seSU = getCasaEngineServiceUnit(endpointRef);
0364: assert !seSU.isInternal();
0365: } else {
0366: assert isDefinedInCompApp(casaPort);
0367: }
0368:
0369: setEndpointName(endpointRef, endpointRef, endpointName);
0370: }
0371:
0372: /**
0373: * Adds a casa extensibility element.
0374: */
0375: // TRANSACTION BOUNDARY (MIGHT NOT)
0376: // USE CASE: from property sheet (editing non-existing extensibility element attribute)
0377: // USE CASE: from property sheet (editing choice extensibility element attribute) (NOT TRANSACTION BOUNDARY)
0378: // AFFECT: CASA
0379: public void addExtensibilityElement(CasaComponent parent,
0380: CasaExtensibilityElement ee) {
0381:
0382: startTransaction();
0383: try {
0384: parent.addExtensibilityElement(ee);
0385: } finally {
0386: if (isIntransaction()) {
0387: fireChangeEvent(ee, PROPERTY_ENDPOINT_EXTENSION_CHANGED);
0388: endTransaction();
0389: }
0390: }
0391: }
0392:
0393: /**
0394: * Removes a casa extensibility element.
0395: */
0396: // TRANSACTION BOUNDARY (NOT!)
0397: // USE CASE: from property sheet (editing choice extensibility element)
0398: // AFFECT: CASA
0399: public void removeExtensibilityElement(CasaComponent parent,
0400: CasaExtensibilityElement ee) {
0401:
0402: startTransaction();
0403: try {
0404: parent.removeExtensibilityElement(ee);
0405: } finally {
0406: if (isIntransaction()) {
0407: fireChangeEvent(ee, PROPERTY_ENDPOINT_EXTENSION_CHANGED);
0408: endTransaction();
0409: }
0410: }
0411: }
0412:
0413: /**
0414: * Sets an attribute value on a casa extensibility element.
0415: */
0416: // TRANSACTION BOUNDARY
0417: // USE CASE: from property sheet
0418: // AFFECT: CASA
0419: public void setExtensibilityElementAttribute(
0420: final CasaExtensibilityElement ee, String attrName,
0421: String attrValue) {
0422:
0423: startTransaction();
0424: try {
0425: ee.setAttribute(attrName, attrValue);
0426: } finally {
0427: if (isIntransaction()) {
0428: fireChangeEvent(ee, PROPERTY_ENDPOINT_EXTENSION_CHANGED);
0429: endTransaction();
0430: }
0431: }
0432: }
0433:
0434: /**
0435: * Gets the WSDL port linked by the casaport
0436: *
0437: * @param port the casaport
0438: * @return the wsdl port linked by the casaport
0439: */
0440: public Port getLinkedWSDLPort(final CasaPort casaPort) {
0441: String linkHref = casaPort.getLink().getHref();
0442: Port port = null;
0443: try {
0444: port = getWSDLComponentFromXLinkHref(linkHref, Port.class);
0445: } catch (Exception ex) {
0446: ex.printStackTrace();
0447: }
0448:
0449: return port;
0450: }
0451:
0452: /**
0453: * Gets a single <code>WSDLComponent</code> from a xlink href that looks like
0454: * "su-name/foo.wsdl#xpointer(some-xpath-for-a-single-wsdl-element)"
0455: *
0456: * @exception IllegalArgumentException if the given href doesn't match the
0457: * expected pattern.
0458: */
0459: @SuppressWarnings("unchecked")
0460: public <T extends WSDLComponent> T getWSDLComponentFromXLinkHref(
0461: String linkHref, Class<T> type) throws URISyntaxException,
0462: CatalogModelException, XPathExpressionException {
0463:
0464: WSDLComponent wsdlComponent = cachedWSDLComponents
0465: .get(linkHref);
0466:
0467: if (wsdlComponent == null) {
0468: String regex = "(.*)#xpointer\\((.*)\\)"; // NOI18N
0469: Pattern pattern = Pattern.compile(regex);
0470: Matcher matcher = pattern.matcher(linkHref);
0471:
0472: if (!matcher.matches()) {
0473: throw new IllegalArgumentException(
0474: "Invalid xlink href: " + linkHref); // NOI18N
0475: }
0476:
0477: String uriString = matcher.group(1);
0478: String xpathString = matcher.group(2);
0479:
0480: try {
0481: WSDLModel wsdlModel = getWSDLModel(uriString);
0482:
0483: if (wsdlModel != null) {
0484: WSDLComponent root = wsdlModel.getRootComponent();
0485: wsdlComponent = new FindWSDLComponent()
0486: .findComponent(root, xpathString);
0487: cachedWSDLComponents.put(linkHref, wsdlComponent);
0488: }
0489: } catch (URISyntaxException e) {
0490: String msg = NbBundle.getMessage(
0491: CasaWrapperModel.class, "MSG_INVALID_URI",
0492: uriString); // NOI18N
0493: NotifyDescriptor d = new NotifyDescriptor.Message(msg,
0494: NotifyDescriptor.ERROR_MESSAGE);
0495: DialogDisplayer.getDefault().notify(d);
0496: } catch (CatalogModelException e) {
0497: // if (mayShowUnavailableWSDLModelError) {
0498: String msg = NbBundle.getMessage(
0499: CasaWrapperModel.class,
0500: "MSG_UNAVAILABLE_WSDL_MODEL", uriString); // NOI18N
0501: System.err.println(msg);
0502: // NotifyDescriptor d =
0503: // new NotifyDescriptor.Message(msg, NotifyDescriptor.ERROR_MESSAGE);
0504: // DialogDisplayer.getDefault().notify(d);
0505: //
0506: // // I don't want to see this error message again before the
0507: // // project gets rebuilt.
0508: // mayShowUnavailableWSDLModelError = false;
0509: // }
0510: }
0511: }
0512:
0513: if (wsdlComponent != null) {
0514: WSDLModel wsdlModel = wsdlComponent.getModel();
0515: wsdlModel
0516: .removePropertyChangeListener(markCasaDirtyListener);
0517: wsdlModel.addPropertyChangeListener(markCasaDirtyListener);
0518: }
0519:
0520: return (T) wsdlComponent;
0521: }
0522:
0523: /**
0524: * Gets the casa provides or consumes endpoint from a casa connection.
0525: */
0526: public CasaEndpointRef getCasaEndpointRef(
0527: final CasaConnection casaConnection, boolean isConsumes) {
0528: CasaEndpoint casaEndpoint = isConsumes ? casaConnection
0529: .getConsumer().get() : casaConnection.getProvider()
0530: .get();
0531: return getCasaEndpointRef(casaEndpoint, isConsumes);
0532: }
0533:
0534: /**
0535: * Gets the CasaConsumes or CasaProvides that links to the given endpoint.
0536: */
0537: private CasaEndpointRef getCasaEndpointRef(
0538: final CasaEndpoint endpoint, boolean isConsumes) {
0539:
0540: for (CasaServiceEngineServiceUnit seSU : getServiceEngineServiceUnits()) {
0541: for (CasaEndpointRef endpointRef : seSU.getEndpoints()) {
0542: if (((isConsumes && endpointRef instanceof CasaConsumes) || (!isConsumes && endpointRef instanceof CasaProvides))
0543: && endpointRef.getEndpoint().get() == endpoint) {
0544: return endpointRef;
0545: }
0546: }
0547: }
0548:
0549: for (CasaBindingComponentServiceUnit bcSU : getBindingComponentServiceUnits()) {
0550: for (CasaPort casaPort : bcSU.getPorts().getPorts()) {
0551: CasaEndpointRef endpointRef = isConsumes ? casaPort
0552: .getConsumes() : casaPort.getProvides();
0553: if (endpointRef != null
0554: && endpointRef.getEndpoint().get() == endpoint) {
0555: return endpointRef;
0556: }
0557: }
0558: }
0559:
0560: return null;
0561: }
0562:
0563: /**
0564: * Gets the service engine service unit endpoint reference that references
0565: * the given endpoint.
0566: *
0567: * @param endpoint an endpoint
0568: * @return the service endinge service unit endpoint reference referencing
0569: * the given endpoint; or null if there is no service engine
0570: * service unit endpoint reference referencing the given endpoint.
0571: */
0572: public CasaEndpointRef getServiceEngineEndpointRef(
0573: final CasaEndpoint endpoint) {
0574:
0575: for (CasaServiceEngineServiceUnit seSU : getServiceEngineServiceUnits()) {
0576: for (CasaEndpointRef endpointRef : seSU.getEndpoints()) {
0577: if (endpointRef.getEndpoint().get() == endpoint) {
0578: return endpointRef;
0579: }
0580: }
0581: }
0582:
0583: return null;
0584: }
0585:
0586: /**
0587: * Sets the location of an internal/external service engine service unit.
0588: */
0589: // TRANSACTION BOUNDARY
0590: // USE CASE: on move
0591: // AFFECT: CASA
0592: public void setLocation(final CasaServiceEngineServiceUnit seSU,
0593: int x, int y) {
0594:
0595: if (seSU.getX() == x && seSU.getY() == y) {
0596: return;
0597: }
0598:
0599: startTransaction();
0600: try {
0601: seSU.setX(x);
0602: seSU.setY(y);
0603: } finally {
0604: if (isIntransaction()) {
0605: endTransaction();
0606: }
0607: }
0608: }
0609:
0610: /**
0611: * Sets the location of a casa port.
0612: */
0613: // TRANSACTION BOUNDARY
0614: // USE CASE: on drop (auto-layout); on move
0615: // AFFECT: CASA
0616: public void setLocation(final CasaPort casaPort, int x, int y) {
0617:
0618: if (casaPort.getX() == x && casaPort.getY() == y) {
0619: return;
0620: }
0621:
0622: startTransaction();
0623: try {
0624: casaPort.setX(x);
0625: casaPort.setY(y);
0626: } finally {
0627: if (isIntransaction()) {
0628: endTransaction();
0629: }
0630: }
0631: }
0632:
0633: /**
0634: * Adds a brand new connection or mark a previously deleted connection
0635: * as unchanged. Incompatible endpoint interface may be adjusted.
0636: */
0637: // TRANSACTION BOUNDARY (convenience method)
0638: // USE CASE: AddConnectionAction on Navigator
0639: // AFFECT: CASA, COMPAPP.WSDL
0640: public CasaConnection addConnection(final CasaConsumes consumes,
0641: final CasaProvides provides) {
0642: return addConnection(consumes, provides, true);
0643: }
0644:
0645: /**
0646: * Adds a brand new connection or mark a previously deleted connection
0647: * as unchanged.
0648: *
0649: * @param consumes a casa consumes endpoint
0650: * @param provides a casa provides endpoint
0651: * @param direction the (mouse) direction during the connection creation.
0652: * If <code>true</code>, the "source" endpoint is the
0653: * consumes endpoint; if <code>false</code>, the "source"
0654: * endpoint is the provides endpoint.
0655: */
0656: // TRANSACTION BOUNDARY
0657: // USE CASE: DnD-style connection on canvas; AddConnectionAction on Navigator
0658: // AFFECT: CASA, COMPAPP.WSDL
0659: public CasaConnection addConnection(final CasaConsumes consumes,
0660: final CasaProvides provides, boolean direction) {
0661:
0662: if (!canConnect(consumes, provides)) {
0663: throw new RuntimeException(
0664: "The two endpoints cannot be connected."); // NOI18N
0665: }
0666:
0667: // 1. Adjust the incompatible BC interface first, if necessary.
0668: boolean endpoint1Defined = isEndpointDefined(consumes);
0669: boolean endpoint2Defined = isEndpointDefined(provides);
0670: if (endpoint1Defined && endpoint2Defined) {
0671: QName consumesInterfaceQName = consumes.getInterfaceQName();
0672: QName providesInterfaceQName = provides.getInterfaceQName();
0673: if (!consumesInterfaceQName.equals(providesInterfaceQName)) {
0674: CasaPort casaPort1 = getCasaPort(consumes);
0675: CasaPort casaPort2 = getCasaPort(provides);
0676: boolean isFreeEditablePort1 = casaPort1 != null
0677: && isEditable(casaPort1)
0678: && getConnections(casaPort1, false).size() == 0; // the flag here doesn't matter
0679: boolean isFreeEditablePort2 = casaPort2 != null
0680: && isEditable(casaPort2)
0681: && getConnections(casaPort2, false).size() == 0; // the flag here doesn't matter
0682:
0683: if (isFreeEditablePort2 && direction) {
0684: _setEndpointInterfaceQName(provides, null);
0685: } else {
0686: _setEndpointInterfaceQName(consumes, null);
0687: }
0688: }
0689: }
0690:
0691: CasaConnection connection = getCasaConnection(consumes,
0692: provides);
0693:
0694: if (connection == null) {
0695: // 2.1. Add brand new connection
0696: connection = addNewConnection(consumes, provides);
0697: } else {
0698: // 2.2 Revitalize a deleted connection
0699: String state = connection.getState();
0700: if (!ConnectionState.DELETED.getState().equals(state)) {
0701: throw new RuntimeException(
0702: "Cannot add a connection that is marked as \"new\" or \"unchanged\""); // NOI18N
0703: }
0704: setConnectionState(connection, ConnectionState.UNCHANGED);
0705: }
0706:
0707: return connection;
0708: }
0709:
0710: /**
0711: * Adds a brand new connection between the given two endpoints.
0712: */
0713: private CasaConnection addNewConnection(
0714: final CasaConsumes consumes, final CasaProvides provides) {
0715:
0716: CasaEndpointRef definedEndpointRef = null;
0717: CasaEndpointRef undefinedEndpointRef = null;
0718:
0719: if (isEndpointDefined(consumes)) {
0720: if (!isEndpointDefined(provides)) {
0721: definedEndpointRef = consumes;
0722: undefinedEndpointRef = provides;
0723: }
0724: } else {
0725: if (isEndpointDefined(provides)) {
0726: definedEndpointRef = provides;
0727: undefinedEndpointRef = consumes;
0728: }
0729: }
0730:
0731: if (definedEndpointRef != null && undefinedEndpointRef != null) {
0732: // Populate the interface name of the undefined endpoint
0733: QName interfaceQName = definedEndpointRef
0734: .getInterfaceQName();
0735: _setEndpointInterfaceQName(undefinedEndpointRef,
0736: interfaceQName);
0737: }
0738:
0739: // Create a new casa connection
0740: CasaComponentFactory casaFactory = getFactory();
0741: CasaConnection casaConnection = casaFactory
0742: .createCasaConnection();
0743: casaConnection.setState(ConnectionState.NEW.getState());
0744: casaConnection.setConsumer(casaConnection.createReferenceTo(
0745: consumes.getEndpoint().get(), CasaEndpoint.class));
0746: casaConnection.setProvider(casaConnection.createReferenceTo(
0747: provides.getEndpoint().get(), CasaEndpoint.class));
0748:
0749: CasaConnections casaConnections = getRootComponent()
0750: .getConnections();
0751:
0752: // Add the new casa connection into casa file
0753: startTransaction();
0754: try {
0755: casaConnections.addConnection(-1, casaConnection);
0756: } finally {
0757: if (isIntransaction()) {
0758: fireChangeEvent(casaConnection,
0759: PROPERTY_CONNECTION_ADDED);
0760: endTransaction();
0761: }
0762: }
0763:
0764: return casaConnection;
0765: }
0766:
0767: private static void populateBindingAndPort(final CasaPort casaPort,
0768: final Port port, final QName interfaceQName, String bType) {
0769:
0770: CasaWrapperModel casaWrapperModel = (CasaWrapperModel) casaPort
0771: .getModel();
0772: PortType portType = casaWrapperModel
0773: .getPortType(interfaceQName);
0774: assert portType != null;
0775: String wsdlLocation = casaWrapperModel
0776: .getWSDLLocation(interfaceQName);
0777:
0778: ExtensibilityElementTemplateFactory factory = new ExtensibilityElementTemplateFactory();
0779: Collection<TemplateGroup> groups = factory
0780: .getExtensibilityElementTemplateGroups();
0781: Vector<LocalizedTemplateGroup> protocols = new Vector<LocalizedTemplateGroup>();
0782: LocalizedTemplateGroup ltg = null;
0783: LocalizedTemplateGroup bindingType = null;
0784: for (TemplateGroup group : groups) {
0785: ltg = factory.getLocalizedTemplateGroup(group);
0786: protocols.add(ltg);
0787: // System.out.println(bType+" Add Potocol: "+ltg.getName());
0788: if (ltg.getName().equalsIgnoreCase(bType)) {
0789: bindingType = ltg;
0790: break;
0791: }
0792: }
0793: if (bindingType == null) {
0794: String msg = NbBundle.getMessage(CasaWrapperModel.class,
0795: "MSG_FAIL_TO_POPULATE_BINDING", // NOI18N
0796: bType == null ? "null" : bType.toUpperCase()); // NOI18N
0797: NotifyDescriptor d = new NotifyDescriptor.Message(msg,
0798: NotifyDescriptor.ERROR_MESSAGE);
0799: DialogDisplayer.getDefault().notify(d);
0800: throw new RuntimeException(msg);
0801: }
0802:
0803: Binding binding = port.getBinding().get();
0804: String bindingName = binding.getName();
0805: Service service = (Service) port.getParent();
0806: String serviceName = service.getName();
0807: String servicePortName = port.getName();
0808: LocalizedTemplate bindingSubType = null;
0809: LocalizedTemplate[] templates = bindingType.getTemplate();
0810:
0811: WSDLModel wsdlModel = port.getModel();
0812: Definitions definitions = wsdlModel.getDefinitions();
0813:
0814: boolean foundImport = false;
0815: if (wsdlLocation != null) {
0816: for (Import imprt : definitions.getImports()) {
0817: if (imprt.getNamespace().equals(
0818: interfaceQName.getNamespaceURI())
0819: && imprt.getLocation().equals(wsdlLocation)) {
0820: foundImport = true;
0821: break;
0822: }
0823: }
0824: }
0825: Import newImport = null;
0826: if (wsdlLocation != null && !foundImport) {
0827: newImport = wsdlModel.getFactory().createImport();
0828: newImport.setNamespace(interfaceQName.getNamespaceURI());
0829: newImport.setLocation(wsdlLocation);
0830: }
0831:
0832: Map<String, Object> configurationMap = new HashMap<String, Object>();
0833: configurationMap.put(
0834: WizardBindingConfigurationStep.BINDING_NAME,
0835: bindingName);
0836: configurationMap.put(
0837: WizardBindingConfigurationStep.BINDING_TYPE,
0838: bindingType);
0839: configurationMap.put(
0840: WizardBindingConfigurationStep.SERVICE_NAME,
0841: serviceName);
0842: configurationMap.put(
0843: WizardBindingConfigurationStep.SERVICEPORT_NAME,
0844: servicePortName);
0845:
0846: wsdlModel.startTransaction();
0847: try {
0848: if (newImport != null) {
0849: definitions.addImport(newImport);
0850: }
0851:
0852: String targetNamespace = definitions.getTargetNamespace();
0853:
0854: boolean invalidBinding = true;
0855:
0856: for (int k = 0; (k < templates.length) && invalidBinding; k++) {
0857: bindingSubType = templates[k];
0858: configurationMap.put(
0859: WizardBindingConfigurationStep.BINDING_SUBTYPE,
0860: bindingSubType);
0861:
0862: if (binding != null) {
0863: definitions.removeBinding(binding);
0864: }
0865:
0866: if (port != null) {
0867: for (ExtensibilityElement ex : port
0868: .getExtensibilityElements()) {
0869: port.removeExtensibilityElement(ex);
0870: }
0871: }
0872:
0873: BindingGenerator bGen = new BindingGenerator(wsdlModel,
0874: portType, configurationMap);
0875: bGen.execute();
0876:
0877: binding = bGen.getBinding();
0878:
0879: if (binding != null) {
0880: bindingSubType.getMProvider().postProcess(
0881: targetNamespace, binding);
0882: }
0883:
0884: if (port != null) {
0885: bindingSubType.getMProvider().postProcess(
0886: targetNamespace, port);
0887: }
0888:
0889: List<ValidationInfo> vBindingInfos = bindingSubType
0890: .getMProvider().validate(binding);
0891: invalidBinding = vBindingInfos.size() > 0;
0892: //System.out.println(invalidBinding + " subType: " + // NOI18N
0893: // bindingSubType.getName());
0894: }
0895: // } catch (RuntimeException e) {
0896: // if (wsdlModel.isIntransaction()) {
0897: // wsdlModel.rollbackTransaction();
0898: // }
0899: // throw e;
0900: } finally {
0901: if (wsdlModel.isIntransaction()) {
0902: wsdlModel.endTransaction();
0903: }
0904: }
0905: }
0906:
0907: /**
0908: * Removes a connection or marks it as deleted depending on the current
0909: * state of the connection.
0910: */
0911: // TRANSACTION BOUNDARY
0912: // USE CASE: various delete action
0913: // AFFECT: CASA
0914: public void removeConnection(final CasaConnection connection) {
0915: removeConnection(connection, false);
0916: }
0917:
0918: /**
0919: * Removes a connection or marks it as deleted (depending on the current
0920: * state of the connection AND the overwriting hard delete flag).
0921: *
0922: * @param hardDelete if true, the connection will be deleted; otherwise,
0923: * the connection will be deleted or marked as deleted
0924: * depending on the current state of the connection.
0925: */
0926: // FIXME: do we need the hardDelete flag?
0927: private void removeConnection(final CasaConnection connection,
0928: boolean hardDelete) {
0929: String state = connection.getState();
0930:
0931: if (ConnectionState.DELETED.getState().equals(state)) {
0932: throw new RuntimeException(
0933: "Trying to remove a connection that has already been marked as \"deleted\"");
0934: }
0935:
0936: // 1. Clear user-created WSDL endpoint's Consumes/Provides interface name
0937: // if there is no visible connections left after the connection deletion.
0938: // Existing WSDL endpoints are left alone because there might be "deleted"
0939: // connections hanging around.
0940: CasaEndpointRef casaConsumes = getCasaEndpointRef(connection,
0941: true);
0942:
0943: CasaEndpointRef casaProvides = getCasaEndpointRef(connection,
0944: false);
0945:
0946: for (CasaEndpointRef endpointRef : new CasaEndpointRef[] {
0947: casaConsumes, casaProvides }) {
0948:
0949: CasaPort casaPort = getCasaPort(endpointRef);
0950: if (casaPort != null) {
0951: // if (isDefinedInCompApp(casaPort)) {
0952: // if (getConnections(casaPort, false).size() == 1) { // this is the only visible connection left
0953: // _setEndpointInterfaceQName(endpointRef, null);
0954: // }
0955: // }
0956: } else {
0957: CasaServiceEngineServiceUnit sesu = getCasaEngineServiceUnit(endpointRef);
0958: if (sesu != null && !sesu.isInternal()) { // endpoint belongs to external SESU
0959: if (getConnections(endpointRef, false).size() == 1) { // this is the only visible connection left
0960: _setEndpointInterfaceQName(endpointRef, null);
0961: }
0962: }
0963: }
0964: }
0965:
0966: // 2. Delete connection
0967: if (ConnectionState.NEW.getState().equals(state) || hardDelete) {
0968: // Remove casa connection
0969: CasaConnections casaConnections = (CasaConnections) connection
0970: .getParent();
0971: startTransaction();
0972: try {
0973: casaConnections.removeConnection(connection);
0974: } finally {
0975: if (isIntransaction()) {
0976: fireChangeEvent(connection,
0977: PROPERTY_CONNECTION_REMOVED);
0978: endTransaction();
0979: }
0980: }
0981: } else if (ConnectionState.UNCHANGED.getState().equals(state)) {
0982: setConnectionState(connection, ConnectionState.DELETED);
0983: }
0984: }
0985:
0986: private void setConnectionState(
0987: final CasaConnection casaConnection,
0988: final ConnectionState state) {
0989: String initialState = casaConnection.getState();
0990: startTransaction();
0991: try {
0992: casaConnection.setState(state.getState());
0993: } finally {
0994: if (isIntransaction()) {
0995: if (ConnectionState.UNCHANGED.getState().equals(
0996: initialState)
0997: && ConnectionState.DELETED.equals(state)) { // FIXME
0998: fireChangeEvent(casaConnection,
0999: PROPERTY_CONNECTION_REMOVED);
1000: } else if (ConnectionState.DELETED.getState().equals(
1001: initialState)
1002: && ConnectionState.UNCHANGED.equals(state)) {
1003: fireChangeEvent(casaConnection,
1004: PROPERTY_CONNECTION_ADDED);
1005: } else {
1006: assert false : "Uh? setConnectionState: "
1007: + initialState + "->" + state.getState(); // NOI18N
1008: }
1009: endTransaction();
1010: }
1011: }
1012: }
1013:
1014: // TODO: replace PropertyChangeListener by ChangeListener
1015: private void fireChangeEvent(final CasaComponent component,
1016: String type) {
1017: firePropertyChangeEvent(new PropertyChangeEvent(component,
1018: type, null, null));
1019: }
1020:
1021: /**
1022: * Tests if the two given endpoints can be connected or not.
1023: * Two endpoints can be connected if and only if ALL of the following
1024: * conditions hold true:
1025: * <UL>
1026: * <LI> one endpoint is a Consumes and the other is a Provides;
1027: * <LI> there is no existing visible connection involving the Consumes
1028: * endpoint (there could be existing visible connections involving
1029: * the Provides endpoint though);
1030: * <LI> at least one of the two endpoints has a defined interface;
1031: * <LI> if the two endpoints have incompatible defined interfaces, then
1032: * one and only one endpoint must be a free editable BC port;
1033: * <LI> the two endpoint cannot be both external endpoints;
1034: * <LI> the two endpoints don't belong to the same binding component;
1035: * </UL>
1036: */
1037: public boolean canConnect(final CasaEndpointRef endpointRef1,
1038: final CasaEndpointRef endpointRef2) {
1039: String unConnectableReason = getUnConnectableReason(
1040: endpointRef1, endpointRef2);
1041: return unConnectableReason == null;
1042: }
1043:
1044: /**
1045: * Gets the reason why two given endpoints are not connectable.
1046: *
1047: * @return a description why two endpoints are not connectable; null if
1048: * the two endpoints are connectable.
1049: */
1050: public String getUnConnectableReason(
1051: final CasaEndpointRef endpointRef1,
1052: final CasaEndpointRef endpointRef2) {
1053:
1054: if (endpointRef1 instanceof CasaConsumes
1055: && endpointRef2 instanceof CasaConsumes) {
1056: return NbBundle.getMessage(this .getClass(),
1057: "MSG_CANNOT_CONNECT_TWO_CONSUMES"); // NOI18N
1058: }
1059:
1060: if (endpointRef1 instanceof CasaProvides
1061: && endpointRef2 instanceof CasaProvides) {
1062: return NbBundle.getMessage(this .getClass(),
1063: "MSG_CANNOT_CONNECT_TWO_PROVIDES"); // NOI18N
1064: }
1065:
1066: CasaEndpointRef consumes = (endpointRef1 instanceof CasaConsumes) ? endpointRef1
1067: : endpointRef2;
1068:
1069: if (getConnections(consumes, false).size() > 0) {
1070: return NbBundle
1071: .getMessage(this .getClass(),
1072: "MSG_CANNOT_CONNECT_TWO_PROVIDES_WITH_ONE_CONSUMES"); // NOI18N
1073: }
1074:
1075: CasaPort casaPort1 = getCasaPort(endpointRef1);
1076: CasaPort casaPort2 = getCasaPort(endpointRef2);
1077: if (casaPort1 != null && casaPort2 != null
1078: && casaPort1 == casaPort2) {
1079: return NbBundle.getMessage(this .getClass(),
1080: "MSG_CANNOT_CONNECT_SAME_BC_TO_BC"); // NOI18N
1081: }
1082:
1083: CasaServiceEngineServiceUnit sesu1 = getCasaEngineServiceUnit(endpointRef1);
1084: CasaServiceEngineServiceUnit sesu2 = getCasaEngineServiceUnit(endpointRef2);
1085: if (sesu1 != null && sesu2 != null && !sesu1.isInternal()
1086: && !sesu2.isInternal()) {
1087: return NbBundle.getMessage(this .getClass(),
1088: "MSG_CANNOT_CONNECT_TWO_EXTERNAL_ENDPOINTS"); // NOI18N
1089: }
1090:
1091: // The following two checks are for unavailable backing WSDL.
1092: // For example, a EJB module whose WSDL has not been added into CASA.
1093: boolean endpoint1Defined = isEndpointDefined(endpointRef1);
1094: if (endpoint1Defined
1095: && !isEndpointPortTypeAvailable(endpointRef1)) {
1096: return NbBundle.getMessage(this .getClass(),
1097: "MSG_PORTTYPE_NOT_AVAILABLE", // NOI18N
1098: endpointRef1.getFullyQualifiedEndpointName());
1099: }
1100:
1101: boolean endpoint2Defined = isEndpointDefined(endpointRef2);
1102: if (endpoint2Defined
1103: && !isEndpointPortTypeAvailable(endpointRef2)) {
1104: return NbBundle.getMessage(this .getClass(),
1105: "MSG_PORTTYPE_NOT_AVAILABLE", // NOI18N
1106: endpointRef2.getFullyQualifiedEndpointName());
1107: }
1108:
1109: // The following two checks are for corrupted model (CASA model and
1110: // WSDL model are out of sync.)
1111: if (casaPort1 != null) {
1112: Port port1 = getLinkedWSDLPort(casaPort1);
1113: if (port1 == null) {
1114: return NbBundle
1115: .getMessage(
1116: this .getClass(),
1117: "MSG_CORRUPTED_MODEL_WITH_MISSING_SRC_WSDL_PORT", // NOI18N
1118: casaPort1.getLink().getHref());
1119: }
1120: }
1121:
1122: if (casaPort2 != null) {
1123: Port port2 = getLinkedWSDLPort(casaPort2);
1124: if (port2 == null) {
1125: return NbBundle
1126: .getMessage(
1127: this .getClass(),
1128: "MSG_CORRUPTED_MODEL_WITH_MISSING_DEST_WSDL_PORT", // NOI18N
1129: casaPort2.getLink().getHref());
1130: }
1131: }
1132:
1133: if (endpoint1Defined && endpoint2Defined) {
1134: QName consumesInterfaceQName = endpointRef1
1135: .getInterfaceQName();
1136: QName providesInterfaceQName = endpointRef2
1137: .getInterfaceQName();
1138: if (!consumesInterfaceQName.equals(providesInterfaceQName)) {
1139: boolean isFreeEditablePort1 = casaPort1 != null
1140: && isEditable(casaPort1)
1141: && getConnections(casaPort1, false).size() == 0; // the flag here doesn't matter
1142: boolean isFreeEditablePort2 = casaPort2 != null
1143: && isEditable(casaPort2)
1144: && getConnections(casaPort2, false).size() == 0; // the flag here doesn't matter
1145: // Two incompatible endpoints are connectable if and only if
1146: // at least one is a free editable BC port.
1147: if (!isFreeEditablePort1 && !isFreeEditablePort2) {
1148: return NbBundle
1149: .getMessage(this .getClass(),
1150: "MSG_CANNOT_CONNECT_INCOMPATIBLE_ENDPOINTS"); // NOI18N
1151: }
1152: }
1153: }
1154:
1155: if (!endpoint1Defined && !endpoint2Defined) {
1156: return NbBundle.getMessage(this .getClass(),
1157: "MSG_CANNOT_CONNECT_TWO_UNDEFINED_ENDPOINTS"); // NOI18N
1158: }
1159:
1160: return null;
1161: }
1162:
1163: /**
1164: * Checks whether the given endpoint has a defined interface QName.
1165: * A defined interface QName is a one that is not the dummy placeholder
1166: * interface.
1167: */
1168: // Note that an defined endpoint doesn't necessarily mean that the WSDL
1169: // PortType is available in CASA. The PortType availability checking is
1170: // separated to provide fine-grained error message.
1171: // See isEndpointPortTypeAvailable().
1172: private boolean isEndpointDefined(final CasaEndpointRef endpointRef) {
1173: QName interfaceQName = endpointRef.getInterfaceQName();
1174: String compAppWSDLTns = getCompAppWSDLTargetNamespace();
1175: return interfaceQName.getLocalPart().trim().length() > 0
1176: && !interfaceQName.equals(new QName(compAppWSDLTns,
1177: DUMMY_PORTTYPE_NAME));
1178: }
1179:
1180: /**
1181: * Checks if the WSDL PortType for the given endpoint is availabe in CASA.
1182: * For example, if a new WSDL file is added into CompApp, without a rebuild,
1183: * the PortType is not available for CASA to use.
1184: */
1185: private boolean isEndpointPortTypeAvailable(
1186: final CasaEndpointRef endpointRef) {
1187: QName interfaceQName = endpointRef.getInterfaceQName();
1188: return getPortType(interfaceQName) != null;
1189: }
1190:
1191: /**
1192: * Gets the casa connection between the two given casa endpoints, including
1193: * connection that is marked as deleted.
1194: */
1195: private CasaConnection getCasaConnection(
1196: final CasaConsumes consumes, final CasaProvides provides) {
1197: // Get all the connections, including deleted ones
1198: List<CasaConnection> connectionList = getCasaConnectionList(true);
1199:
1200: CasaEndpoint consumesEndpoint = consumes.getEndpoint().get();
1201: CasaEndpoint providesEndpoint = provides.getEndpoint().get();
1202:
1203: for (CasaConnection connection : connectionList) {
1204: if (connection.getConsumer().get() == consumesEndpoint
1205: && connection.getProvider().get() == providesEndpoint) {
1206: return connection;
1207: }
1208: }
1209:
1210: return null;
1211: }
1212:
1213: // // FIXME: should we get bcs from design time or run time?
1214: // private void buildBindingComponentMaps() {
1215: // bcName2BindingType = new HashMap<String, String>();
1216: // bindingType2BcName = new HashMap<String, String>();
1217: //
1218: // JbiDefaultComponentInfo bcinfo =
1219: // JbiDefaultComponentInfo.getJbiDefaultComponentInfo();
1220: // assert bcinfo != null;
1221: //
1222: // for (JbiBindingInfo bi : bcinfo.getBindingInfoList()) {
1223: // String bcName = bi.getBindingComponentName();
1224: // String bindingType = bi.getBindingType();
1225: // bcName2BindingType.put(bcName, bindingType);
1226: // bindingType2BcName.put(bindingType, bcName);
1227: // }
1228: // }
1229:
1230: // Mapping binding component name to binding type,
1231: // e.x., sun-ftp-binding => ftp. FIXME THIS IS WRONG!
1232: private Map<String, String> bcNameMap;
1233:
1234: // FIXME: should we get bcs from design time or run time?
1235: public Map<String, String> getDefaultBindingComponents() {
1236: if (bcNameMap == null) {
1237: bcNameMap = new HashMap<String, String>();
1238:
1239: JbiDefaultComponentInfo bcinfo = JbiDefaultComponentInfo
1240: .getJbiDefaultComponentInfo();
1241: assert bcinfo != null;
1242:
1243: List<JbiBindingInfo> bcList = bcinfo.getBindingInfoList();
1244: for (JbiBindingInfo bi : bcList) {
1245: bcNameMap.put(bi.getBindingComponentName(), bi
1246: .getBindingType());
1247: }
1248: }
1249: return bcNameMap;
1250: }
1251:
1252: /**
1253: * Gets a list of <code>CasaConnection</code>s in the CASA model.
1254: */
1255: public List<CasaConnection> getCasaConnectionList(
1256: boolean includeDeleted) {
1257: List<CasaConnection> ret = new ArrayList<CasaConnection>();
1258:
1259: CasaConnections connections = getRootComponent()
1260: .getConnections();
1261: for (CasaConnection connection : connections.getConnections()) {
1262: String state = connection.getState();
1263: if (includeDeleted
1264: || !state
1265: .equals(ConnectionState.DELETED.getState())) {
1266: ret.add(connection);
1267: }
1268: }
1269:
1270: return ret;
1271: }
1272:
1273: /**
1274: * Gets a list of WSDL PortTypes in the composite application and its
1275: * JBI modules.
1276: */
1277: public List<PortType> getPortTypes() {
1278: List<PortType> ret = new ArrayList<PortType>();
1279:
1280: CasaPortTypes portTypes = getRootComponent().getPortTypes();
1281: for (CasaLink link : portTypes.getLinks()) {
1282: String href = link.getHref();
1283: try {
1284: PortType pt = getWSDLComponentFromXLinkHref(href,
1285: PortType.class);
1286: ret.add(pt);
1287: } catch (Exception ex) {
1288: System.out.println("Failed to Fetch: " + href);
1289: }
1290: }
1291:
1292: return ret;
1293: }
1294:
1295: /**
1296: * Gets the WSDL PortType of a given CasaPort.
1297: */
1298: public PortType getCasaPortType(final CasaPort casaPort) {
1299: Port port = getLinkedWSDLPort(casaPort);
1300: if (port == null) {
1301: return null;
1302: } else {
1303: return port.getBinding().get().getType().get();
1304: }
1305: }
1306:
1307: public static boolean isDummyPortType(PortType portType) {
1308: return portType.getName().equals(DUMMY_PORTTYPE_NAME);
1309: }
1310:
1311: public PortType getPortType(final QName interfaceQName) {
1312: CasaPortTypes casaPortTypes = getRootComponent().getPortTypes();
1313: for (CasaLink link : casaPortTypes.getLinks()) {
1314: String href = link.getHref();
1315: try {
1316: PortType pt = this .getWSDLComponentFromXLinkHref(href,
1317: PortType.class);
1318: if (interfaceQName.getNamespaceURI().equals(
1319: pt.getModel().getDefinitions()
1320: .getTargetNamespace())
1321: && interfaceQName.getLocalPart().equals(
1322: pt.getName())) {
1323: return pt;
1324: }
1325: } catch (Exception ex) {
1326: System.out.println("Failed to fetch portType: "
1327: + interfaceQName);
1328: }
1329: }
1330: return null;
1331: }
1332:
1333: private String getWSDLLocation(final QName interfaceQName) {
1334: CasaPortTypes casaPortTypes = getRootComponent().getPortTypes();
1335: for (CasaLink link : casaPortTypes.getLinks()) {
1336: String href = link.getHref();
1337: try {
1338: PortType pt = this .getWSDLComponentFromXLinkHref(href,
1339: PortType.class);
1340: if (interfaceQName.getNamespaceURI().equals(
1341: pt.getModel().getDefinitions()
1342: .getTargetNamespace())
1343: && interfaceQName.getLocalPart().equals(
1344: pt.getName())) {
1345: return href.substring(0, href.indexOf("#xpointer")); // NOI18N
1346: }
1347: } catch (Exception ex) {
1348: System.out.println("Failed to fetch WSDL location: "
1349: + href);
1350: }
1351: }
1352: return null;
1353: }
1354:
1355: /**
1356: * Adds an external service engine service unit (from the palette).
1357: */
1358: // TRANSACTION BOUNDARY
1359: // USE CASE: DnD from palette
1360: // AFFECT: CASA
1361: public CasaServiceEngineServiceUnit addServiceEngineServiceUnit(
1362: boolean internal, int x, int y) {
1363: String projName = getUniqueUnknownServiceEngineServiceUnitName();
1364: return _addServiceEngineServiceUnit(projName, "", // component name unknown // NOI18N
1365: null, // use default service unit description
1366: internal, true, // is unknown?
1367: !internal, // is defined? Treat external SU as defined and internal SU as undefined.
1368: x, y);
1369: }
1370:
1371: private String getUniqueUnknownServiceEngineServiceUnitName() {
1372: List<String> existingUnknownNames = new ArrayList<String>();
1373:
1374: for (CasaServiceEngineServiceUnit seSU : getServiceEngineServiceUnits()) {
1375: if (seSU.isUnknown()) {
1376: existingUnknownNames.add(seSU.getUnitName());
1377: }
1378: }
1379:
1380: String unknownSESUNamePrefix = NbBundle.getMessage(this
1381: .getClass(), "TXT_UNKNOWN_EXTERNAL_SESU_PREFIX"); // NOI18N
1382: return getUniqueName(existingUnknownNames,
1383: unknownSESUNamePrefix);
1384:
1385: }
1386:
1387: /**
1388: * Adds an external service engine service unit (from JBI Manager).
1389: */
1390: // TRANSACTION BOUNDARY
1391: // USE CASE: DnD from JBI Manager
1392: // AFFECT: CASA
1393: public CasaServiceEngineServiceUnit addServiceEngineServiceUnit(
1394: String projName, String compName, String description,
1395: boolean internal, boolean unknown, boolean defined, int x,
1396: int y) {
1397: return _addServiceEngineServiceUnit(projName, compName,
1398: description, internal, unknown, defined, x, y);
1399: }
1400:
1401: private CasaServiceEngineServiceUnit _addServiceEngineServiceUnit(
1402: String projName, String compName, String description,
1403: boolean internal, boolean unknown, boolean defined, int x,
1404: int y) {
1405:
1406: CasaComponentFactory factory = getFactory();
1407: CasaServiceEngineServiceUnit seSU = factory
1408: .createCasaEngineServiceUnit();
1409: seSU.setX(x);
1410: seSU.setY(y);
1411: seSU.setInternal(internal);
1412: seSU.setUnknown(unknown);
1413: seSU.setDefined(defined);
1414: seSU.setName(projName);
1415: seSU.setUnitName(projName);
1416: seSU.setDescription(description == null ? NbBundle.getMessage(
1417: this .getClass(), "TXT_SERVICE_UNIT_DESCRIPTION") : // NOI18N
1418: description);
1419: seSU.setComponentName(compName);
1420: seSU.setArtifactsZip(projName + ".jar"); // NOI18N
1421:
1422: CasaServiceUnits sus = getRootComponent().getServiceUnits();
1423: startTransaction();
1424: try {
1425: sus.addServiceEngineServiceUnit(-1, seSU);
1426: } finally {
1427: if (isIntransaction()) {
1428: fireChangeEvent(seSU,
1429: PROPERTY_SERVICE_ENGINE_SERVICE_UNIT_ADDED);
1430: endTransaction();
1431: }
1432: }
1433:
1434: return seSU;
1435: }
1436:
1437: private PortType getDummyPortType(final WSDLModel compAppWSDLModel,
1438: boolean create) {
1439:
1440: Definitions definitions = compAppWSDLModel.getDefinitions();
1441: for (PortType pt : definitions.getPortTypes()) {
1442: if (pt.getName().equals(DUMMY_PORTTYPE_NAME)) {
1443: return pt;
1444: }
1445: }
1446:
1447: PortType pt = null;
1448:
1449: if (create) {
1450: WSDLComponentFactory wsdlFactory = compAppWSDLModel
1451: .getFactory();
1452: pt = wsdlFactory.createPortType();
1453: pt.setName(DUMMY_PORTTYPE_NAME);
1454:
1455: compAppWSDLModel.startTransaction();
1456: try {
1457: definitions.addPortType(pt);
1458: } finally {
1459: if (compAppWSDLModel.isIntransaction()) {
1460: compAppWSDLModel.endTransaction();
1461: }
1462: }
1463: }
1464:
1465: return pt;
1466: }
1467:
1468: /**
1469: * Adds a new WSDL endpoint.
1470: */
1471: // TRANSACTION BOUNDARY
1472: // USE CASE: AddWSDLPortAction on the WSDL Port Region; DnD from Palette
1473: // AFFECT: CASA, COMPAPP.WSDL
1474: public CasaPort addCasaPort(String bindingType,
1475: String componentName, int x, int y) {
1476:
1477: // 1. Update casa wsdl
1478: WSDLModel compAppWSDLModel = getCompAppWSDLModel(true);
1479: WSDLComponentFactory wsdlFactory = compAppWSDLModel
1480: .getFactory();
1481: Definitions definitions = compAppWSDLModel.getDefinitions();
1482:
1483: // 1.0. create dummy porttype (need this to avoid NPE when building compapp)
1484: PortType portType = getDummyPortType(compAppWSDLModel, true);
1485:
1486: // 1.1. create new binding
1487: Binding binding = wsdlFactory.createBinding();
1488: String newBindingName = getUniqueBindingName(compAppWSDLModel);
1489: binding.setName(newBindingName);
1490:
1491: // 1.2. create new port
1492: Port port = wsdlFactory.createPort();
1493: String newPortName = getUniquePortName(compAppWSDLModel);
1494: port.setName(newPortName);
1495:
1496: // 1.3. create new service
1497: int serviceCount = definitions.getServices().size();
1498: Service service = wsdlFactory.createService(); // FIXME: use existing one?
1499: String newServiceName = getUniqueServiceName(compAppWSDLModel);
1500: service.setName(newServiceName);
1501:
1502: compAppWSDLModel.startTransaction();
1503: try {
1504: definitions.addBinding(binding);
1505: binding.setType(binding.createReferenceTo(portType,
1506: PortType.class));
1507: definitions.addService(service);
1508: service.addPort(port);
1509: port.setBinding(port.createReferenceTo(binding,
1510: Binding.class));
1511: } finally {
1512: if (compAppWSDLModel.isIntransaction()) {
1513: compAppWSDLModel.endTransaction();
1514: }
1515: }
1516:
1517: String relativePath = getRelativePathForCompAppWSDL();
1518: String portHref = getPortHref(relativePath, newServiceName,
1519: newPortName);
1520: String portTypeHref = getPortTypeHref(relativePath,
1521: DUMMY_PORTTYPE_NAME);
1522:
1523: String tns = compAppWSDLModel.getDefinitions()
1524: .getTargetNamespace();
1525:
1526: return addCasaPortToModel(componentName, bindingType,
1527: new QName(tns, DUMMY_PORTTYPE_NAME), new QName(tns,
1528: newServiceName), newPortName, portHref,
1529: portTypeHref, x, y);
1530: }
1531:
1532: private String getRelativePathForCompAppWSDL() {
1533: String compAppWSDLFileName = getCompAppWSDLFileName();
1534: return CASA_WSDL_RELATIVE_LOCATION + compAppWSDLFileName;
1535: }
1536:
1537: private String getPortHref(String relativePath, String serviceName,
1538: String portName) {
1539: return relativePath + "#xpointer(/definitions/service[@name='" + // NOI18N
1540: serviceName + "']/port[@name='" + portName + "'])"; // NOI18N
1541: }
1542:
1543: private String getPortTypeHref(String relativePath,
1544: String portTypeName) {
1545: return relativePath + "#xpointer(/definitions/portType[@name='"
1546: + portTypeName + "'])"; // NOI18N
1547: }
1548:
1549: private String getCompAppWSDLFileName() {
1550: Project jbiProject = getJBIProject();
1551: if (jbiProject != null) {
1552: return JbiProjectHelper.getJbiProjectName(jbiProject)
1553: + ".wsdl"; // NOI18N
1554: } else {
1555: return null;
1556: }
1557: }
1558:
1559: /**
1560: * Add a WSDL port from WSDL file into CASA. This is to restore user-deleted
1561: * CASA port from component projects.
1562: *
1563: * @param port selected WSDL port to add
1564: * @param wsdlFile the source WSDL file
1565: * @return the casa port or null if failed to add
1566: */
1567: // TRSACTION ANNOTATION
1568: // USE CASE: LoadWSDLPortsAction from SESU's context menu
1569: // AFFECT: CASA
1570: // TODO: support adding multiple ports
1571: public CasaPort addCasaPortFromWsdlPort(final Port port,
1572: final File wsdlFile) {
1573: try {
1574: JbiBindingInfo bi = JbiDefaultComponentInfo
1575: .getBindingInfo(port);
1576: if (bi == null) {
1577: return null;
1578: }
1579:
1580: String newServiceName = ((Service) (port.getParent()))
1581: .getName();
1582: String newPortName = port.getName();
1583: String fname = wsdlFile.getCanonicalPath();
1584: String relativePath = fname;
1585: if (fname.indexOf(JBI_SERVICE_UNITS_DIR) > 0) { // standard SU wsdl...
1586: relativePath = "../" + // NOI18N
1587: fname.substring(
1588: fname.indexOf(JBI_SERVICE_UNITS_DIR))
1589: .replace('\\', '/'); // NOI18N
1590: } else if (fname.indexOf(JBI_SOURCE_DIR) > 0) { // CompApp wsdl...
1591: relativePath = "../" + // NOI18N
1592: fname.substring(fname.indexOf(JBI_SOURCE_DIR))
1593: .replace('\\', '/'); // NOI18N
1594: }
1595: String portHref = getPortHref(relativePath, newServiceName,
1596: newPortName);
1597:
1598: for (CasaBindingComponentServiceUnit bcSU : getBindingComponentServiceUnits()) {
1599: for (CasaPort casaPort : bcSU.getPorts().getPorts()) {
1600: if (portHref.equals(casaPort.getLink().getHref())) {
1601: assert CasaPortState.DELETED.getState().equals(
1602: casaPort.getState());
1603: setCasaPortState(casaPort, CasaPortState.NORMAL);
1604: return casaPort;
1605: }
1606: }
1607: }
1608:
1609: String tns = port.getModel().getDefinitions()
1610: .getTargetNamespace();
1611: String newInterfaceName = port.getBinding().get().getType()
1612: .get().getName();
1613: String newPortTypeHref = getPortTypeHref(relativePath,
1614: newInterfaceName);
1615:
1616: String bindingType = bi.getBindingType();
1617: String componentName = bi.getBindingComponentName();
1618:
1619: return addCasaPortToModel(componentName, bindingType,
1620: new QName(tns, newInterfaceName), new QName(tns,
1621: newServiceName), newPortName, portHref,
1622: newPortTypeHref, 0, 0);
1623: } catch (Exception ex) {
1624: // add failed...
1625: ex.printStackTrace();
1626: }
1627:
1628: return null;
1629: }
1630:
1631: private CasaPort addCasaPortToModel(String componentName,
1632: String bindingType, QName newInterfaceQName,
1633: QName newServiceQName, String newPortName, String portHref,
1634: String portTypeHref, int x, int y) {
1635:
1636: CasaEndpoints endpoints = getRootComponent().getEndpoints();
1637:
1638: // 1. Create and add a dummy endpoint
1639: CasaComponentFactory casaFactory = getFactory();
1640: CasaEndpoint newEndpoint = casaFactory.createCasaEndpoint();
1641: String newEndpointID = getUniqueEndpointID(this );
1642:
1643: startTransaction();
1644: try {
1645: newEndpoint.setName(newEndpointID);
1646: newEndpoint.setEndpointName(newPortName);
1647: newEndpoint.setInterfaceQName(newInterfaceQName);
1648: newEndpoint.setServiceQName(newServiceQName);
1649:
1650: endpoints.addEndpoint(-1, newEndpoint);
1651: } finally {
1652: if (isIntransaction()) {
1653: endTransaction();
1654: }
1655: }
1656:
1657: // 2. Create new casa port
1658: CasaPort casaPort = casaFactory.createCasaPort();
1659: casaPort.setX(x);
1660: casaPort.setY(y);
1661: // casaPort.setBindingState("unbound");
1662: // casaPort.setPortType("");
1663: casaPort.setBindingType(bindingType);
1664:
1665: // 3. Add casa port link
1666: CasaLink link = casaFactory.createCasaLink();
1667: link.setHref(portHref);
1668: link.setType("simple");
1669: casaPort.setLink(link);
1670:
1671: // 4. Create and add consumes reference
1672: CasaConsumes casaConsumes = casaFactory.createCasaConsumes();
1673: casaConsumes.setEndpoint(casaConsumes.createReferenceTo(
1674: newEndpoint, CasaEndpoint.class));
1675: casaPort.setConsumes(casaConsumes);
1676:
1677: // 5. Create and add provides reference
1678: CasaProvides casaProvides = casaFactory.createCasaProvides();
1679: casaProvides.setEndpoint(casaProvides.createReferenceTo(
1680: newEndpoint, CasaEndpoint.class));
1681: casaPort.setProvides(casaProvides);
1682:
1683: // 6. Create a new portType link, if the exsiting portType list doens't
1684: // contains the new portType.
1685: boolean portTypeExists = false;
1686: CasaPortTypes portTypes = getRootComponent().getPortTypes();
1687: for (CasaLink portTypeLink : portTypes.getLinks()) {
1688: if (portTypeLink.getHref().equals(portTypeHref)) {
1689: portTypeExists = true;
1690: break;
1691: }
1692: }
1693: CasaLink portTypeLink = null;
1694: if (!portTypeExists) {
1695: portTypeLink = casaFactory.createCasaLink();
1696: portTypeLink.setHref(portTypeHref);
1697: portTypeLink.setType("simple"); // NOI18N
1698: }
1699:
1700: startTransaction();
1701: try {
1702: CasaBindingComponentServiceUnit casaBCSU = null;
1703: for (CasaBindingComponentServiceUnit bcSUs : getBindingComponentServiceUnits()) {
1704: if (bcSUs.getComponentName().equals(componentName)) {
1705: casaBCSU = bcSUs;
1706: break;
1707: }
1708: }
1709:
1710: if (casaBCSU == null) {
1711: // create a new casa binding component service unit in *.casa
1712: casaBCSU = casaFactory.createCasaBindingServiceUnit();
1713: casaBCSU.setUnitName(componentName);
1714: casaBCSU.setComponentName(componentName);
1715: casaBCSU.setName(componentName); // FIXME
1716: casaBCSU.setDescription(NbBundle.getMessage(this
1717: .getClass(), "TXT_SERVICE_UNIT_DESCRIPTION")); // NOI18N
1718: casaBCSU.setArtifactsZip(componentName + ".jar"); // NOI18N
1719:
1720: CasaPorts casaPorts = casaFactory.createCasaPorts();
1721: casaBCSU.setPorts(casaPorts);
1722:
1723: CasaServiceUnits casaSUs = getRootComponent()
1724: .getServiceUnits();
1725: casaSUs.addBindingComponentServiceUnit(-1, casaBCSU);
1726: }
1727:
1728: // add the new WSDL endpoint
1729: CasaPorts casaPorts = casaBCSU.getPorts();
1730: casaPorts.addPort(-1, casaPort);
1731:
1732: // add the new portType link, if applicable
1733: if (portTypeLink != null) {
1734: portTypes.addLink(-1, portTypeLink);
1735: }
1736:
1737: // TODO: we are not using Bindings and Services. Those are currently
1738: // not updated.
1739:
1740: } finally {
1741: if (isIntransaction()) {
1742: fireChangeEvent(casaPort, PROPERTY_CASA_PORT_ADDED);
1743: endTransaction();
1744: }
1745: }
1746:
1747: return casaPort;
1748: }
1749:
1750: /**
1751: * Deletes a casa port or marks it as deleted depending on where the casa
1752: * port is defined. All the visible connections connecting the casa port's
1753: * Consumes and Provides endpoint are deleted or marked as deleted as a
1754: * side effect.
1755: *
1756: * If the casa port is defined in compapp, then the corresponding WSDL port
1757: * and binding in casa wsdl are cleaned up.
1758: *
1759: * @param casaPort a casa port
1760: */
1761: // TRANSACTION BOUNDARY
1762: // USE CASE: various delete action
1763: // AFFECT: CASA, COMPAPP.WSDL
1764: public void removeCasaPort(final CasaPort casaPort) {
1765:
1766: String linkHref = casaPort.getLink().getHref();
1767: final Port port = getLinkedWSDLPort(casaPort);
1768:
1769: CasaEndpoint endpoint = casaPort.getConsumes() != null ? casaPort
1770: .getConsumes().getEndpoint().get()
1771: : casaPort.getProvides().getEndpoint().get();
1772:
1773: // 1. Delete connections
1774: CasaConsumes consumes = casaPort.getConsumes();
1775: if (consumes != null) {
1776: for (CasaConnection connection : getConnections(consumes,
1777: false)) { // don't include "deleted" connection
1778: removeConnection(connection, false);
1779: }
1780: }
1781:
1782: CasaProvides provides = casaPort.getProvides();
1783: if (provides != null) {
1784: for (CasaConnection connection : getConnections(provides,
1785: false)) { // don't include "deleted" connection
1786: removeConnection(connection, false);
1787: }
1788: }
1789:
1790: if (!isDefinedInCompApp(casaPort)) {
1791: // 2. Simply mark the casa port as deleted and that's it.
1792: setCasaPortState(casaPort, CasaPortState.DELETED);
1793:
1794: } else {
1795: // 2. Delete the casa port itself or delete the binding component
1796: // service unit if there is no casa port left behind.
1797: CasaPorts casaPorts = (CasaPorts) casaPort.getParent();
1798: startTransaction();
1799: try {
1800: if (casaPorts.getPorts().size() > 1) {
1801: casaPorts.removePort(casaPort);
1802: } else {
1803: CasaBindingComponentServiceUnit bcSU = (CasaBindingComponentServiceUnit) casaPorts
1804: .getParent();
1805: CasaServiceUnits sus = (CasaServiceUnits) bcSU
1806: .getParent();
1807: sus.removeBindingComponentServiceUnit(bcSU);
1808: }
1809: } finally {
1810: if (isIntransaction()) {
1811: fireChangeEvent(casaPort,
1812: PROPERTY_CASA_PORT_REMOVED);
1813: endTransaction();
1814: }
1815: }
1816:
1817: // 3. Delete dangling endpoint
1818: removeDanglingEndpoint(endpoint);
1819:
1820: // The port should not be null under normal circumstance.
1821: // Just in case the CASA model and WSDL model are out of sync
1822: // (#120268), the user should be able to delete the CASA port
1823: // without seeing any more exception.
1824: if (port != null) {
1825: // 4. Clean up casa wsdl
1826: // Added invokeLater to fix a IllegalStateException from WSDL UI
1827: // temporarily.
1828: // To reproduce the problem:
1829: // (1) Use SynchSample
1830: // (2) Open CASA editor
1831: // (3) Open casa wsdl (this is the key step)
1832: // (4) Drop a WSDL port into CASA
1833: // (5) Make a connection from the WSDL port to BPEL SU's endpoint
1834: // (6) Delete the dropped WSDL port
1835: // => IllegalStateException: Referencing component not part of model
1836: //
1837: // If we delete the new connection first then delete the WSDL port,
1838: // then everything is OK.
1839: SwingUtilities.invokeLater(new Runnable() {
1840:
1841: public void run() {
1842: Binding binding = port.getBinding().get();
1843: Service service = (Service) port.getParent();
1844: Definitions definitions = (Definitions) service
1845: .getParent();
1846:
1847: WSDLModel compAppWSDLModel = port.getModel();
1848: compAppWSDLModel.startTransaction();
1849: try {
1850: // Added null-checking to avoid exception when dealing
1851: // with corrupted WSDL model (for example, a port w/o
1852: // binding).
1853: if (service != null) {
1854: if (port != null) {
1855: service.removePort(port);
1856: }
1857: definitions.removeService(service);
1858: }
1859: if (binding != null) {
1860: definitions.removeBinding(binding);
1861: }
1862: } finally {
1863: if (compAppWSDLModel.isIntransaction()) {
1864: compAppWSDLModel.endTransaction();
1865: }
1866: }
1867:
1868: // checkAndCleanUpDummyPortType(compAppWSDLModel);
1869: }
1870: });
1871: }
1872:
1873: // 5. Clear the cached WSDL component reference.
1874: cachedWSDLComponents.remove(linkHref);
1875: }
1876: }
1877:
1878: /**
1879: * Clean up the dummy portType if it is no longer used in casa wsdl.
1880: */
1881: /*
1882: private void checkAndCleanUpDummyPortType(WSDLModel compAppWSDLModel) {
1883: PortType dummyPortType = getDummyPortType(compAppWSDLModel, false);
1884:
1885: if (dummyPortType != null) {
1886: boolean dummyPortTypeUsed = false;
1887:
1888: Definitions definitions = compAppWSDLModel.getDefinitions();
1889: for (Binding b : definitions.getBindings()) {
1890: if (b.getType().get() == dummyPortType) {
1891: dummyPortTypeUsed = true;
1892: break;
1893: }
1894: }
1895:
1896: if (!dummyPortTypeUsed) {
1897: compAppWSDLModel.startTransaction();
1898: try {
1899: definitions.removePortType(dummyPortType);
1900: } finally {
1901: if (compAppWSDLModel.isIntransaction()) {
1902: compAppWSDLModel.endTransaction();
1903: }
1904: }
1905: }
1906: }
1907: } */
1908:
1909: private void setCasaPortState(final CasaPort casaPort,
1910: final CasaPortState state) {
1911: String initialState = casaPort.getState();
1912: startTransaction();
1913: try {
1914: casaPort.setState(state.getState());
1915: } finally {
1916: if (isIntransaction()) {
1917: if (//CasaPortState.UNCHANGED.getState().equals(initialState) &&
1918: CasaPortState.DELETED.equals(state)) { // FIXME
1919: fireChangeEvent(casaPort,
1920: PROPERTY_CASA_PORT_REMOVED);
1921: } else if (CasaPortState.DELETED.getState().equals(
1922: initialState) //&&
1923: //ConnectionState.UNCHANGED.equals(state)
1924: ) {
1925: fireChangeEvent(casaPort, PROPERTY_CASA_PORT_ADDED);
1926: } else {
1927: assert false : "Uh? setCasaPortState: "
1928: + initialState + "->" + state.getState(); // NOI18N
1929: }
1930: endTransaction();
1931: }
1932: }
1933: }
1934:
1935: /**
1936: * Removes a external Consumes/Provides endpoint from an external
1937: * service engine service unit. All the visible connections connecting
1938: * the endpoint are deleted as well.
1939: *
1940: * @param endpoint an external CasaConsumes or CasaProvides endpoint
1941: */
1942: // TRANSACTION BOUNDARY
1943: // USE CASE: various delete action inside an external SE SU
1944: // AFFECT: CASA
1945: public void removeExternalEndpoint(final CasaEndpointRef endpointRef) {
1946:
1947: // 1. Delete any visible connections
1948: List<CasaConnection> visibleConnections = getConnections(
1949: endpointRef, false);
1950: for (CasaConnection visibleConnection : visibleConnections) {
1951: removeConnection(visibleConnection, false);
1952: }
1953:
1954: CasaEndpoint endpoint = endpointRef.getEndpoint().get();
1955:
1956: // 2. Delete the endpoint reference itself
1957: CasaServiceEngineServiceUnit seSU = (CasaServiceEngineServiceUnit) endpointRef
1958: .getParent();
1959: startTransaction();
1960: try {
1961: if (endpointRef instanceof CasaConsumes) {
1962: seSU.removeConsumes((CasaConsumes) endpointRef);
1963: } else {
1964: seSU.removeProvides((CasaProvides) endpointRef);
1965: }
1966: } finally {
1967: if (isIntransaction()) {
1968: fireChangeEvent(endpointRef, PROPERTY_ENDPOINT_REMOVED);
1969: endTransaction();
1970: }
1971: }
1972:
1973: CasaEndpoints endpoints = getRootComponent().getEndpoints();
1974: startTransaction();
1975: try {
1976: endpoints.removeEndpoint(endpoint);
1977: } finally {
1978: if (isIntransaction()) {
1979: endTransaction();
1980: }
1981: }
1982:
1983: /*
1984: // Delete dangling endpoint
1985: boolean endpointRemoved = removeDanglingEndpoint(endpoint);
1986:
1987: // Delete the corresponding Port, Binding and possibly Service element
1988: // from casa wsdl if applicable.
1989: if (endpointRemoved && casaPort != null && isDefinedInCompApp(casaPort)) {
1990: Port port = getLinkedWSDLPort(casaPort);
1991:
1992: WSDLModel compAppWSDLModel = port.getModel();
1993: if (compAppWSDLModel != null) {
1994: // FIXME: when deleting a user-defined casaport, we delete
1995: // the consumes and provides endpoint, both of which try to
1996: // delete the same port/binding/service now! Maybe we should
1997: // hold on deleting port/... until there is really no reference
1998: // left?
1999: Definitions definitions = compAppWSDLModel.getDefinitions();
2000: Binding binding = port.getBinding().get();
2001: Service service = (Service) port.getParent();
2002:
2003: compAppWSDLModel.startTransaction();
2004: try {
2005: definitions.removeBinding(binding);
2006: if (service.getPorts().size() == 1) {
2007: definitions.removeService(service);
2008: } else {
2009: service.removePort(port);
2010: }
2011: } finally {
2012: if (compAppWSDLModel.isIntransaction()) {
2013: compAppWSDLModel.endTransaction();
2014: }
2015: }
2016: }
2017: }
2018: */
2019: }
2020:
2021: /**
2022: * Removes a casa endpoint if it is not referenced anywhere, that it, it is
2023: * not reference by any service engine service unit, binding component
2024: * service unit, or invisible connections.
2025: */
2026: private boolean removeDanglingEndpoint(final CasaEndpoint endpoint) {
2027: // For invisible connections, we still need to keep the endpoints around.
2028:
2029: for (CasaServiceEngineServiceUnit seSU : getServiceEngineServiceUnits()) {
2030: for (CasaEndpointRef endpointRef : seSU.getEndpoints()) {
2031: if (endpointRef.getEndpoint().get() == endpoint) {
2032: return false;
2033: }
2034: }
2035: }
2036:
2037: for (CasaBindingComponentServiceUnit bcSU : getBindingComponentServiceUnits()) {
2038: for (CasaPort port : bcSU.getPorts().getPorts()) {
2039: CasaEndpointRef consumes = port.getConsumes();
2040: if (consumes != null) {
2041: if (consumes.getEndpoint().get() == endpoint) {
2042: return false;
2043: }
2044: }
2045: // The following is not really necessary now that casaport
2046: // always contains a Consumes and a Provides endpoint.
2047: CasaEndpointRef provides = port.getProvides();
2048: if (provides != null) {
2049: if (provides.getEndpoint().get() == endpoint) {
2050: return false;
2051: }
2052: }
2053: }
2054: }
2055:
2056: // Actually, we only care about connections that are marked as "deleted"
2057: for (CasaConnection connection : getCasaConnectionList(true)) { // include deleted
2058: if (connection.getConsumer().get() == endpoint
2059: || connection.getProvider().get() == endpoint) {
2060: return false;
2061: }
2062: }
2063:
2064: // The endpoint is not referenced by anyone. We can safely delete it now.
2065: CasaEndpoints endpoints = getRootComponent().getEndpoints();
2066: startTransaction();
2067: try {
2068: endpoints.removeEndpoint(endpoint);
2069: } finally {
2070: if (isIntransaction()) {
2071: endTransaction();
2072: }
2073: }
2074:
2075: return true;
2076: }
2077:
2078: /**
2079: * Gets the containing casa port for an endpoint.
2080: *
2081: * @param endpoint a casa endpoint reference
2082: * @return the containing casa port, or <code>null</code> if the given
2083: * endpoint belongs to a service engine service unit.
2084: */
2085: public CasaPort getCasaPort(final CasaEndpointRef endpointRef) {
2086: CasaComponent comp = endpointRef.getParent();
2087: if (comp instanceof CasaPort) {
2088: return (CasaPort) comp;
2089: } else {
2090: return null;
2091: }
2092: }
2093:
2094: /**
2095: * Gets the containing service engine service unit for an endpoint.
2096: *
2097: * @param endpoint a casa endpoint reference
2098: * @return the containing service engine service unit, or <code>null</null>
2099: * if the given endpoint belongs to a casa port.
2100: */
2101: public CasaServiceEngineServiceUnit getCasaEngineServiceUnit(
2102: final CasaEndpointRef endpointRef) {
2103: CasaComponent comp = endpointRef.getParent();
2104: if (comp instanceof CasaServiceEngineServiceUnit) {
2105: return (CasaServiceEngineServiceUnit) comp;
2106: } else {
2107: return null;
2108: }
2109: }
2110:
2111: // public CasaServiceEngineServiceUnit getCasaEngineServiceUnit(
2112: // final CasaEndpoint endpoint) {
2113: // for (CasaServiceEngineServiceUnit sesu : getServiceEngineServiceUnits()) {
2114: // for (CasaEndpointRef endpointRef : sesu.getEndpoints()) {
2115: // if (endpointRef.getEndpoint().get() == endpoint) {
2116: // return getCasaEngineServiceUnit(endpointRef);
2117: // }
2118: // }
2119: // }
2120: //
2121: // return null;
2122: // }
2123:
2124: private boolean isBindingComponentEndpoint(
2125: final CasaEndpointRef endpointRef) {
2126: return getCasaPort(endpointRef) != null;
2127: }
2128:
2129: /**
2130: * Saves all the related models.
2131: * This should be called when the CasaWrapperModel is saved.
2132: */
2133: public void saveDocument() {
2134:
2135: saveRelatedDataObjects();
2136:
2137: addPendingProjects();
2138:
2139: deletePendingProjects();
2140: }
2141:
2142: /**
2143: * Saves all the related models.
2144: */
2145: private void saveRelatedDataObjects() {
2146:
2147: List<DataObject> dataObjects = getRelatedDataObjects();
2148:
2149: for (DataObject dataObject : dataObjects) {
2150: SaveCookie saveCookie = dataObject
2151: .getCookie(SaveCookie.class);
2152: if (saveCookie != null) {
2153: try {
2154: saveCookie.save();
2155: } catch (IOException ex) {
2156: ex.printStackTrace();
2157: }
2158: }
2159: }
2160: }
2161:
2162: /**
2163: * Discards changes to all the related models.
2164: * This should be called when the CasaWrapperModel's changes are discarded.
2165: */
2166: public void discardRelatedDataObjects() {
2167:
2168: List<DataObject> dataObjects = getRelatedDataObjects();
2169:
2170: for (DataObject dataObject : dataObjects) {
2171: dataObject.setModified(false);
2172: try {
2173: dataObject.setValid(false);
2174: } catch (PropertyVetoException ex) {
2175: ex.printStackTrace();
2176: }
2177: }
2178: }
2179:
2180: /**
2181: * Gets a list of related data objects.
2182: */
2183: private List<DataObject> getRelatedDataObjects() {
2184:
2185: List<DataObject> ret = new ArrayList<DataObject>();
2186:
2187: // Get casa wsdl
2188: WSDLModel compAppWSDLModel = getCompAppWSDLModel(false);
2189: if (compAppWSDLModel != null) {
2190: DataObject dataObject = getDataObject(compAppWSDLModel);
2191: if (dataObject != null) {
2192: ret.add(dataObject);
2193: }
2194: }
2195:
2196: return ret;
2197: }
2198:
2199: private static DataObject getDataObject(final Model model) {
2200: Lookup lookup = model.getModelSource().getLookup();
2201: FileObject fileObject = lookup.lookup(FileObject.class);
2202: try {
2203: DataObject dataObject = DataObject.find(fileObject);
2204: return dataObject;
2205: } catch (DataObjectNotFoundException ex) {
2206: ex.printStackTrace();
2207: } catch (IOException ex) {
2208: ex.printStackTrace();
2209: }
2210:
2211: return null;
2212: }
2213:
2214: /**
2215: * Adds a new external endpoint to an external service engine service unit.
2216: */
2217: // TRANSACTION BOUNDARY
2218: // USE CASE: Add[Consumes|Provides]PinAction on external SESU; DnD from palette
2219: // AFFECT: CASA
2220: public CasaEndpointRef addExternalEndpoint(
2221: final CasaServiceEngineServiceUnit seSU, boolean isConsumes) {
2222: return _addExternalEndpoint(seSU, isConsumes);
2223: }
2224:
2225: /**
2226: * Adds a new external endpoint to an external service engine service unit.
2227: */
2228: private CasaEndpointRef _addExternalEndpoint(
2229: final CasaServiceEngineServiceUnit seSU, boolean isConsumes) {
2230:
2231: assert !seSU.isInternal();
2232:
2233: CasaComponentFactory casaFactory = getFactory();
2234:
2235: String endpointID = getUniqueEndpointID(this );
2236: String endpointName = getUniqueExternalEndpointName(this );
2237:
2238: // Create casa endpoint
2239: CasaEndpoint endpoint = casaFactory.createCasaEndpoint();
2240: endpoint.setName(endpointID);
2241: endpoint.setEndpointName(endpointName);
2242:
2243: // Create casa endpoint reference
2244: CasaEndpointRef endpointRef = isConsumes ? casaFactory
2245: .createCasaConsumes() : casaFactory
2246: .createCasaProvides();
2247:
2248: CasaEndpoints endpoints = getRootComponent().getEndpoints();
2249:
2250: startTransaction();
2251: try {
2252: endpoint.setInterfaceQName(new QName("")); // NOI18N
2253: endpoint.setServiceQName(new QName("")); // NOI18N
2254: endpoints.addEndpoint(-1, endpoint);
2255:
2256: endpointRef.setEndpoint(endpointRef.createReferenceTo(
2257: endpoint, CasaEndpoint.class));
2258:
2259: if (isConsumes) {
2260: seSU.addConsumes(-1, (CasaConsumes) endpointRef);
2261: } else {
2262: seSU.addProvides(-1, (CasaProvides) endpointRef);
2263: }
2264: } finally {
2265: if (isIntransaction()) {
2266: fireChangeEvent(endpointRef, PROPERTY_ENDPOINT_ADDED);
2267: endTransaction();
2268: }
2269: }
2270:
2271: return endpointRef;
2272: }
2273:
2274: /**
2275: * Adds a list of external endpoints (from JBI Manager DnD transfer) to an
2276: * external service engine service unit.
2277: */
2278: // TRANSACTION BOUNDARY
2279: // USE CASE: DnD from JBIManager
2280: // AFFECT: CASA
2281: // TODO: fix TransferObject
2282: public void addExternalEndpoints(
2283: final JBIServiceUnitTransferObject suTransfer,
2284: final CasaServiceEngineServiceUnit seSU) {
2285:
2286: Model model = seSU.getModel();
2287: List<JBIServiceUnitTransferObject.Endpoint> pList = suTransfer
2288: .getProvidesEndpoints();
2289: for (JBIServiceUnitTransferObject.Endpoint p : pList) {
2290: CasaEndpointRef endpointRef = _addExternalEndpoint(seSU,
2291: false);
2292: CasaEndpoint endpoint = endpointRef.getEndpoint().get();
2293:
2294: model.startTransaction();
2295: try {
2296: endpoint.setInterfaceQName(p.getInterfaceQName());
2297: endpoint.setServiceQName(p.getServiceQName());
2298: endpoint.setEndpointName(p.getEndpointName());
2299: } finally {
2300: if (model.isIntransaction()) {
2301: model.endTransaction();
2302: }
2303: }
2304: }
2305: List<JBIServiceUnitTransferObject.Endpoint> cList = suTransfer
2306: .getConsumesEndpoints();
2307: for (JBIServiceUnitTransferObject.Endpoint c : cList) {
2308: CasaEndpointRef endpointRef = _addExternalEndpoint(seSU,
2309: true);
2310: CasaEndpoint endpoint = endpointRef.getEndpoint().get();
2311:
2312: model.startTransaction();
2313: try {
2314: endpoint.setInterfaceQName(c.getInterfaceQName());
2315: endpoint.setServiceQName(c.getServiceQName());
2316: endpoint.setEndpointName(c.getEndpointName());
2317: } finally {
2318: if (model.isIntransaction()) {
2319: model.endTransaction();
2320: }
2321: }
2322: }
2323: }
2324:
2325: /**
2326: * Adds all the pending JBI module projects from queue to the CompApp project.
2327: */
2328: private void addPendingProjects() {
2329: try {
2330: Project jbiProject = getJBIProject();
2331:
2332: AddProjectAction addProjectAction = new AddProjectAction();
2333:
2334: for (String key : new HashSet<String>(mAddProjects.keySet())) {
2335: Project project = mAddProjects.get(key);
2336: AntArtifactProvider antArtifactProvider = project
2337: .getLookup().lookup(AntArtifactProvider.class);
2338: assert antArtifactProvider != null;
2339:
2340: AntArtifact[] artifacts = antArtifactProvider
2341: .getBuildArtifacts();
2342: boolean success = addProjectAction.addProject(
2343: jbiProject, artifacts[0]);
2344: if (success) {
2345: mAddProjects.remove(key);
2346: }
2347: }
2348: } catch (Exception ex) {
2349: ex.printStackTrace();
2350: }
2351: }
2352:
2353: /**
2354: * Deletes all the pending JBI module projects from queue to the CompApp project.
2355: */
2356: private void deletePendingProjects() {
2357: try {
2358: Project jbiProject = getJBIProject();
2359:
2360: DeleteModuleAction deleteModuleAction = SystemAction
2361: .get(DeleteModuleAction.class);
2362:
2363: for (String key : new HashSet<String>(mDeleteProjects
2364: .keySet())) {
2365: String artifactName = mDeleteProjects.get(key);
2366: boolean success = deleteModuleAction.removeProject(
2367: jbiProject, artifactName);
2368: if (success) {
2369: mDeleteProjects.remove(key);
2370: }
2371: }
2372: } catch (Exception ex) {
2373: ex.printStackTrace();
2374: }
2375: }
2376:
2377: /**
2378: * Adds a component project into compapp project (from project explorer).
2379: *
2380: * @param project a component project
2381: * @param x x location of the new service unit in the editor
2382: * @param y y location of the new service unit in the editor
2383: */
2384: // TRANSACTION BOUNDARY
2385: // USE CASE: DnD from Project Explorer
2386: // AFFECT: CASA
2387: public void addJBIModule(final Project project, String type, int x,
2388: int y) {
2389: String projectName = ProjectUtils.getInformation(project)
2390: .getDisplayName();
2391:
2392: if (mDeleteProjects.containsKey(projectName)) {
2393: mDeleteProjects.remove(projectName);
2394: } else {
2395: mAddProjects.put(projectName, project); // todo: needs to fix duplicate proj names..
2396: }
2397:
2398: _addServiceEngineServiceUnit(projectName, type, null, // use default description
2399: true, // is internal SESU?
2400: false, // is known?
2401: false, // is defined?
2402: x, y);
2403: }
2404:
2405: /**
2406: * Adds a component project into compapp project (created from the project plugin).
2407: *
2408: * @param plugin a plugin project
2409: * @param name a plugin project name
2410: * @param type a plugin project type
2411: * @param x x location of the new service unit in the editor
2412: * @param y y location of the new service unit in the editor
2413: */
2414: // TRANSACTION BOUNDARY
2415: // USE CASE: DnD from Project Explorer
2416: // AFFECT: CASA
2417: public void addJBIModuleFromPlugin(
2418: final InternalProjectTypePlugin plugin, String name,
2419: String type, int x, int y) {
2420:
2421: final String projectName = name;
2422: final String projectType = type;
2423: final int projectX = x;
2424: final int projectY = y;
2425:
2426: RequestProcessor.getDefault().post(new Runnable() {
2427:
2428: public void run() {
2429: ProgressHandle handle = ProgressHandleFactory
2430: .createHandle(NbBundle.getMessage(
2431: CasaWrapperModel.class,
2432: "MSG_ADDPROJECT_CREATE")); // NOI18N
2433: try {
2434: handle.start(100);
2435:
2436: InternalProjectTypePluginWizardIterator wizardIterator = plugin
2437: .getWizardIterator();
2438: WizardDescriptor descriptor = new WizardDescriptor(
2439: wizardIterator);
2440: Project project = null;
2441:
2442: // Set up project name and location
2443: File projectsRoot = FileUtil.toFile(getJBIProject()
2444: .getProjectDirectory());
2445: File jbiprojsRoot = new File(projectsRoot,
2446: JbiProjectConstants.FOLDER_JBIPROJECTS);
2447: if (!jbiprojsRoot.exists()) {
2448: jbiprojsRoot.mkdirs();
2449: }
2450: File projectFolder = new File(jbiprojsRoot,
2451: projectName);
2452: descriptor.putProperty(
2453: WizardPropertiesTemp.PROJECT_DIR,
2454: projectFolder);
2455: descriptor.putProperty(WizardPropertiesTemp.NAME,
2456: projectName);
2457: descriptor.putProperty(
2458: WizardPropertiesTemp.J2EE_LEVEL, "1.4");
2459: descriptor.putProperty(
2460: WizardPropertiesTemp.SET_AS_MAIN,
2461: new Boolean(false));
2462:
2463: handle.progress(NbBundle.getMessage(
2464: CasaWrapperModel.class,
2465: "MSG_ADDPROJECT_INVOKE"), 20); // NOI18N
2466: if (wizardIterator.hasContent()) {
2467: descriptor.setModal(true);
2468: Dialog dialog = DialogDisplayer.getDefault()
2469: .createDialog(descriptor);
2470: dialog.setVisible(true);
2471: } else {
2472: wizardIterator.instantiate();
2473: }
2474:
2475: handle.progress(NbBundle.getMessage(
2476: CasaWrapperModel.class,
2477: "MSG_ADDPROJECT_SETUP"), 50); // NOI18N
2478: project = wizardIterator.getProject();
2479: if (project != null) {
2480: addJBIModule(project, projectType, projectX,
2481: projectY);
2482: copyPrivateProperties(projectsRoot,
2483: projectFolder);
2484: }
2485:
2486: if (mDeleteProjects.containsKey(projectName)) {
2487: mDeleteProjects.remove(projectName);
2488: } else {
2489: mAddProjects.put(projectName, project); // todo: needs to fix duplicate proj names..
2490: }
2491: handle.progress(80);
2492: } catch (Exception e) { // create plug-in project failed...
2493: ErrorManager.getDefault().notify(e);
2494: }
2495: handle.finish();
2496: }
2497: });
2498:
2499: }
2500:
2501: private void copyPrivateProperties(File root, File proj) {
2502: String privateLoc = "nbproject/private/private.properties"; // NOI18N
2503: String lbl_installDir = "module.install.dir"; // NOI18N
2504: String lbl_userDir = "netbeans.user"; // NOI18N
2505: File privateRoot = new File(root, privateLoc);
2506: File privateProj = new File(proj, privateLoc);
2507: Properties propRoot = new Properties();
2508: Properties propProj = new Properties();
2509: try {
2510: FileInputStream fisRoot = new FileInputStream(privateRoot);
2511: FileInputStream fisProj = new FileInputStream(privateProj);
2512: propRoot.load(fisRoot);
2513: propProj.load(fisProj);
2514: fisRoot.close();
2515: fisProj.close();
2516: String val_installDir = propRoot
2517: .getProperty(lbl_installDir);
2518: String val_userDir = propRoot.getProperty(lbl_userDir);
2519: propProj.setProperty(lbl_installDir, val_installDir);
2520: propProj.setProperty(lbl_userDir, val_userDir);
2521: //System.out.println("Copying val_installDir: " +val_installDir);
2522: //System.out.println("Copying val_userDir: " +val_userDir);
2523: FileOutputStream fosProj = new FileOutputStream(privateProj);
2524: propProj.store(fosProj, null);
2525: fosProj.close();
2526: } catch (IOException e) { // copy failed...
2527: ErrorManager.getDefault().notify(e);
2528: }
2529: }
2530:
2531: /**
2532: * Deletes an internal or external service engine service unit.
2533: * All the connections connecting the service unit, and possibly
2534: * WSDL endpoints (defined in component projects), will be deleted as well.
2535: *
2536: * @param seSU an existing service engine service unit
2537: */
2538: // TRANSACTION BOUNDARY
2539: // USE CASE: various delete action on internal/external SE SU
2540: // AFFECT: CASA
2541: public void removeServiceEngineServiceUnit(
2542: final CasaServiceEngineServiceUnit seSU) {
2543:
2544: if (seSU.isInternal() && !seSU.isUnknown()) {
2545: String projectName = seSU.getUnitName();
2546: if (mAddProjects.containsKey(projectName)) {
2547: mAddProjects.remove(projectName);
2548: } else {
2549: mDeleteProjects
2550: .put(projectName, seSU.getArtifactsZip());
2551: }
2552: }
2553:
2554: Set<CasaPort> connectingCasaPorts = new HashSet<CasaPort>();
2555:
2556: // 1. Delete connections
2557: for (CasaEndpointRef endpointRef : seSU.getEndpoints()) {
2558:
2559: List<CasaConnection> visibleConnections = getConnections(
2560: endpointRef, false); // don't include "deleted" connection
2561: for (CasaConnection visibleConnection : visibleConnections) {
2562:
2563: // find connecting casa ports
2564: CasaEndpointRef casaConsumes = getCasaEndpointRef(
2565: visibleConnection.getConsumer().get(), true);
2566: CasaPort casaPort = getCasaPort(casaConsumes);
2567: if (casaPort != null) {
2568: connectingCasaPorts.add(casaPort);
2569: }
2570:
2571: CasaEndpointRef casaProvides = getCasaEndpointRef(
2572: visibleConnection.getProvider().get(), false);
2573: casaPort = getCasaPort(casaProvides);
2574: if (casaPort != null) {
2575: connectingCasaPorts.add(casaPort);
2576: }
2577:
2578: removeConnection(visibleConnection, true); // hard delete connections?
2579: }
2580: }
2581:
2582: // 2. Delete WSDL endpoints
2583: for (CasaPort casaPort : connectingCasaPorts) {
2584: // Here we only want to delete those casa ports that come from the
2585: // component projects.
2586: if (!isDefinedInCompApp(casaPort)) {
2587: // Delete the casa port if there is no (even deleted) connections
2588: // connecting it any more.
2589: if (getConnections(casaPort, true).size() == 0) { // casaport not connected
2590: removeCasaPort(casaPort);
2591: }
2592: }
2593: }
2594:
2595: // 3. Remember the endpoints inside the service unit. We might have some
2596: // cleanup work to do.
2597: List<CasaEndpointRef> endpointRefs = seSU.getEndpoints();
2598: List<CasaEndpoint> endpoints = new ArrayList<CasaEndpoint>();
2599: for (CasaEndpointRef endpointRef : endpointRefs) {
2600: endpoints.add(endpointRef.getEndpoint().get());
2601: }
2602:
2603: // 4. Delete the casa service unit
2604: CasaServiceUnits casaSUs = getRootComponent().getServiceUnits();
2605: startTransaction();
2606: try {
2607: casaSUs.removeServiceEngineServiceUnit(seSU);
2608: } finally {
2609: if (isIntransaction()) {
2610: fireChangeEvent(seSU,
2611: PROPERTY_SERVICE_ENGINE_SERVICE_UNIT_REMOVED);
2612: endTransaction();
2613: }
2614: }
2615:
2616: // 5. Clean up dangling endpoints
2617: for (CasaEndpoint endpoint : endpoints) {
2618: removeDanglingEndpoint(endpoint);
2619: }
2620: }
2621:
2622: /**
2623: * Gets the owning compapp project.
2624: */
2625: public Project getJBIProject() {
2626: try {
2627: Lookup lookup = getModelSource().getLookup();
2628: FileObject casaFO = lookup.lookup(FileObject.class);
2629: FileObject projectFO = casaFO.getParent().getParent()
2630: .getParent();
2631: return ProjectManager.getDefault().findProject(projectFO);
2632: } catch (IOException e) {
2633: ErrorManager.getDefault().notify(e);
2634: }
2635: return null;
2636: }
2637:
2638: /**
2639: * Gets a (non-null) list of casa connections connecting the given endpoint.
2640: *
2641: * @param endpointRef an endpoint reference
2642: * @param includeDeleted whether to include connections that are marked as deleted
2643: */
2644: private List<CasaConnection> getConnections(
2645: final CasaEndpointRef endpointRef, boolean includeDeleted) {
2646: List<CasaConnection> ret = new ArrayList<CasaConnection>();
2647:
2648: CasaEndpoint endpoint = endpointRef.getEndpoint().get();
2649: for (CasaConnection connection : getCasaConnectionList(includeDeleted)) {
2650: if ((endpointRef instanceof CasaConsumes && connection
2651: .getConsumer().get() == endpoint)
2652: || (endpointRef instanceof CasaProvides && connection
2653: .getProvider().get() == endpoint)) {
2654: ret.add(connection);
2655: }
2656: }
2657:
2658: return ret;
2659: }
2660:
2661: private static String getUniqueEndpointID(
2662: final CasaWrapperModel model) {
2663: List<String> existingNames = new ArrayList<String>();
2664:
2665: for (CasaEndpoint casaEndpoint : model.getRootComponent()
2666: .getEndpoints().getEndpoints()) {
2667: String name = casaEndpoint.getName();
2668: existingNames.add(name);
2669: }
2670:
2671: return getUniqueName(existingNames, "endpoint"); // NOI18N
2672: }
2673:
2674: private static String getUniqueExternalEndpointName(
2675: final CasaWrapperModel model) {
2676: List<String> existingNames = new ArrayList<String>();
2677:
2678: for (CasaEndpoint casaEndpoint : model.getRootComponent()
2679: .getEndpoints().getEndpoints()) {
2680: String name = casaEndpoint.getEndpointName();
2681: existingNames.add(name);
2682: }
2683:
2684: return getUniqueName(existingNames, "extEndpoint"); // NOI18N
2685: }
2686:
2687: private static String getUniquePortTypeName(
2688: final WSDLModel wsdlModel) {
2689: List<String> existingNames = new ArrayList<String>();
2690:
2691: for (PortType portType : wsdlModel.getDefinitions()
2692: .getPortTypes()) {
2693: String name = portType.getName();
2694: existingNames.add(name);
2695: }
2696:
2697: return getUniqueName(existingNames, "casaPortType"); // NOI18N
2698: }
2699:
2700: private static String getUniqueBindingName(final WSDLModel wsdlModel) {
2701: List<String> existingNames = new ArrayList<String>();
2702:
2703: for (Binding binding : wsdlModel.getDefinitions().getBindings()) {
2704: String name = binding.getName();
2705: existingNames.add(name);
2706: }
2707:
2708: return getUniqueName(existingNames, "casaBinding"); // NOI18N
2709: }
2710:
2711: private static String getUniqueServiceName(final WSDLModel wsdlModel) {
2712: List<String> existingNames = new ArrayList<String>();
2713:
2714: for (Service service : wsdlModel.getDefinitions().getServices()) {
2715: String name = service.getName();
2716: existingNames.add(name);
2717: }
2718:
2719: return getUniqueName(existingNames, "casaService"); // NOI18N
2720: }
2721:
2722: private static String getUniquePortName(final WSDLModel wsdlModel) {
2723: List<String> existingNames = new ArrayList<String>();
2724:
2725: for (Service service : wsdlModel.getDefinitions().getServices()) {
2726: for (Port port : service.getPorts()) {
2727: String name = port.getName();
2728: existingNames.add(name);
2729: }
2730: }
2731:
2732: return getUniqueName(existingNames, "casaPort"); // NOI18N
2733: }
2734:
2735: private static String getUniqueName(
2736: final List<String> existingNames, String prefix) {
2737: String newName = null;
2738:
2739: for (int i = 1;; i++) {
2740: newName = prefix + i;
2741: if (!existingNames.contains(newName)) {
2742: break;
2743: }
2744: }
2745:
2746: return newName;
2747: }
2748:
2749: /**
2750: * Gets the WSDL Model for the given URI string.
2751: */
2752: private WSDLModel getWSDLModel(String uriString)
2753: throws URISyntaxException, CatalogModelException {
2754: WSDLModel ret = null;
2755:
2756: ModelSource modelSource = getModelSource();
2757: Lookup lookup = modelSource.getLookup();
2758: CatalogModel catalogModel = lookup.lookup(CatalogModel.class);
2759:
2760: ModelSource wsdlModelSource = catalogModel.getModelSource(
2761: new URI(uriString), modelSource);
2762: if (wsdlModelSource != null) {
2763: ret = WSDLModelFactory.getDefault().getModel(
2764: wsdlModelSource);
2765: assert ret != null && ret.getDefinitions() != null;
2766: }
2767:
2768: return ret;
2769: }
2770:
2771: // WSDLModel compappWSDLModel = null;
2772: private WSDLModel getCompAppWSDLModel(boolean create) {
2773: // TODO: use cache?
2774: // if (compappWSDLModel != null) {
2775: // return compappWSDLModel;
2776: // }
2777: String compAppWSDLFileName = getCompAppWSDLFileName();
2778:
2779: ModelSource modelSource = getModelSource();
2780: Lookup lookup = modelSource.getLookup();
2781: CatalogModel catalogModel = lookup.lookup(CatalogModel.class);
2782: FileObject casaFO = lookup.lookup(FileObject.class);
2783: URI uri = null;
2784: try {
2785: uri = new URI(CASA_WSDL_RELATIVE_LOCATION
2786: + compAppWSDLFileName);
2787: } catch (URISyntaxException ex) {
2788: ex.printStackTrace();
2789: }
2790:
2791: ModelSource wsdlModelSource = null;
2792:
2793: FileObject srcFO = casaFO.getParent().getParent();
2794: FileObject compAppWSDLDirFO = srcFO.getFileObject("jbiasa"); // NOI18N
2795: if (compAppWSDLDirFO == null && create) {
2796: try {
2797: compAppWSDLDirFO = srcFO.createFolder("jbiasa"); // NOI18N
2798: } catch (Exception e) {
2799: String msg = NbBundle.getMessage(this .getClass(),
2800: "MSG_FAIED_TO_CREATE_DIRECTORY", "src/jbiasa"); // NOI18N
2801: NotifyDescriptor d = new NotifyDescriptor.Message(msg,
2802: NotifyDescriptor.ERROR_MESSAGE);
2803: DialogDisplayer.getDefault().notify(d);
2804: }
2805: }
2806:
2807: if (compAppWSDLDirFO != null) {
2808: File compAppWSDLFile = new File(FileUtil
2809: .toFile(compAppWSDLDirFO), compAppWSDLFileName);
2810: try {
2811: if (!compAppWSDLFile.exists()) {
2812: if (create) {
2813: createEmptyCompAppWSDLFile(compAppWSDLFile);
2814: wsdlModelSource = catalogModel.getModelSource(
2815: uri, modelSource);
2816: }
2817: } else {
2818: wsdlModelSource = catalogModel.getModelSource(uri,
2819: modelSource);
2820: }
2821: } catch (CatalogModelException ex) {
2822: ex.printStackTrace();
2823: }
2824:
2825: if (wsdlModelSource != null) {
2826: WSDLModel wsdlModel = WSDLModelFactory.getDefault()
2827: .getModel(wsdlModelSource);
2828: // compappWSDLModel = wsdlModel;
2829: return wsdlModel;
2830: }
2831: }
2832:
2833: return null;
2834: }
2835:
2836: private String getCompAppWSDLTargetNamespace() {
2837: Project jbiProject = getJBIProject();
2838: return JbiProjectHelper.getJbiProjectName(jbiProject);
2839: }
2840:
2841: private void createEmptyCompAppWSDLFile(File file) {
2842: String tns = getCompAppWSDLTargetNamespace();
2843:
2844: try {
2845: FileObject fo = FileUtil.createData(file);
2846: OutputStream outputStream = fo.getOutputStream();
2847:
2848: PrintWriter out = new PrintWriter(outputStream); // NOI18N
2849: out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); // NOI18M
2850: out.println();
2851: out.println("<!--"); // NOI18N
2852: out.println(" This file is auto-generated by CASA. "); // NOI18N
2853: out
2854: .println(" Edit its content manually may cause unrecoverable errors."); // NOI18N
2855: out.println("-->"); // NOI18N
2856: out.println();
2857: out
2858: .println("<definitions xmlns=\"http://schemas.xmlsoap.org/wsdl/\""); // NOI18M
2859: out
2860: .println(" xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\""); // NOI18M
2861: out
2862: .println(" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""); // NOI18M
2863: out.println(" targetNamespace=\"" + tns + "\""); // NOI18M
2864: out.println(" xmlns:tns=\"" + tns + "\">"); // NOI18M
2865: out.println("</definitions>"); // NOI18M
2866: out.close();
2867: } catch (Exception e) {
2868: e.printStackTrace();
2869: }
2870: }
2871:
2872: /**
2873: * Gets a list of Connections that involve the given WSDL endpoint.
2874: */
2875: private List<CasaConnection> getConnections(
2876: final CasaPort casaPort, boolean includeDeleted) {
2877: List<CasaConnection> ret = new ArrayList<CasaConnection>();
2878:
2879: CasaConsumes consumes = casaPort.getConsumes();
2880: if (consumes != null) {
2881: ret.addAll(getConnections(consumes, includeDeleted));
2882: }
2883:
2884: CasaProvides provides = casaPort.getProvides();
2885: if (provides != null) {
2886: ret.addAll(getConnections(provides, includeDeleted));
2887: }
2888:
2889: return ret;
2890: }
2891:
2892: /**
2893: * Checks whether a service unit is editable.
2894: * For now only external service units are editable.
2895: */
2896: public boolean isEditable(final CasaServiceEngineServiceUnit seSU) {
2897: return !seSU.isInternal();
2898: }
2899:
2900: public boolean isEditable(final CasaServiceEngineServiceUnit seSU,
2901: String propertyName) {
2902: if (!isEditable(seSU)) {
2903: return false;
2904: }
2905:
2906: if (CasaAttribute.UNIT_NAME.getName().equals(propertyName)
2907: || CasaAttribute.DESCRIPTION.getName().equals(
2908: propertyName)) {
2909: return true;
2910: } else {
2911: return false;
2912: }
2913: }
2914:
2915: public boolean isEditable(final CasaBindingComponentServiceUnit bcSU) {
2916: return false;
2917: }
2918:
2919: /**
2920: * Checks whether a CasaPort is editable.
2921: * Only CasaPorts coming from compapp are editable. CasaPorts that come from
2922: * component projects are not editable.
2923: */
2924: public boolean isEditable(final CasaPort casaPort) {
2925: return isDefinedInCompApp(casaPort);
2926: }
2927:
2928: /**
2929: * Checks whether a particular property of a CasaPort is editable.
2930: */
2931: public boolean isEditable(final CasaPort casaPort,
2932: String propertyName) {
2933: if (!isEditable(casaPort)) {
2934: return false;
2935: }
2936:
2937: // Can't edit internface name when there is visible connection
2938: if (JBIAttributes.INTERFACE_NAME.getName().equals(propertyName)
2939: && getConnections(casaPort, false).size() > 0) {
2940: return false;
2941: }
2942:
2943: return true;
2944: }
2945:
2946: /**
2947: * Checks whether a particular property of an endpoint is editable.
2948: *
2949: * Endpoints in internal service engine service unit and WSDL endpoints
2950: * casa port that come from component projects are not editable.
2951: */
2952: public boolean isEditable(final CasaEndpointRef endpointRef,
2953: String propertyName) {
2954:
2955: CasaServiceEngineServiceUnit seSU = getCasaEngineServiceUnit(endpointRef);
2956: if (seSU != null) {
2957: if (seSU.isInternal()) {
2958: return false;
2959: }
2960: } else {
2961: CasaPort casaPort = getCasaPort(endpointRef);
2962: if (!isEditable(casaPort)) {
2963: return false;
2964: }
2965: }
2966:
2967: // Can't edit internface name when there is visible connection
2968: if (JBIAttributes.INTERFACE_NAME.getName().equals(propertyName)) {
2969: /* Issue: 113870 : The consumes and provides of wsdl end points shouldn't be editable */
2970: CasaPort casaPort = getCasaPort(endpointRef);
2971: if (casaPort != null) {
2972: return false;
2973: }
2974: /*
2975: if (getConnections(endpointRef, false).size() > 0) {
2976: return false;
2977: } else {
2978: // For WSDL port, we need to check both consumes and provides.
2979: CasaPort casaPort = getCasaPort(endpointRef);
2980: if (casaPort != null
2981: && getConnections(casaPort, false).size() > 0) {
2982: return false;
2983: }
2984: }
2985: */
2986: }
2987:
2988: return true;
2989: }
2990:
2991: /**
2992: * Check whether the given casa port is defined in the composite application.
2993: */
2994: private boolean isDefinedInCompApp(final CasaPort casaPort) {
2995: CasaLink link = casaPort.getLink();
2996: String linkHref = link.getHref();
2997: return linkHref.startsWith("../jbiasa/"); // NOI18N
2998: }
2999:
3000: private boolean isDefinedInCompAppWSDL(final CasaPort casaPort) {
3001: CasaLink link = casaPort.getLink();
3002: String linkHref = link.getHref();
3003: return linkHref.startsWith("../jbiasa/"
3004: + getCompAppWSDLFileName() + "#xpointer"); // NOI18N
3005: }
3006:
3007: /**
3008: * Checks whether a service unit is deletable. For now a service unit is
3009: * always deletable.
3010: */
3011: public boolean isDeletable(final CasaServiceEngineServiceUnit seSU) {
3012: return true;
3013: }
3014:
3015: public boolean isDeletable(
3016: final CasaBindingComponentServiceUnit bcSU) {
3017: return true;
3018: }
3019:
3020: /**
3021: * Checks whether a WSDL endpoint is deletable.
3022: */
3023: public boolean isDeletable(final CasaPort casaPort) {
3024: return true;
3025: }
3026:
3027: /**
3028: * Checks whether an endpoint is deletable. An endpoint is deletable if
3029: * and only if it belongs to an external service engine service unit.
3030: */
3031: public boolean isDeletable(final CasaEndpointRef endpointRef) {
3032: CasaServiceEngineServiceUnit casaSESU = getCasaEngineServiceUnit(endpointRef);
3033: return casaSESU != null && !casaSESU.isInternal();
3034: }
3035:
3036: /**
3037: * Checks whether a connection is deletable. A connection is always deletable,
3038: * although for auto-generated connections, a delete is actually a hide.
3039: */
3040: public boolean isDeletable(final CasaConnection connection) {
3041: return true;
3042: }
3043:
3044: /**
3045: * Sets name of an endpoint.
3046: * To keep model integrity, the following side effects of this change
3047: * could occur, if applicable:
3048: * <UL>
3049: * <LI> The name of the corresponding WSDL port in WSDL file (casa wsdl)
3050: * is updated;
3051: * <LI> The containing casa port's link href is updated.
3052: * </UL>
3053: */
3054: private void setEndpointName(final CasaComponent component,
3055: CasaEndpointRef endpointRef, String endpointName) {
3056: CasaEndpoint casaEndpoint = endpointRef.getEndpoint().get();
3057:
3058: String oldEndpointName = casaEndpoint.getEndpointName();
3059: if (oldEndpointName.equals(endpointName)) {
3060: return;
3061: }
3062:
3063: // If the corresponding port is defined in casa wsdl,
3064: // update the port name in casa wsdl and also the xlink in casa.
3065: CasaPort casaPort = null;
3066: if (component instanceof CasaPort) {
3067: casaPort = (CasaPort) component;
3068: } else {
3069: casaPort = getCasaPort((CasaEndpointRef) component);
3070: }
3071:
3072: if (casaPort != null) {
3073: Port port = getLinkedWSDLPort(casaPort);
3074: // The port must be defined in casa wsdl because otherwise
3075: // the endpoint is not editable.
3076: WSDLModel compAppWSDLModel = port.getModel();
3077: compAppWSDLModel.startTransaction();
3078: try {
3079: port.setName(endpointName);
3080: } finally {
3081: if (compAppWSDLModel.isIntransaction()) {
3082: compAppWSDLModel.endTransaction();
3083: }
3084: }
3085: }
3086:
3087: startTransaction();
3088: try {
3089: if (casaPort != null) {
3090: CasaLink link = casaPort.getLink();
3091: String linkHref = link.getHref();
3092: linkHref = linkHref.replaceAll("/port\\[@name='"
3093: + oldEndpointName + "'\\]", // NOI18N
3094: "/port[@name='" + endpointName + "']"); // NOI18N
3095: link.setHref(linkHref);
3096: }
3097:
3098: casaEndpoint.setEndpointName(endpointName);
3099:
3100: } finally {
3101: if (isIntransaction()) {
3102: fireChangeEvent(component,
3103: PROPERTY_ENDPOINT_NAME_CHANGED);
3104: if (casaPort != null && casaPort != component) {
3105: fireChangeEvent(casaPort,
3106: PROPERTY_ENDPOINT_NAME_CHANGED);
3107: }
3108: endTransaction();
3109: }
3110: }
3111: }
3112:
3113: /**
3114: * Sets the interface QName of an endpoint. Updates the corresponding WSDL
3115: * Port, Binding and PortType if the endpoint is defined in casa wsdl.
3116: *
3117: * @param endpointRef a casa consumes or provides endpoint reference
3118: * @param interfaceQName the new interface QName for the referenced endpoint
3119: */
3120: // TRANSACTION BOUNDARY
3121: // USE CASE: from property sheet or interface property editor
3122: // AFFECT: CASA, COMPAPP.WSDL
3123: public void setEndpointInterfaceQName(
3124: final CasaEndpointRef endpointRef,
3125: final QName interfaceQName) {
3126: _setEndpointInterfaceQName(endpointRef, interfaceQName);
3127: }
3128:
3129: /**
3130: * Sets the interface QName of an endpoint. Updates the corresponding WSDL
3131: * Port, Binding and PortType if the endpoint is defined in casa wsdl.
3132: *
3133: * @param endpointRef a casa consumes or provides endpoint reference
3134: * @param interfaceQName the new interface QName for the referenced endpoint
3135: */
3136: private void _setEndpointInterfaceQName(
3137: final CasaEndpointRef endpointRef,
3138: final QName interfaceQName) {
3139:
3140: if (endpointRef.getInterfaceQName().equals(interfaceQName)) {
3141: return; // need this to avoid infinite loop
3142: }
3143:
3144: // 1. Update endpoint interface qname in casa.
3145: CasaEndpoint endpoint = endpointRef.getEndpoint().get();
3146: QName oldInterfaceQName = endpoint.getInterfaceQName();
3147: startTransaction();
3148: try {
3149: if (interfaceQName == null
3150: || interfaceQName.equals(new QName(""))) { // NOI18N
3151: CasaPort casaPort = getCasaPort(endpointRef);
3152: if (casaPort != null
3153: && isDefinedInCompAppWSDL(casaPort)) {
3154: Port port = getLinkedWSDLPort(casaPort);
3155: WSDLModel compAppWSDLModel = port.getModel();
3156: String tns = compAppWSDLModel.getDefinitions()
3157: .getTargetNamespace();
3158: endpoint.setInterfaceQName(new QName(tns,
3159: DUMMY_PORTTYPE_NAME));
3160: } else {
3161: endpoint.setInterfaceQName(interfaceQName);
3162: }
3163: } else {
3164: endpoint.setInterfaceQName(interfaceQName);
3165: }
3166: } finally {
3167: if (isIntransaction()) {
3168: fireChangeEvent(endpointRef,
3169: PROPERTY_ENDPOINT_INTERFACE_QNAME_CHANGED);
3170: endTransaction();
3171: }
3172: }
3173:
3174: // 2. Update compapp.wsdl and casacade the interface change, if applicable.
3175: CasaPort casaPort = getCasaPort(endpointRef);
3176: if (casaPort == null) {
3177: return;
3178: }
3179: Port port = getLinkedWSDLPort(casaPort);
3180:
3181: if (port == null) {
3182: String msg = NbBundle.getMessage(this .getClass(),
3183: "MSG_CORRUPTED_MODEL_WITH_MISSING_WSDL_PORT", // NOI18N
3184: casaPort.getLink().getHref());
3185: NotifyDescriptor d = new NotifyDescriptor.Message(msg,
3186: NotifyDescriptor.ERROR_MESSAGE);
3187: DialogDisplayer.getDefault().notify(d);
3188: return;
3189: }
3190:
3191: if (isDefinedInCompAppWSDL(casaPort)) {
3192: WSDLModel compAppWSDLModel = port.getModel();
3193: String tns = compAppWSDLModel.getDefinitions()
3194: .getTargetNamespace();
3195:
3196: if (interfaceQName == null
3197: || interfaceQName.equals(new QName("")) || // NOI18N
3198: interfaceQName.equals(new QName(tns,
3199: DUMMY_PORTTYPE_NAME))) {
3200: PortType dummyPT = getDummyPortType(compAppWSDLModel,
3201: true);
3202: // Here we also need to clean up casa wsdl:
3203: compAppWSDLModel.startTransaction();
3204: try {
3205: // (1) remove wsdl port children
3206: for (ExtensibilityElement ex : port
3207: .getExtensibilityElements()) {
3208: port.removeExtensibilityElement(ex);
3209: }
3210: // (2) remove binding children
3211: Binding binding = port.getBinding().get();
3212: for (BindingOperation op : binding
3213: .getBindingOperations()) {
3214: binding.removeBindingOperation(op);
3215: }
3216: for (ExtensibilityElement ex : binding
3217: .getExtensibilityElements()) {
3218: binding.removeExtensibilityElement(ex);
3219: }
3220: // (3) change binding type to dummy porttype
3221: binding.setType(binding.createReferenceTo(dummyPT,
3222: PortType.class));
3223: } finally {
3224: if (compAppWSDLModel.isIntransaction()) {
3225: compAppWSDLModel.endTransaction();
3226: }
3227: }
3228: } else {
3229: try {
3230: populateBindingAndPort(casaPort, port,
3231: interfaceQName, casaPort.getBindingType());
3232: } catch (RuntimeException e) {
3233: // TODO: we need better transaction rollback handling.
3234: startTransaction();
3235: try {
3236: endpoint.setInterfaceQName(oldInterfaceQName);
3237: } finally {
3238: if (isIntransaction()) {
3239: fireChangeEvent(endpointRef,
3240: PROPERTY_ENDPOINT_INTERFACE_QNAME_CHANGED);
3241: endTransaction();
3242: }
3243: }
3244: throw e;
3245: }
3246: }
3247: } else {
3248: // TODO
3249: }
3250: }
3251:
3252: /**
3253: * Sets the service QName of a CASA endpoint reference (consumes/provides).
3254: *
3255: * The owner of the endpoint could be an external SE SU, or an editable
3256: * BC SU. For editable BC SU, the change is also propagated to the
3257: * corresponding WSDL file.
3258: */
3259: // TRANSACTION BOUNDARY
3260: // USE CASE: from property sheet
3261: // AFFECT: CASA, (COMPAPP.WSDL or other WSDL defined in CompApp project)
3262: public void setEndpointServiceQName(
3263: final CasaEndpointRef endpointRef,
3264: final QName newServiceQName) {
3265:
3266: CasaEndpoint endpoint = endpointRef.getEndpoint().get();
3267: QName oldServiceQName = endpoint.getServiceQName();
3268: if (oldServiceQName.equals(newServiceQName)) {
3269: return;
3270: }
3271:
3272: CasaPort casaPort = getCasaPort(endpointRef);
3273:
3274: // Validate service QName localname
3275: String newServiceName = newServiceQName.getLocalPart();
3276: if (!isNCName(newServiceName)) {
3277: String msg = NbBundle.getMessage(CasaWrapperModel.class,
3278: "MSG_INVALID_SERVICE_NAME", newServiceName); // NOI18N
3279: NotifyDescriptor d = new NotifyDescriptor.Message(msg,
3280: NotifyDescriptor.ERROR_MESSAGE);
3281: DialogDisplayer.getDefault().notify(d);
3282: return;
3283: }
3284:
3285: // Validate service QName namespace
3286: String newServiceNamespace = newServiceQName.getNamespaceURI();
3287: if (!isURI(newServiceNamespace)) {
3288: String msg = NbBundle.getMessage(CasaWrapperModel.class,
3289: "MSG_INVALID_NAMESPACE_URI", newServiceNamespace); // NOI18N
3290: NotifyDescriptor d = new NotifyDescriptor.Message(msg,
3291: NotifyDescriptor.ERROR_MESSAGE);
3292: DialogDisplayer.getDefault().notify(d);
3293: return;
3294: }
3295:
3296: // Validate service QName prefix
3297: String newPrefix = newServiceQName.getPrefix();
3298: if (!isNCName(newPrefix)) {
3299: String msg = NbBundle.getMessage(CasaWrapperModel.class,
3300: "MSG_INVALID_PREFIX_NAME", newPrefix); // NOI18N
3301: NotifyDescriptor d = new NotifyDescriptor.Message(msg,
3302: NotifyDescriptor.ERROR_MESSAGE);
3303: DialogDisplayer.getDefault().notify(d);
3304: return;
3305: }
3306:
3307: // If the owner of the endpoint is a BC SU, then the change needs to be
3308: // propagated to the corresponding WSDL file.
3309: if (casaPort != null) {
3310:
3311: // Make sure the service is still in the WSDL's target namespace
3312: if (!newServiceNamespace.equals(oldServiceQName
3313: .getNamespaceURI())) {
3314: String msg = NbBundle.getMessage(
3315: CasaWrapperModel.class,
3316: "MSG_INVALID_SERVICE_NAMESPACE", // NOI18N
3317: oldServiceQName.getNamespaceURI());
3318: NotifyDescriptor d = new NotifyDescriptor.Message(msg,
3319: NotifyDescriptor.ERROR_MESSAGE);
3320: DialogDisplayer.getDefault().notify(d);
3321: return;
3322: }
3323:
3324: Port oldPort = getLinkedWSDLPort(casaPort);
3325: Service oldService = (Service) oldPort.getParent();
3326: WSDLModel wsdlModel = oldPort.getModel();
3327: WSDLComponentFactory wsdlFactory = wsdlModel.getFactory();
3328: Definitions definitions = oldPort.getModel()
3329: .getDefinitions();
3330:
3331: Service newService = null;
3332: for (Service service : definitions.getServices()) {
3333: if (service.getName().equals(newServiceName)) {
3334: newService = service;
3335: break;
3336: }
3337: }
3338:
3339: if (newService != null) {
3340: // Make sure the new service name doesn't cause any
3341: // name conflict for ports.
3342: String portName = endpointRef.getEndpointName();
3343: for (Port port : newService.getPorts()) {
3344: if (port.getName().equals(portName)) {
3345: String msg = NbBundle
3346: .getMessage(
3347: CasaWrapperModel.class,
3348: "MSG_SETTING_SERVICE_QNAME_CAUSES_PORT_CONFLICT", // NOI18N
3349: newServiceQName);
3350: NotifyDescriptor d = new NotifyDescriptor.Message(
3351: msg, NotifyDescriptor.ERROR_MESSAGE);
3352: DialogDisplayer.getDefault().notify(d);
3353: return;
3354: }
3355: }
3356: }
3357:
3358: wsdlModel.startTransaction();
3359: try {
3360: // Create new service if applicable
3361: if (newService == null) {
3362: newService = wsdlFactory.createService();
3363: newService.setName(newServiceName);
3364: definitions.addService(newService);
3365: }
3366:
3367: Port newPort = (Port) oldPort.copy(newService);
3368:
3369: // Remove old service/port
3370: if (oldService.getPorts().size() == 1) {
3371: definitions.removeService(oldService);
3372: oldService = null;
3373: }
3374: if (oldService != null) { // remove AFTER cloning the old port
3375: oldService.removePort(oldPort);
3376: }
3377:
3378: // Add new port
3379: newService.addPort(newPort);
3380: } finally {
3381: if (wsdlModel.isIntransaction()) {
3382: wsdlModel.endTransaction();
3383: }
3384: }
3385: }
3386:
3387: startTransaction();
3388: try {
3389: if (casaPort != null) {
3390: String oldServiceName = oldServiceQName.getLocalPart();
3391:
3392: // Update casa port link href
3393: CasaLink link = casaPort.getLink();
3394: String linkHref = link.getHref();
3395: linkHref = linkHref.replaceAll("/service\\[@name='"
3396: + oldServiceName + "'\\]", // NOI18N
3397: "/service[@name='" + newServiceName + "']"); // NOI18N
3398: link.setHref(linkHref);
3399:
3400: // Update service link
3401: // We could probably live without the update until the next build.
3402: }
3403:
3404: endpoint.setServiceQName(newServiceQName);
3405: } finally {
3406: if (isIntransaction()) {
3407: fireChangeEvent(endpointRef,
3408: PROPERTY_ENDPOINT_SERVICE_QNAME_CHANGED);
3409: endTransaction();
3410: }
3411: }
3412: }
3413:
3414: public CasaRegion getCasaRegion(CasaRegion.Name regionName) {
3415: String name = regionName.getName();
3416: List<CasaRegion> regions = getRootComponent().getRegions()
3417: .getRegions();
3418: for (CasaRegion region : regions) {
3419: if (region.getName().equals(name)) {
3420: return region;
3421: }
3422: }
3423:
3424: assert false : "Unknown casa region: " + name; // NOI18N
3425: return null;
3426: }
3427:
3428: /**
3429: * Sets the width of the given casa region.
3430: */
3431: // TRANSACTION BOUNDARY
3432: // USE CASE: on region resize
3433: // AFFECT: CASA
3434: public void setCasaRegionWidth(final CasaRegion casaRegion,
3435: int width) {
3436: startTransaction();
3437: try {
3438: casaRegion.setWidth(width);
3439: } finally {
3440: if (isIntransaction()) {
3441: endTransaction();
3442: }
3443: }
3444: }
3445:
3446: /**
3447: * Sets the unit name of an external service engine service unit.
3448: */
3449: // TRANSACTION BOUNDARY
3450: // USE CASE: on setting name from property sheet
3451: // AFFECT: CASA
3452: // TODO: rename me, change signature
3453: public void setUnitName(final CasaServiceUnit su, String unitName) {
3454: assert su instanceof CasaServiceEngineServiceUnit;
3455: assert !((CasaServiceEngineServiceUnit) su).isInternal();
3456:
3457: startTransaction();
3458: try {
3459: su.setUnitName(unitName);
3460: } finally {
3461: if (isIntransaction()) {
3462: fireChangeEvent(su, PROPERTY_SERVICE_UNIT_RENAMED);
3463: endTransaction();
3464: }
3465: }
3466: }
3467:
3468: /**
3469: * Gets all the namespaces defined in the SA jbi model.
3470: *
3471: * @return a map mapping namespace prefix to namespace URI
3472: */
3473: public Map<String, String> getNamespaces() {
3474: return getDocumentModelNamespaces(this );
3475: }
3476:
3477: /**
3478: * Gets the namespaces defined in any document model. Note that certain
3479: * well-known namespaces are not included.
3480: *
3481: * @return a map mapping namespace prefix to namespace URI
3482: */
3483: private static Map<String, String> getDocumentModelNamespaces(
3484: AbstractDocumentModel model) {
3485: Map<String, String> ret = new TreeMap<String, String>();
3486:
3487: NamedNodeMap map = model.getRootComponent().getPeer()
3488: .getAttributes();
3489: for (int j = 0; j < map.getLength(); j++) {
3490: Node node = map.item(j);
3491:
3492: String prefix = node.getPrefix();
3493: if (prefix != null && prefix.equals("xmlns")) {
3494: String localName = node.getLocalName();
3495: if (!localName.equals("xsi") // NOI18N // TMP
3496: && !localName.equals("xlink")) { // NOI18N // TMP
3497: String namespaceURI = node.getNodeValue();
3498: ret.put(localName, namespaceURI);
3499: }
3500: }
3501: }
3502:
3503: return ret;
3504: }
3505:
3506: public String getJbiProjectType(Project p) {
3507: if (p == null) {
3508: return null;
3509: }
3510:
3511: // allow JavaEE project types
3512: if (JbiDefaultComponentInfo.isJavaEEProject(p)) {
3513: return JbiProjectConstants.JAVA_EE_SE_COMPONENT_NAME;
3514: }
3515:
3516: AntArtifactProvider prov = p.getLookup().lookup(
3517: AntArtifactProvider.class);
3518: if (prov != null) {
3519: AntArtifact[] artifacts = prov.getBuildArtifacts();
3520: Iterator<String> artifactTypeItr = null;
3521: String artifactType = null;
3522: if (artifacts != null) {
3523: for (int i = 0; i < artifacts.length; i++) {
3524: artifactTypeItr = this .artifactTypes.iterator();
3525: while (artifactTypeItr.hasNext()) {
3526: artifactType = artifactTypeItr.next();
3527: String arts = artifacts[i].getType();
3528: if (arts.startsWith(artifactType)) {
3529: int idx = arts.indexOf(':') + 1;
3530: return arts.substring(idx);
3531: }
3532: }
3533: }
3534: }
3535: }
3536:
3537: return null;
3538: }
3539:
3540: public void clearCache() {
3541: cachedWSDLComponents.clear();
3542: }
3543:
3544: @Override
3545: public void sync() throws IOException {
3546: // This should reset the internal fields/state of saJBIModel
3547: // as well as make a call to saJBIModel.super.sync()
3548: super .sync();
3549:
3550: WSDLModel compAppWSDLModel = getCompAppWSDLModel(false);
3551:
3552: if (compAppWSDLModel != null) {
3553: compAppWSDLModel.sync();
3554: }
3555:
3556: cachedWSDLComponents.clear();
3557:
3558: // mayShowUnavailableWSDLModelError = true;
3559:
3560: // Probably need to also reset all internal fields/state
3561: // of the su jbi models.
3562: // cachedReferences.clear();
3563:
3564: // This seems necessary to update the extensibility elements
3565: // when switching from source -> design view.
3566: // Perhaps this introduces a performance hit?
3567: super .refresh();
3568:
3569: // At the very end, we need to fire a property change event
3570: // so that the view can update itself.
3571: mSupport.firePropertyChange(new PropertyChangeEvent(this ,
3572: PROPERTY_MODEL_RELOAD, null, null));
3573: }
3574:
3575: /*
3576: private void startMyTransaction() {
3577: assert !isIntransaction();
3578: startTransaction();
3579: }
3580:
3581: private void rollbackMyTransaction() {
3582: assert isIntransaction();
3583: rollbackTransaction();
3584: }
3585:
3586: private void endMyTransaction() {
3587: assert isIntransaction();
3588: endTransaction();
3589: }
3590: */
3591: /**
3592: * Validates this model.
3593: *
3594: * @return a list of validation result items.
3595: */
3596: public List<ResultItem> validate() {
3597:
3598: List<ResultItem> ret = new ArrayList<ResultItem>();
3599:
3600: List<Model> models = new ArrayList<Model>();
3601: models.add(this );
3602:
3603: // FIXME: should validate all WSDL Models defined in CompApp
3604: WSDLModel compAppWSDLModel = getCompAppWSDLModel(false);
3605: if (compAppWSDLModel != null) {
3606: models.add(compAppWSDLModel);
3607: }
3608:
3609: for (Model model : models) {
3610: Validation validation = new Validation();
3611: validation.validate(model, ValidationType.COMPLETE);
3612: List<ResultItem> validationResult = validation
3613: .getValidationResult();
3614: ret.addAll(validationResult);
3615: }
3616:
3617: return ret;
3618: }
3619:
3620: // TMP
3621: private CasaValidationController controller;
3622:
3623: public CasaValidationController getValidationController() {
3624: if (controller == null) {
3625: controller = new CasaValidationController(this );
3626: }
3627: return controller;
3628: }
3629:
3630: /**
3631: * Checks whether the given name is a valid NCName.
3632: * (http://www.w3.org/TR/REC-xml-names/#NT-NCName)
3633: */
3634: private static boolean isNCName(String name) {
3635: String regex = "[_A-Za-z][-._A-Za-z0-9]*"; // NOI18N
3636: return name.matches(regex);
3637: }
3638:
3639: /**
3640: * Checks whether the given name is a valid URI.
3641: * (http://www.ietf.org/rfc/rfc2396.txt)
3642: */
3643: private static boolean isURI(String uri) {
3644: String regex = "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?"; // NOI18N
3645: return uri.matches(regex);
3646: }
3647:
3648: // CasaModel
3649:
3650: public Casa getRootComponent() {
3651: return casa;
3652: }
3653:
3654: public void setCasa(Casa casa) {
3655: this .casa = casa;
3656: }
3657:
3658: protected ComponentUpdater<CasaComponent> getComponentUpdater() {
3659: return new CasaSyncUpdateVisitor();
3660: }
3661:
3662: public CasaComponent createComponent(CasaComponent parent,
3663: Element element) {
3664: return getFactory().create(element, parent);
3665: }
3666:
3667: public Casa createRootComponent(Element root) {
3668: Casa casa = new CasaImpl(this , root);
3669: setCasa(casa);
3670: return casa;
3671: }
3672:
3673: public CasaComponentFactory getFactory() {
3674: return factory;
3675: }
3676:
3677: //------------------------------------------------------------------------
3678: // 02/06/08, T. Li CASA usability enhancements
3679: // - wsit config badge update
3680: // - clone wsdl port (from SU.jar to CompApp) to edit
3681: //------------------------------------------------------------------------
3682:
3683: /**
3684: * Check to see if the port has any WS policy attached
3685: * @param casaPort
3686: * @return true if has WS policies
3687: */
3688: public boolean isWsitEnable(final CasaPort casaPort) {
3689: Port port = getLinkedWSDLPort(casaPort);
3690: Binding binding = port.getBinding().get();
3691: for (ExtensibilityElement ex : binding
3692: .getExtensibilityElements()) {
3693: String exNS = ex.getQName().getNamespaceURI();
3694: if (exNS
3695: .equals("http://schemas.xmlsoap.org/ws/2004/09/policy")) { // NOI18N
3696: return true;
3697: }
3698: }
3699: return false;
3700: }
3701:
3702: public void refershWsitStatus(final CasaPort casaPort) {
3703: startTransaction();
3704: try {
3705: if (casaPort != null) {
3706: // no CASA model change is needed for now...
3707: }
3708: } finally {
3709: if (isIntransaction()) {
3710: if (casaPort != null) {
3711: fireChangeEvent(casaPort,
3712: PROPERTY_CASA_PORT_REFRESH);
3713: }
3714: endTransaction();
3715: }
3716: }
3717:
3718: }
3719:
3720: /**
3721: * Change the xlink reference of a casa WSDL port
3722: * @param casaPort selected WSDL port
3723: * @param href xlink reference
3724: */
3725: public void setEndpointLink(CasaPort casaPort, String href) {
3726: if ((casaPort == null)
3727: || (casaPort.getLink().getHref().equals(href))) {
3728: return;
3729: }
3730:
3731: startTransaction();
3732: try {
3733: casaPort.getLink().setHref(href);
3734: } finally {
3735: if (isIntransaction()) {
3736: fireChangeEvent(casaPort, PROPERTY_CASA_PORT_REFRESH);
3737: endTransaction();
3738: }
3739: }
3740: }
3741:
3742: }
|