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.projects.jbi.anttasks;
0042:
0043: import java.io.File;
0044: import java.io.IOException;
0045: import java.util.ArrayList;
0046: import java.util.HashMap;
0047: import java.util.List;
0048: import java.util.Map;
0049: import javax.xml.namespace.QName;
0050: import javax.xml.parsers.DocumentBuilder;
0051: import javax.xml.parsers.DocumentBuilderFactory;
0052: import javax.xml.parsers.ParserConfigurationException;
0053: import org.apache.tools.ant.Project;
0054: import org.apache.tools.ant.Task;
0055: import org.netbeans.modules.compapp.projects.jbi.api.JbiProjectConstants;
0056: import org.netbeans.modules.compapp.projects.jbi.descriptor.XmlUtil;
0057: import org.netbeans.modules.compapp.projects.jbi.descriptor.endpoints.model.Endpoint;
0058: import org.netbeans.modules.compapp.projects.jbi.util.MyFileUtil;
0059: import org.netbeans.modules.xml.wsdl.model.Binding;
0060: import org.netbeans.modules.xml.wsdl.model.Definitions;
0061: import org.netbeans.modules.xml.wsdl.model.Port;
0062: import org.netbeans.modules.xml.wsdl.model.PortType;
0063: import org.netbeans.modules.xml.wsdl.model.Service;
0064: import org.netbeans.modules.xml.wsdl.model.WSDLModel;
0065: import org.openide.filesystems.FileObject;
0066: import org.openide.filesystems.FileUtil;
0067: import org.openide.util.Lookup;
0068: import org.w3c.dom.DOMException;
0069: import org.w3c.dom.Document;
0070: import org.w3c.dom.Element;
0071: import org.w3c.dom.NamedNodeMap;
0072: import org.w3c.dom.Node;
0073: import org.w3c.dom.NodeList;
0074: import org.w3c.dom.Text;
0075: import org.xml.sax.SAXException;
0076:
0077: import static org.netbeans.modules.compapp.projects.jbi.CasaConstants.*;
0078: import static org.netbeans.modules.compapp.projects.jbi.JbiConstants.*;
0079: import static org.netbeans.modules.compapp.projects.jbi.api.JbiEndpointExtensionConstants.*;
0080:
0081: /**
0082: *
0083: * @author jqian
0084: */
0085: public class CasaBuilder {
0086:
0087: // WSDL Domain
0088: public static final String WSDL_NAMESPACE_URI = "http://schemas.xmlsoap.org/wsdl/";
0089: public static final String WSDL_PORT_ELEM_NAME = "port";
0090: public static final String WSDL_SERVICE_ELEM_NAME = "service";
0091: public static final String WSDL_NAME_ATTR_NAME = "name";
0092: // XLink Domain
0093: public static final String XLINK_NAMESPACE_URI = "http://www.w3.org/2000/xlink";
0094: public static final String XLINK_NAMESPACE_PREFIX = "xlink";
0095: public static final String XLINK_HREF_ATTR_NAME = "href";
0096: public static final String XLINK_TYPE_ATTR_NAME = "type";
0097: public static final String WSDL_ENDPOINTS_REGION_NAME = "WSDL Endpoints";
0098: public static final String JBI_MODULES_REGION_NAME = "JBI Modules";
0099: public static final String EXTERNAL_MODULES_REGION_NAME = "External Modules";
0100: public static final String DEFAULT_WSDL_ENDPOINTS_REGION_WIDTH = "150";
0101: public static final String DEFAULT_JBI_MODULES_REGION_WIDTH = "500";
0102: public static final String DEFAULT_EXTERNAL_MODULES_REGION_WIDTH = "200";
0103: // mapping binding component namespace to binding component name,
0104: // e.x.,
0105: private Map<String, String> bcNamespace2NameMap;
0106: // mapping SE/BC SU name to endpoints defined in the SU's jbi.xml
0107: private Map<String, List<Endpoint>> su2Endpoints = new HashMap<String, List<Endpoint>>();
0108: // A Map mapping fully qualified endpoint name to endpoint ID for all
0109: // the endpoints in the new casa document.
0110: private Map<String, String> newEndpointMap = new HashMap<String, String>();
0111: // index used for creating endpoint IDs in the new casa document
0112: private int endpointIndex = 1;
0113: // a list of external endpoints in the old casa document
0114: private List<Endpoint> externalEndpoints;
0115: // a list of endpoints defined in all the WSDL files in the compapp and
0116: // its component projects
0117: private List<Endpoint> newWsdlEndpoints;
0118: // mapping BC name to list of deleted endpoints for that BC type in the
0119: // old casa document
0120: private Map<String, List<Endpoint>> deletedBCEndpointsMap;
0121: // mapping BC name to a list of unconnected endpoints in the old casa document
0122: private Map<String, List<Endpoint>> oldUnconnectedBCEndpointsMap;
0123: private String serviceUnitsDirLoc;
0124: private String confDirLoc;
0125: private String casaFileLoc;
0126: private Project project;
0127: private wsdlRepository wsdlRepository;
0128: private Task task;
0129: private Document oldCasaDocument;
0130: private Document newCasaDocument;
0131:
0132: public CasaBuilder(Project project, wsdlRepository wsdlRepository,
0133: Task task) {
0134:
0135: this .project = project;
0136: this .wsdlRepository = wsdlRepository;
0137: this .task = task;
0138:
0139: String projName = AntProjectHelper
0140: .getServiceAssemblyID(project);
0141: String projPath = project.getProperty("basedir")
0142: + File.separator;
0143: String srcDirLoc = projPath + "src" + File.separator;
0144: confDirLoc = srcDirLoc + "conf" + File.separator;
0145: serviceUnitsDirLoc = srcDirLoc
0146: + JbiProjectConstants.FOLDER_JBISERVICEUNITS
0147: + File.separator;
0148: casaFileLoc = confDirLoc + projName + ".casa";
0149:
0150: File casaFile = new File(casaFileLoc);
0151: if (casaFile.exists()) {
0152: DocumentBuilderFactory factory = DocumentBuilderFactory
0153: .newInstance();
0154: factory.setValidating(false);
0155: factory.setNamespaceAware(true);
0156: try {
0157: DocumentBuilder documentBuilder = factory
0158: .newDocumentBuilder();
0159: oldCasaDocument = documentBuilder.parse(casaFile);
0160: } catch (Exception ex) {
0161: ex.printStackTrace();
0162: }
0163: }
0164: }
0165:
0166: final Document getOldCasaDocument() {
0167: return oldCasaDocument;
0168: }
0169:
0170: /**
0171: * Creates a new CASA document based on sa jbi.xml and optionally
0172: * an old CASA file.
0173: *
0174: * @param jbiDocument service assembly JBI document
0175: *
0176: * @return the new CASA document
0177: */
0178: public Document createCasaDocument(Document jbiDocument) {
0179: try {
0180: DocumentBuilderFactory factory = DocumentBuilderFactory
0181: .newInstance();
0182: factory.setNamespaceAware(true);
0183:
0184: DocumentBuilder builder = factory.newDocumentBuilder();
0185: newCasaDocument = builder.newDocument();
0186:
0187: Element casaRoot = newCasaDocument
0188: .createElement(CASA_ELEM_NAME);
0189: newCasaDocument.appendChild(casaRoot);
0190: casaRoot.setAttribute("xmlns", CASA_NAMESPACE_URI);
0191: casaRoot.setAttribute("xmlns:" + XLINK_NAMESPACE_PREFIX,
0192: XLINK_NAMESPACE_URI);
0193:
0194: // build binding component namespace to ID map
0195: bcNamespace2NameMap = wsdlRepository
0196: .buildBindingComponentMap(project);
0197:
0198: // Prepare various endpoint lists
0199: deletedBCEndpointsMap = getDeletedBCEndpointsMap();
0200: oldUnconnectedBCEndpointsMap = getUnconnectedBCEndpointsMap();
0201:
0202: // endpoints
0203: Element casaEndpoints = createEndpoints(jbiDocument);
0204: casaRoot.appendChild(casaEndpoints);
0205:
0206: // service units
0207: Element casaServiceUnits = createSUs(jbiDocument);
0208: casaRoot.appendChild(casaServiceUnits);
0209:
0210: // connections
0211: Element casaConnections = createConnections(jbiDocument);
0212: casaRoot.appendChild(casaConnections);
0213:
0214: // porttypes, bindings, services
0215: List<Element> casaWSDLReferences = createWSDLReferenceElements();
0216: for (Element casaElement : casaWSDLReferences) {
0217: casaRoot.appendChild(casaElement);
0218: }
0219:
0220: // regions
0221: Element casaRegions = createRegions();
0222: casaRoot.appendChild(casaRegions);
0223:
0224: // preserveCasaWSDLEndpointsAndPorts();
0225:
0226: mergeLocations();
0227:
0228: // Merge endpoint extension elements from old casa
0229: mergeBCEndpointExtensions(true);
0230: mergeBCEndpointExtensions(false);
0231:
0232: // Merge connection extension elements from old casa
0233: mergeConnectionExtensions();
0234:
0235: XmlUtil.writeToFile(casaFileLoc, newCasaDocument);
0236: } catch (Exception e) {
0237: e.printStackTrace();
0238: log(e.getMessage());
0239: }
0240:
0241: return newCasaDocument;
0242: }
0243:
0244: /**
0245: * Gets an Endpoint object from an endpoint element in CASA DOM.
0246: */
0247: private static Endpoint getEndpointInCASA(
0248: Element casaEndpointElement) {
0249: String endpointName = casaEndpointElement
0250: .getAttribute(CASA_ENDPOINT_NAME_ATTR_NAME);
0251: QName serviceQName = XmlUtil.getAttributeNSName(
0252: casaEndpointElement, CASA_SERVICE_NAME_ATTR_NAME);
0253: QName interfaceQName = XmlUtil.getAttributeNSName(
0254: casaEndpointElement, CASA_INTERFACE_NAME_ATTR_NAME);
0255:
0256: return new Endpoint(endpointName, serviceQName, interfaceQName);
0257: }
0258:
0259: /**
0260: * Gets the ID of the given endpoint in the CASA document.
0261: */
0262: private static String getEndpointID(Document casaDocument,
0263: Endpoint endpoint) {
0264: NodeList endpointNodeList = casaDocument
0265: .getElementsByTagName(CASA_ENDPOINT_ELEM_NAME);
0266:
0267: for (int i = 0; i < endpointNodeList.getLength(); i++) {
0268: Element endpointElement = (Element) endpointNodeList
0269: .item(i);
0270: Endpoint casaEndpoint = getEndpointInCASA(endpointElement);
0271: if (endpoint.equals(casaEndpoint)) {
0272: return endpointElement
0273: .getAttribute(CASA_NAME_ATTR_NAME);
0274: }
0275: }
0276:
0277: return null;
0278: }
0279:
0280: /**
0281: * Creates the SE/BC service-units element in the new casa document.
0282: */
0283: private Element createSUs(Document jbiDocument)
0284: throws SAXException, IOException,
0285: ParserConfigurationException {
0286:
0287: Element casaSUs = newCasaDocument
0288: .createElement(CASA_SERVICE_UNITS_ELEM_NAME);
0289:
0290: // 1. "Copy" SE and BC SUs from jbi document over
0291: List<String> componentIDs = new ArrayList<String>();
0292:
0293: if (jbiDocument == null) {
0294: return casaSUs;
0295: }
0296: NodeList jbiSUs = jbiDocument
0297: .getElementsByTagName(JBI_SERVICE_UNIT_ELEM_NAME);
0298: for (int i = 0; i < jbiSUs.getLength(); i++) {
0299: Element jbiSU = (Element) jbiSUs.item(i);
0300: String componentID = getJBIServiceUnitComponentName(jbiSU);
0301: componentIDs.add(componentID);
0302:
0303: Element casaSU = bcNamespace2NameMap.values().contains(
0304: componentID) ? createBCSUFromJbiElement(jbiSU)
0305: : createSESUFromJbiElement(jbiSU);
0306:
0307: if (casaSU != null) {
0308: casaSUs.appendChild(casaSU);
0309: }
0310: }
0311:
0312: if (oldCasaDocument != null) {
0313: // 2. Merge BC SUs from old casa that contains only unconnected
0314: // and/or deleted ports.
0315: NodeList bcSUs = oldCasaDocument
0316: .getElementsByTagName(CASA_BINDING_COMPONENT_SERVICE_UNIT_ELEM_NAME);
0317: for (int i = 0; i < bcSUs.getLength(); i++) {
0318: Element bcSU = (Element) bcSUs.item(i);
0319: String bcName = bcSU
0320: .getAttribute(CASA_COMPONENT_NAME_ATTR_NAME);
0321: if (!componentIDs.contains(bcName)) {
0322: Element casaSU = createBCSUFromCasaElement(bcSU);
0323: // Only add this BC SU if it still contains at least one
0324: // unconnected or deleted port.
0325: Element ports = (Element) casaSU
0326: .getElementsByTagName(CASA_PORTS_ELEM_NAME)
0327: .item(0);
0328: if (ports.getChildNodes().getLength() > 0) {
0329: casaSUs.appendChild(casaSU);
0330: }
0331: }
0332: }
0333:
0334: // 3. Merge external SE SUs from old casa
0335: try {
0336: List<Element> externalSESUs = getExternalSESUs();
0337: for (Element oldSESU : externalSESUs) {
0338: Node newSESU = deepCloneCasaNodeWithEndpointConversion(oldSESU);
0339: casaSUs.appendChild(newSESU);
0340: }
0341: } catch (Exception e) {
0342: log("ERROR: Problem merging external service units from old casa: "
0343: + e
0344: + ". This does not affect regular compapp build.");
0345: }
0346: }
0347:
0348: return casaSUs;
0349: }
0350:
0351: /**
0352: * Merge connection extension elements from the old CASA document.
0353: *
0354: * @param isConsumes is consumes endpoint or provides endpoint
0355: */
0356: private void mergeConnectionExtensions() {
0357: if (oldCasaDocument == null) {
0358: return;
0359: }
0360:
0361: NodeList oldConnections = oldCasaDocument
0362: .getElementsByTagName(CASA_CONNECTION_ELEM_NAME);
0363:
0364: for (int i = 0; i < oldConnections.getLength(); i++) {
0365: Element oldConnection = (Element) oldConnections.item(i);
0366: Element newConnection = findConnection(oldCasaDocument,
0367: oldConnection, newCasaDocument);
0368:
0369: // Copy child extension elements over from old CASA to new CASA
0370: if (newConnection != null) {
0371: deepCloneChildren(oldConnection, newConnection);
0372: }
0373: }
0374: }
0375:
0376: private static Element findConnection(Document oldCasaDocument,
0377: Element oldConnection, Document newCasaDocument) {
0378: Element ret = null;
0379:
0380: String oldConsumerEndpointID = oldConnection
0381: .getAttribute(CASA_CONSUMER_ATTR_NAME);
0382: Endpoint consumerEndpoint = getEndpoint(oldCasaDocument,
0383: oldConsumerEndpointID);
0384: String newConsumerEndpointID = getEndpointID(newCasaDocument,
0385: consumerEndpoint);
0386:
0387: String oldProviderEndpointID = oldConnection
0388: .getAttribute(CASA_PROVIDER_ATTR_NAME);
0389: Endpoint providerEndpoint = getEndpoint(oldCasaDocument,
0390: oldProviderEndpointID);
0391: String newProviderEndpointID = getEndpointID(newCasaDocument,
0392: providerEndpoint);
0393:
0394: NodeList newConnections = newCasaDocument
0395: .getElementsByTagName(CASA_CONNECTION_ELEM_NAME);
0396:
0397: for (int i = 0; i < newConnections.getLength(); i++) {
0398: Element newConnection = (Element) newConnections.item(i);
0399: if (newConnection.getAttribute(CASA_CONSUMER_ATTR_NAME)
0400: .equals(newConsumerEndpointID)
0401: && newConnection.getAttribute(
0402: CASA_PROVIDER_ATTR_NAME).equals(
0403: newProviderEndpointID)) {
0404: ret = newConnection;
0405: break;
0406: }
0407: }
0408:
0409: return ret;
0410: }
0411:
0412: /**
0413: * Merge binding component endpoint extension elements from the
0414: * old CASA document.
0415: *
0416: * @param isConsumes is consumes endpoint or provides endpoint
0417: */
0418: private void mergeBCEndpointExtensions(boolean isConsumes) {
0419: if (oldCasaDocument == null) {
0420: return;
0421: }
0422:
0423: NodeList oldBCSUs = oldCasaDocument
0424: .getElementsByTagName(CASA_BINDING_COMPONENT_SERVICE_UNIT_ELEM_NAME);
0425:
0426: for (int i = 0; i < oldBCSUs.getLength(); i++) {
0427: Element oldBCSU = (Element) oldBCSUs.item(i);
0428: NodeList oldEndpointRefs = oldBCSU
0429: .getElementsByTagName(isConsumes ? CASA_CONSUMES_ELEM_NAME
0430: : CASA_PROVIDES_ELEM_NAME);
0431:
0432: for (int j = 0; j < oldEndpointRefs.getLength(); j++) {
0433: Element oldEndpointRef = (Element) oldEndpointRefs
0434: .item(j);
0435: Element newEndpointRef = findEndpointRef(
0436: oldCasaDocument, oldEndpointRef,
0437: newCasaDocument, isConsumes);
0438:
0439: // Copy child extension elements over from old CASA to new CASA
0440: if (newEndpointRef != null) {
0441: deepCloneChildren(oldEndpointRef, newEndpointRef);
0442: }
0443: }
0444: }
0445: }
0446:
0447: private static Element findEndpointRef(Document oldCasaDocument,
0448: Element oldEndpointRef, Document newCasaDocument,
0449: boolean isConsumes) {
0450: Element newEndpointRef = null;
0451:
0452: String oldEndpointID = oldEndpointRef
0453: .getAttribute(CASA_ENDPOINT_ATTR_NAME);
0454: Endpoint endpoint = getEndpoint(oldCasaDocument, oldEndpointID);
0455: String newEndpointID = getEndpointID(newCasaDocument, endpoint);
0456:
0457: if (newEndpointID != null) {
0458: newEndpointRef = getEndpointRefElement(newCasaDocument,
0459: newEndpointID, false, isConsumes);
0460: }
0461:
0462: return newEndpointRef;
0463: }
0464:
0465: public static void deepCloneChildren(Element src, Element dest) {
0466: assert src != null && dest != null;
0467:
0468: Document destDocument = dest.getOwnerDocument();
0469:
0470: NodeList oldChildren = src.getChildNodes();
0471: for (int k = 0; k < oldChildren.getLength(); k++) {
0472: Node oldChild = oldChildren.item(k);
0473: if (oldChild instanceof Element) {
0474: Node clonedNode = deepCloneCasaNode(oldChild,
0475: destDocument);
0476: dest.appendChild(clonedNode);
0477: }
0478: }
0479: }
0480:
0481: /**
0482: * Gets the CASA endpoint reference element (consumes/provides) that
0483: * corresponds to the given endpoint object.
0484: *
0485: * @param casaDocument CASA document
0486: * @param endpoint an endpoint object
0487: * @param isSESU if <code>true</code>, the endpoint belongs to a
0488: * service engine service unit;
0489: * if <code>false</code>, the endpoint belongs to a
0490: * binging component service unit
0491: * @param isConsumes if <code>true</code>, the endpoint is a consumes,
0492: * if <code>false</code>, the endpoint is a provides.
0493: *
0494: * @return the consumes/provides element with the given ID.
0495: */
0496: static Element getEndpointRefElement(Document casaDocument,
0497: Endpoint endpoint, boolean isSESU, boolean isConsumes) {
0498:
0499: String endpointID = getEndpointID(casaDocument, endpoint);
0500: return getEndpointRefElement(casaDocument, endpointID, isSESU,
0501: isConsumes);
0502: }
0503:
0504: /**
0505: * Gets the CASA endpoint reference element (consumes/provides) with the
0506: * given enpoint ID.
0507: *
0508: * @param casaDocument CASA document
0509: * @param endpointID ID of an endpoint
0510: * @param isSESU if <code>true</code>, the endpoint belongs to a
0511: * service engine service unit;
0512: * if <code>false</code>, the endpoint belongs to a
0513: * binging component service unit
0514: * @param isConsumes if <code>true</code>, the endpoint is a consumes,
0515: * if <code>false</code>, the endpoint is a provides.
0516: *
0517: * @return the consumes/provides element with the given ID.
0518: */
0519: private static Element getEndpointRefElement(Document casaDocument,
0520: String endpointID, boolean isSESU, boolean isConsumes) {
0521:
0522: NodeList sus = casaDocument
0523: .getElementsByTagName(isSESU ? CASA_SERVICE_ENGINE_SERVICE_UNIT_ELEM_NAME
0524: : CASA_BINDING_COMPONENT_SERVICE_UNIT_ELEM_NAME);
0525:
0526: for (int i = 0; i < sus.getLength(); i++) {
0527:
0528: Element su = (Element) sus.item(i);
0529:
0530: NodeList endpointRefs = su
0531: .getElementsByTagName(isConsumes ? CASA_CONSUMES_ELEM_NAME
0532: : CASA_PROVIDES_ELEM_NAME);
0533:
0534: for (int j = 0; j < endpointRefs.getLength(); j++) {
0535: Element endpointRef = (Element) endpointRefs.item(j);
0536: if (endpointRef.getAttribute(CASA_ENDPOINT_ATTR_NAME)
0537: .equals(endpointID)) {
0538: return endpointRef;
0539: }
0540: }
0541: }
0542:
0543: return null;
0544: }
0545:
0546: private Element deepCloneCasaNodeWithEndpointConversion(
0547: Element oldElement) {
0548:
0549: Element newElement = (Element) deepCloneCasaNode(oldElement,
0550: newCasaDocument);
0551:
0552: NodeList oldConsumesNodeList = oldElement
0553: .getElementsByTagName(CASA_CONSUMES_ELEM_NAME);
0554: NodeList newConsumesNodeList = newElement
0555: .getElementsByTagName(CASA_CONSUMES_ELEM_NAME);
0556: for (int i = 0; i < oldConsumesNodeList.getLength(); i++) {
0557: Element oldConsumes = (Element) oldConsumesNodeList.item(i);
0558: Element newConsumes = (Element) newConsumesNodeList.item(i);
0559: fixEndpointRefElementID(oldConsumes, newConsumes);
0560: }
0561:
0562: NodeList oldProvidesNodeList = oldElement
0563: .getElementsByTagName(CASA_PROVIDES_ELEM_NAME);
0564: NodeList newProvidesNodeList = newElement
0565: .getElementsByTagName(CASA_PROVIDES_ELEM_NAME);
0566: for (int i = 0; i < oldProvidesNodeList.getLength(); i++) {
0567: Element oldProvides = (Element) oldProvidesNodeList.item(i);
0568: Element newProvides = (Element) newProvidesNodeList.item(i);
0569: fixEndpointRefElementID(oldProvides, newProvides);
0570: }
0571:
0572: return newElement;
0573: }
0574:
0575: /**
0576: * Fixes the ID attribute of an endpoint reference element
0577: * (consumes/provides) in the new CASA document so that both the
0578: * endpoint referebce element in the new CASA document and the
0579: * endpoint reference element in the old CASA document refer to
0580: * the same fully-qualified endpoint.
0581: *
0582: * @param oldEndpoint an endpoint reference element in the old CASA document
0583: * @param newEndpoint an endpoint reference element in the new CASA document
0584: */
0585: private void fixEndpointRefElementID(Element oldEndpointRef,
0586: Element newEndpointRef) {
0587: String oldEndpointID = oldEndpointRef
0588: .getAttribute(CASA_ENDPOINT_ATTR_NAME);
0589: Endpoint endpoint = getEndpoint(oldCasaDocument, oldEndpointID);
0590: String newEndpointID = addEndpoint(endpoint);
0591: newEndpointRef.setAttribute(CASA_ENDPOINT_ATTR_NAME,
0592: newEndpointID);
0593: }
0594:
0595: /**
0596: * Creates a BC SU element in the new casa document from a BC SU element
0597: * in the jbi document.
0598: */
0599: private Element createBCSUFromJbiElement(Element jbiSU)
0600: throws SAXException, IOException,
0601: ParserConfigurationException {
0602:
0603: Element bcSU = newCasaDocument
0604: .createElement(CASA_BINDING_COMPONENT_SERVICE_UNIT_ELEM_NAME);
0605: String suName = getJBIServiceUnitName(jbiSU);
0606:
0607: Element identification = (Element) jbiSU.getElementsByTagName(
0608: JBI_IDENTIFICATION_ELEM_NAME).item(0);
0609: String name = ((Element) identification.getElementsByTagName(
0610: JBI_NAME_ELEM_NAME).item(0)).getFirstChild()
0611: .getNodeValue();
0612: String description = ((Element) identification
0613: .getElementsByTagName(JBI_DESCRIPTION_ELEM_NAME)
0614: .item(0)).getFirstChild().getNodeValue();
0615:
0616: Element target = (Element) jbiSU.getElementsByTagName(
0617: JBI_TARGET_ELEM_NAME).item(0);
0618: String componentName = ((Element) target.getElementsByTagName(
0619: JBI_COMPONENT_NAME_ELEM_NAME).item(0)).getFirstChild()
0620: .getNodeValue();
0621: String artifactsZip = ((Element) target.getElementsByTagName(
0622: JBI_ARTIFACTS_ZIP_ELEM_NAME).item(0)).getFirstChild()
0623: .getNodeValue();
0624:
0625: bcSU.setAttribute(CASA_NAME_ATTR_NAME, name);
0626: bcSU.setAttribute(CASA_UNIT_NAME_ATTR_NAME, suName);
0627: bcSU.setAttribute(CASA_COMPONENT_NAME_ATTR_NAME, componentName);
0628: bcSU.setAttribute(CASA_DESCRIPTION_ATTR_NAME, description);
0629: bcSU.setAttribute(CASA_ARTIFACTS_ZIP_ATTR_NAME, artifactsZip);
0630:
0631: Element casaPorts = createPorts(suName);
0632: bcSU.appendChild(casaPorts);
0633:
0634: return bcSU;
0635: }
0636:
0637: /**
0638: * Creates a BC SU element in the new casa document from a BC SU element
0639: * in the old casa document.
0640: */
0641: private Element createBCSUFromCasaElement(Element casaBCSU)
0642: throws SAXException, IOException,
0643: ParserConfigurationException {
0644:
0645: Element ret = newCasaDocument
0646: .createElement(CASA_BINDING_COMPONENT_SERVICE_UNIT_ELEM_NAME);
0647:
0648: NamedNodeMap attrs = casaBCSU.getAttributes();
0649: for (int i = 0; i < attrs.getLength(); i++) {
0650: Node attrNode = attrs.item(i);
0651: String name = attrNode.getNodeName();
0652: String value = attrNode.getNodeValue();
0653: ret.setAttribute(name, value); // no namespace requirement here
0654: }
0655:
0656: String suName = ret.getAttribute(CASA_COMPONENT_NAME_ATTR_NAME);
0657: Element casaPorts = createPorts(suName);
0658: ret.appendChild(casaPorts);
0659:
0660: return ret;
0661: }
0662:
0663: /**
0664: * Creates a SE SU element in the new casa document from a SE SU element
0665: * in the jbi document.
0666: */
0667: private Element createSESUFromJbiElement(Element jbiSU)
0668: throws SAXException, IOException,
0669: ParserConfigurationException {
0670:
0671: Element seSU = newCasaDocument
0672: .createElement(CASA_SERVICE_ENGINE_SERVICE_UNIT_ELEM_NAME);
0673: String suName = getJBIServiceUnitName(jbiSU);
0674:
0675: List<Endpoint> suEndpointList = su2Endpoints.get(suName);
0676: // if (suEndpointList == null) {
0677: // log("ERROR: Invalid service unit name in service assembly jbi.xml: " + suName);
0678: // return null;
0679: // }
0680:
0681: // if (suEndpointList.size() == 0) {
0682: // // This is OK. It's possible that a SU doesn't contain any endpoints,
0683: // // for example, an empty BPEL SU.
0684: // }
0685:
0686: Element identification = (Element) jbiSU.getElementsByTagName(
0687: JBI_IDENTIFICATION_ELEM_NAME).item(0);
0688: String name = ((Element) identification.getElementsByTagName(
0689: JBI_NAME_ELEM_NAME).item(0)).getFirstChild()
0690: .getNodeValue();
0691: Node descriptionChildNode = ((Element) identification
0692: .getElementsByTagName(JBI_DESCRIPTION_ELEM_NAME)
0693: .item(0)).getFirstChild();
0694: String description = descriptionChildNode == null ? ""
0695: : descriptionChildNode.getNodeValue();
0696:
0697: Element target = (Element) jbiSU.getElementsByTagName(
0698: JBI_TARGET_ELEM_NAME).item(0);
0699: String componentName = ((Element) target.getElementsByTagName(
0700: JBI_COMPONENT_NAME_ELEM_NAME).item(0)).getFirstChild()
0701: .getNodeValue();
0702: String artifactsZip = ((Element) target.getElementsByTagName(
0703: JBI_ARTIFACTS_ZIP_ELEM_NAME).item(0)).getFirstChild()
0704: .getNodeValue();
0705:
0706: seSU.setAttribute(CASA_X_ATTR_NAME, "-1");
0707: seSU.setAttribute(CASA_Y_ATTR_NAME, "-1");
0708:
0709: seSU.setAttribute(CASA_INTERNAL_ATTR_NAME, "true");
0710: seSU.setAttribute(CASA_DEFINED_ATTR_NAME, "true");
0711: seSU.setAttribute(CASA_UNKNOWN_ATTR_NAME, "false");
0712: seSU.setAttribute(CASA_NAME_ATTR_NAME, name);
0713: seSU.setAttribute(CASA_UNIT_NAME_ATTR_NAME, suName);
0714: seSU.setAttribute(CASA_COMPONENT_NAME_ATTR_NAME, componentName);
0715: seSU.setAttribute(CASA_DESCRIPTION_ATTR_NAME, description);
0716: seSU.setAttribute(CASA_ARTIFACTS_ZIP_ATTR_NAME, artifactsZip);
0717:
0718: if (suEndpointList != null) {
0719: for (Endpoint endpoint : suEndpointList) {
0720: Element endpointRef = endpoint.isConsumes() ? (Element) newCasaDocument
0721: .createElement(CASA_CONSUMES_ELEM_NAME)
0722: : (Element) newCasaDocument
0723: .createElement(CASA_PROVIDES_ELEM_NAME);
0724: String endpointID = getNewEndpointID(endpoint);
0725: endpointRef.setAttribute(CASA_ENDPOINT_ATTR_NAME,
0726: endpointID);
0727: seSU.appendChild(endpointRef);
0728: }
0729: }
0730: return seSU;
0731: }
0732:
0733: /**
0734: * Creates the Connections element in the new casa document.
0735: */
0736: private Element createConnections(Document jbiDocument) {
0737:
0738: Element casaConnections = newCasaDocument
0739: .createElement(CASA_CONNECTIONS_ELEM_NAME);
0740:
0741: if (jbiDocument == null) {
0742: return casaConnections;
0743: }
0744:
0745: // 1. Copy jbi:connections from jbi document over.
0746: NodeList jbiConnections = jbiDocument.getElementsByTagNameNS(
0747: JBI_NAMESPACE_URI, JBI_CONNECTION_ELEM_NAME);
0748:
0749: for (int i = 0; i < jbiConnections.getLength(); i++) {
0750: Element jbiConnection = (Element) jbiConnections.item(i);
0751:
0752: Element consumer = (Element) jbiConnection
0753: .getElementsByTagName(JBI_CONSUMER_ELEM_NAME).item(
0754: 0);
0755: String consumerEndpointName = consumer
0756: .getAttribute(JBI_ENDPOINT_NAME_ATTR_NAME);
0757: QName consumerServiceQName = XmlUtil.getAttributeNSName(
0758: consumer, JBI_SERVICE_NAME_ATTR_NAME);
0759: String consumerID = getNewEndpointID(consumerServiceQName,
0760: consumerEndpointName);
0761: if (consumerID == null || consumerID.trim().length() == 0) {
0762: continue; // the consumes endpoint no longer exists in compapp
0763: // This could happen when a JBI module is deleted outside of
0764: // CASA, in which case, the SE SU is removed from CASA model
0765: // but all the connections are left untouched. A second build
0766: // of compapp still sees the connections which are no longer
0767: // valid. A clean and build should have no problem though.
0768: }
0769:
0770: Element provider = (Element) jbiConnection
0771: .getElementsByTagName(JBI_PROVIDER_ELEM_NAME).item(
0772: 0);
0773: String providerEndpointName = provider
0774: .getAttribute(JBI_ENDPOINT_NAME_ATTR_NAME);
0775: QName providerServiceQName = XmlUtil.getAttributeNSName(
0776: provider, JBI_SERVICE_NAME_ATTR_NAME);
0777: String providerID = getNewEndpointID(providerServiceQName,
0778: providerEndpointName);
0779: if (providerID == null || providerID.trim().length() == 0) {
0780: continue; // the provides endpoint no longer exists in compapp
0781: }
0782:
0783: Element casaConnection = newCasaDocument
0784: .createElement(CASA_CONNECTION_ELEM_NAME);
0785: casaConnection.setAttribute(CASA_STATE_ATTR_NAME,
0786: CASA_UNCHANGED_ATTR_VALUE);
0787: casaConnection.setAttribute(CASA_CONSUMER_ATTR_NAME,
0788: consumerID);
0789: casaConnection.setAttribute(CASA_PROVIDER_ATTR_NAME,
0790: providerID);
0791: casaConnections.appendChild(casaConnection);
0792: }
0793:
0794: // 2. Mark user created connection as "new";
0795: // Merge deleted connections from the old casa document.
0796: if (oldCasaDocument != null) {
0797: try {
0798: NodeList oldConnectionList = oldCasaDocument
0799: .getElementsByTagName(CASA_CONNECTION_ELEM_NAME);
0800:
0801: for (int i = oldConnectionList.getLength() - 1; i >= 0; i--) {
0802: Element oldConnection = (Element) oldConnectionList
0803: .item(i);
0804: String oldConnectionState = oldConnection
0805: .getAttribute(CASA_STATE_ATTR_NAME);
0806: if (oldConnectionState
0807: .equals(CASA_DELETED_ATTR_VALUE)
0808: || oldConnectionState
0809: .equals(CASA_NEW_ATTR_VALUE)) {
0810: String newConsumerID = findNewEndpointID(
0811: oldCasaDocument, newCasaDocument,
0812: oldConnection, true);
0813: if (newConsumerID == null
0814: || newConsumerID.trim().length() == 0) {
0815: continue; // the consumes endpoint no longer exists in compapp
0816: }
0817:
0818: String newProviderID = findNewEndpointID(
0819: oldCasaDocument, newCasaDocument,
0820: oldConnection, false);
0821: if (newProviderID == null
0822: || newProviderID.trim().length() == 0) {
0823: continue; // the provides endpoint no longer exists in compapp
0824: }
0825:
0826: Element newConnection = findConnection(
0827: casaConnections, newConsumerID,
0828: newProviderID);
0829:
0830: if (oldConnectionState
0831: .equals(CASA_DELETED_ATTR_VALUE)) {
0832: // Merge deleted connections from the old casa document
0833: assert newConnection == null;
0834: // Add deleted casa connection
0835: newConnection = newCasaDocument
0836: .createElement(CASA_CONNECTION_ELEM_NAME);
0837: newConnection.setAttribute(
0838: CASA_CONSUMER_ATTR_NAME,
0839: newConsumerID);
0840: newConnection.setAttribute(
0841: CASA_PROVIDER_ATTR_NAME,
0842: newProviderID);
0843: newConnection.setAttribute(
0844: CASA_STATE_ATTR_NAME,
0845: CASA_DELETED_ATTR_VALUE);
0846: casaConnections.appendChild(newConnection);
0847: } else {
0848: // Mark user created connection as "new"
0849: newConnection.setAttribute(
0850: CASA_STATE_ATTR_NAME,
0851: CASA_NEW_ATTR_VALUE);
0852: }
0853: }
0854: }
0855: } catch (Exception e) {
0856: log("ERROR: Problem merging deleted/new connections from old casa: "
0857: + e
0858: + ". This does not affect regular compapp build.");
0859: }
0860: }
0861:
0862: return casaConnections;
0863: }
0864:
0865: private List<Element> createWSDLReferenceElements() {
0866:
0867: List<Element> ret = new ArrayList<Element>();
0868:
0869: Element casaPortTypes = newCasaDocument
0870: .createElement(CASA_PORTTYPES_ELEM_NAME);
0871: Element casaBindings = newCasaDocument
0872: .createElement(CASA_BINDINGS_ELEM_NAME);
0873: Element casaServices = newCasaDocument
0874: .createElement(CASA_SERVICES_ELEM_NAME);
0875:
0876: for (WSDLModel model : wsdlRepository.getWsdlCollection()) {
0877: String relativePath = MyFileUtil.getRelativePath(new File(
0878: confDirLoc), getFile(model));
0879:
0880: Definitions defs = model.getDefinitions();
0881:
0882: // Add casa:porttypes
0883: for (PortType pt : defs.getPortTypes()) {
0884: String ptName = pt.getName();
0885: Element linkElement = createLink(relativePath,
0886: "/definitions/portType" + "[@name='" + ptName
0887: + "']");
0888: casaPortTypes.appendChild(linkElement);
0889: }
0890:
0891: // Add casa:bindings
0892: for (Binding b : defs.getBindings()) {
0893: String bName = b.getName();
0894: Element linkElement = createLink(relativePath,
0895: "/definitions/binding" + "[@name='" + bName
0896: + "']");
0897: casaBindings.appendChild(linkElement);
0898: }
0899:
0900: // Add casa:services
0901: for (Service s : defs.getServices()) {
0902: String sName = s.getName();
0903: Element linkElement = createLink(relativePath,
0904: "/definitions/service" + "[@name='" + sName
0905: + "']");
0906: casaServices.appendChild(linkElement);
0907: }
0908: }
0909:
0910: ret.add(casaPortTypes);
0911: ret.add(casaBindings);
0912: ret.add(casaServices);
0913:
0914: return ret;
0915: }
0916:
0917: /**
0918: * Creates the Regions element in the new casa document.
0919: */
0920: private Element createRegions() {
0921:
0922: if (oldCasaDocument != null) {
0923: try {
0924: Element oldRegions = (Element) oldCasaDocument
0925: .getElementsByTagName(CASA_REGIONS_ELEM_NAME)
0926: .item(0);
0927: return (Element) deepCloneCasaNode(oldRegions,
0928: newCasaDocument);
0929: } catch (Exception e) {
0930: log("ERROR: Problem merging regsions from old casa: "
0931: + e
0932: + ". This does not affect regular compapp build.");
0933: }
0934: }
0935:
0936: Element regions = newCasaDocument
0937: .createElement(CASA_REGIONS_ELEM_NAME);
0938:
0939: Element region = newCasaDocument
0940: .createElement(CASA_REGION_ELEM_NAME);
0941: region.setAttribute(CASA_NAME_ATTR_NAME,
0942: WSDL_ENDPOINTS_REGION_NAME);
0943: region.setAttribute(CASA_WIDTH_ATTR_NAME,
0944: DEFAULT_WSDL_ENDPOINTS_REGION_WIDTH);
0945: regions.appendChild(region);
0946:
0947: region = newCasaDocument.createElement(CASA_REGION_ELEM_NAME);
0948: region.setAttribute(CASA_NAME_ATTR_NAME,
0949: JBI_MODULES_REGION_NAME);
0950: region.setAttribute(CASA_WIDTH_ATTR_NAME,
0951: DEFAULT_JBI_MODULES_REGION_WIDTH);
0952: regions.appendChild(region);
0953:
0954: region = newCasaDocument.createElement(CASA_REGION_ELEM_NAME);
0955: region.setAttribute(CASA_NAME_ATTR_NAME,
0956: EXTERNAL_MODULES_REGION_NAME);
0957: region.setAttribute(CASA_WIDTH_ATTR_NAME,
0958: DEFAULT_EXTERNAL_MODULES_REGION_WIDTH);
0959:
0960: regions.appendChild(region);
0961:
0962: return regions;
0963: }
0964:
0965: private String getJBIServiceUnitComponentName(Element jbiSU) {
0966: Element target = (Element) jbiSU.getElementsByTagName(
0967: JBI_TARGET_ELEM_NAME).item(0);
0968: Element compName = (Element) target.getElementsByTagName(
0969: JBI_COMPONENT_NAME_ELEM_NAME).item(0);
0970: return compName.getTextContent();
0971: }
0972:
0973: private String getJBIServiceUnitName(Element jbiSU) {
0974: // We can not derive the SU name (w/o the compapp name prefix) from
0975: // the jar name. We can derive it from the SU identification name.
0976: // See JbiProjectProperties.generateServiceUnitElement().
0977: /*
0978: Element target = (Element) jbiSU.getElementsByTagName(JBI_TARGET_ELEM_NAME).item(0);
0979: Element artifactsZip = (Element) target.getElementsByTagName(JBI_ARTIFACTS_ZIP_ELEM_NAME).item(0);
0980: String zipFileName = artifactsZip.getFirstChild().getNodeValue();
0981: // Java EE application can have extension '.war' and '.ear'
0982: //assert zipFileName.endsWith(".jar");
0983: return zipFileName.substring(0, zipFileName.length() - 4);
0984: */
0985:
0986: Element suID = (Element) jbiSU.getElementsByTagName(
0987: JBI_IDENTIFICATION_ELEM_NAME).item(0);
0988: Element suName = (Element) suID.getElementsByTagName(
0989: JBI_NAME_ELEM_NAME).item(0);
0990: String compApp_SuName = suName.getTextContent();
0991:
0992: Element jbiSA = (Element) jbiSU.getParentNode();
0993: Element saID = (Element) jbiSA.getElementsByTagName(
0994: JBI_IDENTIFICATION_ELEM_NAME).item(0);
0995: Element saName = (Element) saID.getElementsByTagName(
0996: JBI_NAME_ELEM_NAME).item(0);
0997: String compAppName = saName.getTextContent();
0998:
0999: // Strip the compAppName and '-' from compApp_SuName
1000: return compApp_SuName.substring(compAppName.length() + 1);
1001: }
1002:
1003: private static File getFile(WSDLModel model) {
1004: Lookup lookup = model.getModelSource().getLookup();
1005: File f = lookup.lookup(File.class);
1006: if (f == null) {
1007: FileObject fo = lookup.lookup(FileObject.class);
1008: f = FileUtil.toFile(fo);
1009: }
1010: return f;
1011: }
1012:
1013: // private List<String> getDeletedBCSUs() {
1014: // List<String> ret = new ArrayList<String>();
1015: //
1016: // if (oldCasaDocument != null) {
1017: // NodeList bcsuNodeList =
1018: // oldCasaDocument.getElementsByTagName(CASA_BINDING_COMPONENT_SERVICE_UNIT_ELEM_NAME);
1019: //
1020: // for (int i = 0; i < bcsuNodeList.getLength(); i++) {
1021: // Element bcSU = (Element) bcsuNodeList.item(i);
1022: // String bcName = bcSU.getAttribute(CASA_COMPONENT_NAME_ATTR_NAME);
1023: //
1024: // NodeList portNodeList = bcSU.getElementsByTagName(CASA_PORT_ELEM_NAME);
1025: // for (int j = 0; j < portNodeList.getLength(); j++) {
1026: // Element port = (Element) portNodeList.item(j);
1027: // String state = port.getAttribute(CASA_STATE_ATTR_NAME);
1028: // if (CASA_DELETED_ATTR_VALUE.equals(state)) {
1029: //
1030: // }
1031: // }
1032: // }
1033: // }
1034: //
1035: // return ret;
1036: // }
1037: private Map<String, List<Endpoint>> getDeletedBCEndpointsMap() {
1038:
1039: if (deletedBCEndpointsMap == null) {
1040: deletedBCEndpointsMap = new HashMap<String, List<Endpoint>>();
1041:
1042: if (oldCasaDocument != null) {
1043: NodeList portNodeList = oldCasaDocument
1044: .getElementsByTagName(CASA_PORT_ELEM_NAME);
1045:
1046: for (int i = 0; i < portNodeList.getLength(); i++) {
1047: Element port = (Element) portNodeList.item(i);
1048: String state = port
1049: .getAttribute(CASA_STATE_ATTR_NAME);
1050: if (CASA_DELETED_ATTR_VALUE.equals(state)) {
1051: // assume both Consumes and Provides coexist and give
1052: // the same endpoint info
1053: NodeList consumesNodeList = port
1054: .getElementsByTagName(CASA_CONSUMES_ELEM_NAME);
1055: if (consumesNodeList != null
1056: && consumesNodeList.getLength() == 1) {
1057: Element consumes = (Element) consumesNodeList
1058: .item(0);
1059: String endpointID = consumes
1060: .getAttribute(CASA_ENDPOINT_ATTR_NAME);
1061: Endpoint endpoint = getEndpoint(
1062: oldCasaDocument, endpointID);
1063:
1064: // build deltedBCEndpointsMap
1065: Element bcsuElement = (Element) port
1066: .getParentNode().getParentNode();
1067: String bcName = bcsuElement
1068: .getAttribute(CASA_COMPONENT_NAME_ATTR_NAME);
1069: List<Endpoint> deletedBCEndpoints = deletedBCEndpointsMap
1070: .get(bcName);
1071: if (deletedBCEndpoints == null) {
1072: deletedBCEndpoints = new ArrayList<Endpoint>();
1073: deletedBCEndpointsMap.put(bcName,
1074: deletedBCEndpoints);
1075: }
1076: deletedBCEndpoints.add(endpoint);
1077: }
1078: }
1079: }
1080: }
1081: }
1082:
1083: return deletedBCEndpointsMap;
1084: }
1085:
1086: private Map<String, List<Endpoint>> getUnconnectedBCEndpointsMap() {
1087:
1088: Map<String, List<Endpoint>> endpointMap = new HashMap<String, List<Endpoint>>();
1089:
1090: if (oldCasaDocument != null) {
1091: // compute the list of connected endpoint IDs in the old casa
1092: List<String> connectedEndpointIDs = new ArrayList<String>();
1093: NodeList connectionNodeList = oldCasaDocument
1094: .getElementsByTagName(CASA_CONNECTION_ELEM_NAME);
1095: for (int i = 0; i < connectionNodeList.getLength(); i++) {
1096: Element connection = (Element) connectionNodeList
1097: .item(i);
1098: String state = connection
1099: .getAttribute(CASA_STATE_ATTR_NAME);
1100: if (!state.equals(CASA_DELETED_ATTR_VALUE)) {
1101: connectedEndpointIDs.add(connection
1102: .getAttribute(CASA_CONSUMER_ATTR_NAME));
1103: connectedEndpointIDs.add(connection
1104: .getAttribute(CASA_PROVIDER_ATTR_NAME));
1105: }
1106: }
1107:
1108: NodeList portNodeList = oldCasaDocument
1109: .getElementsByTagName(CASA_PORT_ELEM_NAME);
1110:
1111: List<Endpoint> endpointList = new ArrayList<Endpoint>();
1112: NodeList endpointNodeList = oldCasaDocument
1113: .getElementsByTagName(CASA_ENDPOINT_ELEM_NAME);
1114: for (int i = 0; i < endpointNodeList.getLength(); i++) {
1115: Element endpointElement = (Element) endpointNodeList
1116: .item(i);
1117: String endpointID = endpointElement
1118: .getAttribute(CASA_NAME_ATTR_NAME);
1119: if (!connectedEndpointIDs.contains(endpointID)) {
1120: // this is an unconnected SE/BC endpoint
1121: for (int j = 0; j < portNodeList.getLength(); j++) {
1122: Element portElement = (Element) portNodeList
1123: .item(j);
1124: String id = getCasaPortEndpointID(portElement);
1125: if (id.equals(endpointID)) {
1126: // this is an unconnected BC endpoint
1127: Element bcsuElement = (Element) portElement
1128: .getParentNode().getParentNode();
1129: String componentName = bcsuElement
1130: .getAttribute(CASA_COMPONENT_NAME_ATTR_NAME);
1131: List<Endpoint> list = endpointMap
1132: .get(componentName);
1133: if (list == null) {
1134: list = new ArrayList<Endpoint>();
1135: endpointMap.put(componentName, list);
1136: }
1137:
1138: Endpoint endpoint = getEndpointInCASA(endpointElement);
1139: list.add(endpoint);
1140: break;
1141: }
1142: }
1143: }
1144: }
1145: }
1146:
1147: return endpointMap;
1148: }
1149:
1150: private String getCasaPortEndpointID(Element portElement) {
1151: NodeList consumesNodeList = portElement
1152: .getElementsByTagName(CASA_CONSUMES_ELEM_NAME);
1153: if (consumesNodeList != null
1154: && consumesNodeList.getLength() == 1) {
1155: Element consumes = (Element) consumesNodeList.item(0);
1156: return consumes.getAttribute(CASA_ENDPOINT_ATTR_NAME);
1157: } else {
1158: return null;
1159: }
1160: }
1161:
1162: /**
1163: * Gets a non-null list of external SE SU elements in the old casa document.
1164: */
1165: private List<Element> getExternalSESUs() {
1166: List<Element> ret = new ArrayList<Element>();
1167:
1168: if (oldCasaDocument != null) {
1169: NodeList oldCasaSUs = oldCasaDocument
1170: .getElementsByTagName(CASA_SERVICE_ENGINE_SERVICE_UNIT_ELEM_NAME);
1171: for (int i = 0; i < oldCasaSUs.getLength(); i++) {
1172: Element oldCasaSU = (Element) oldCasaSUs.item(i);
1173: String type = oldCasaSU
1174: .getAttribute(CASA_INTERNAL_ATTR_NAME);
1175: if (type != null && type.equals("false")) {
1176: ret.add(oldCasaSU);
1177: }
1178: }
1179: }
1180:
1181: return ret;
1182: }
1183:
1184: /**
1185: * Gets a non-null list of endpoints from the old CASA document.
1186: * (The external endpoints in the new CASA document will always be the same.)
1187: */
1188: private List<Endpoint> getExternalEndpoints() {
1189: if (externalEndpoints == null) {
1190: externalEndpoints = new ArrayList<Endpoint>();
1191:
1192: for (Element sesu : getExternalSESUs()) {
1193: NodeList consumesNodeList = sesu
1194: .getElementsByTagName(CASA_CONSUMES_ELEM_NAME);
1195: for (int j = 0; j < consumesNodeList.getLength(); j++) {
1196: Element consumes = (Element) consumesNodeList
1197: .item(j);
1198: String endpointID = consumes
1199: .getAttribute(CASA_ENDPOINT_ATTR_NAME);
1200: Endpoint endpoint = getEndpoint(oldCasaDocument,
1201: endpointID);
1202: externalEndpoints.add(endpoint);
1203: }
1204: NodeList providesNodeList = sesu
1205: .getElementsByTagName(CASA_PROVIDES_ELEM_NAME);
1206: for (int j = 0; j < providesNodeList.getLength(); j++) {
1207: Element provides = (Element) providesNodeList
1208: .item(j);
1209: String endpointID = provides
1210: .getAttribute(CASA_ENDPOINT_ATTR_NAME);
1211: Endpoint endpoint = getEndpoint(oldCasaDocument,
1212: endpointID);
1213: externalEndpoints.add(endpoint);
1214: }
1215: }
1216: }
1217:
1218: return externalEndpoints;
1219: }
1220:
1221: private void mergeLocations() {
1222:
1223: if (oldCasaDocument == null) {
1224: return;
1225: }
1226:
1227: // 1. Merge SE SU locations
1228: NodeList oldSESUs = oldCasaDocument
1229: .getElementsByTagName(CASA_SERVICE_ENGINE_SERVICE_UNIT_ELEM_NAME);
1230: NodeList newSESUs = newCasaDocument
1231: .getElementsByTagName(CASA_SERVICE_ENGINE_SERVICE_UNIT_ELEM_NAME);
1232:
1233: for (int i = 0; i < oldSESUs.getLength(); i++) {
1234: Element oldSESU = (Element) oldSESUs.item(i);
1235: // CASA_UNIT_NAME_ATTR_NAME uniquely identifies a SE/BC SU.
1236: String oldSESUName = oldSESU
1237: .getAttribute(CASA_UNIT_NAME_ATTR_NAME);
1238: for (int j = 0; j < newSESUs.getLength(); j++) {
1239: Element newSESU = (Element) newSESUs.item(j);
1240: String newSESUName = newSESU
1241: .getAttribute(CASA_UNIT_NAME_ATTR_NAME);
1242: if (newSESUName.equals(oldSESUName)) {
1243: newSESU.setAttribute(CASA_X_ATTR_NAME, oldSESU
1244: .getAttribute(CASA_X_ATTR_NAME));
1245: newSESU.setAttribute(CASA_Y_ATTR_NAME, oldSESU
1246: .getAttribute(CASA_Y_ATTR_NAME));
1247: break;
1248: }
1249: }
1250: }
1251:
1252: // 2. Merge BC SU port locations and other attributes
1253: NodeList oldPorts = oldCasaDocument
1254: .getElementsByTagName(CASA_PORT_ELEM_NAME);
1255: NodeList newPorts = newCasaDocument
1256: .getElementsByTagName(CASA_PORT_ELEM_NAME);
1257:
1258: for (int i = 0; i < oldPorts.getLength(); i++) {
1259: Element oldPort = (Element) oldPorts.item(i);
1260: Element newPort = findLinkContainerElement(newPorts,
1261: oldPort);
1262: if (newPort != null) {
1263: newPort.setAttribute(CASA_X_ATTR_NAME, oldPort
1264: .getAttribute(CASA_X_ATTR_NAME));
1265: newPort.setAttribute(CASA_Y_ATTR_NAME, oldPort
1266: .getAttribute(CASA_Y_ATTR_NAME));
1267: String bindingType = oldPort
1268: .getAttribute(CASA_BINDING_TYPE_ATTR_NAME);
1269: if (bindingType != null
1270: && bindingType.trim().length() > 0) {
1271: newPort.setAttribute(CASA_BINDING_TYPE_ATTR_NAME,
1272: bindingType);
1273: }
1274: }
1275: }
1276: }
1277:
1278: private static Element getCasaEndpointElement(
1279: Document casaDocument, String endpointID) {
1280: NodeList endpoints = casaDocument
1281: .getElementsByTagName(CASA_ENDPOINT_ELEM_NAME);
1282: for (int i = 0; i < endpoints.getLength(); i++) {
1283: Element endpoint = (Element) endpoints.item(i);
1284: if (endpoint.getAttribute(CASA_NAME_ATTR_NAME).equals(
1285: endpointID)) {
1286: return endpoint;
1287: }
1288: }
1289: return null;
1290: }
1291:
1292: private String findNewEndpointID(Document oldCasaDocument,
1293: Document newCasaDocument, Element oldConnection,
1294: boolean isConsumes) {
1295: String oldEndpointID = isConsumes ? oldConnection
1296: .getAttribute(CASA_CONSUMER_ATTR_NAME) : oldConnection
1297: .getAttribute(CASA_PROVIDER_ATTR_NAME);
1298:
1299: Element oldEndpoint = getCasaEndpointElement(oldCasaDocument,
1300: oldEndpointID);
1301: if (oldEndpoint != null) {
1302: String oldEndpointName = oldEndpoint
1303: .getAttribute(CASA_ENDPOINT_NAME_ATTR_NAME);
1304: QName oldServiceQName = XmlUtil.getAttributeNSName(
1305: oldEndpoint, CASA_SERVICE_NAME_ATTR_NAME);
1306: return getNewEndpointID(oldServiceQName, oldEndpointName);
1307: }
1308:
1309: return null;
1310: }
1311:
1312: private Element findConnection(Element connections,
1313: String consumerID, String providerID) {
1314:
1315: NodeList connectionsNodeList = connections
1316: .getElementsByTagName(CASA_CONNECTION_ELEM_NAME);
1317: for (int i = 0; i < connectionsNodeList.getLength(); i++) {
1318: Element connection = (Element) connectionsNodeList.item(i);
1319: if (connection.getAttribute(CASA_CONSUMER_ATTR_NAME)
1320: .equals(consumerID)
1321: && connection.getAttribute(CASA_PROVIDER_ATTR_NAME)
1322: .equals(providerID)) {
1323: return connection;
1324: }
1325: }
1326:
1327: return null;
1328: }
1329:
1330: // REFACTOR ME
1331: static Node deepCloneCasaNode(final Node node,
1332: final Document targetDocument) throws DOMException {
1333: String nodeName = node.getNodeName();
1334:
1335: Node clonedNode = null;
1336:
1337: if (node instanceof Element) {
1338: clonedNode = targetDocument.createElement(nodeName);
1339:
1340: NamedNodeMap attrs = node.getAttributes();
1341: for (int i = 0; i < attrs.getLength(); i++) {
1342: Node attrNode = attrs.item(i);
1343: String attrName = attrNode.getNodeName();
1344: String attrValue = attrNode.getNodeValue();
1345:
1346: if (!attrName.equals("xmlns")
1347: && attrValue.indexOf(":") != -1) {
1348: String oldValuePrefix = attrValue.substring(0,
1349: attrValue.indexOf(":"));
1350: String oldNamespaceURI = XmlUtil.getNamespaceURI(
1351: (Element) node, oldValuePrefix); // REFACTOR ME
1352:
1353: // We don't really know if the attr value is a QName or not.
1354: if (!oldNamespaceURI.equals("")) {
1355: // Add the namespace definition to the cloned node.
1356: ((Element) clonedNode).setAttribute("xmlns:"
1357: + oldValuePrefix, oldNamespaceURI);
1358: }
1359: }
1360:
1361: ((Element) clonedNode)
1362: .setAttribute(attrName, attrValue);
1363: }
1364:
1365: NodeList children = node.getChildNodes();
1366: for (int i = 0; i < children.getLength(); i++) {
1367: Node child = children.item(i);
1368: Node clonedChild = deepCloneCasaNode(child,
1369: targetDocument);
1370: clonedNode.appendChild(clonedChild);
1371: }
1372: } else if (node instanceof Text) {
1373: clonedNode = targetDocument.createTextNode(((Text) node)
1374: .getWholeText());
1375: } else {
1376: assert false : "deep clone node of type "
1377: + node.getClass().getName()
1378: + " is not implemented yet.";
1379: }
1380:
1381: return clonedNode;
1382: }
1383:
1384: // TODO
1385: /**
1386: * Finds a link container element from a list of link container elements.
1387: */
1388: private Element findLinkContainerElement(NodeList newPortNodeList,
1389: Element oldPort) {
1390:
1391: // Note that a casa port might contain multiple links.
1392: NodeList oldLinkNodeList = oldPort
1393: .getElementsByTagName(CASA_LINK_ELEM_NAME);
1394: for (int i = 0; i < oldLinkNodeList.getLength(); i++) {
1395: Element oldLink = (Element) oldLinkNodeList.item(i);
1396: String oldLinkHref = oldLink.getAttributeNS(
1397: XLINK_NAMESPACE_URI, XLINK_HREF_ATTR_NAME);
1398: for (int j = 0; j < newPortNodeList.getLength(); j++) {
1399: Element newPort = (Element) newPortNodeList.item(j);
1400: NodeList newLinkNodeList = newPort
1401: .getElementsByTagName(CASA_LINK_ELEM_NAME);
1402: for (int k = 0; k < newLinkNodeList.getLength(); k++) {
1403: Element newLink = (Element) newLinkNodeList.item(k);
1404: // String myLinkHref = myLink.getAttributeNS(XLINK_NAMESPACE_URI, XLINK_HREF_ATTR_NAME); // FIXME ?????
1405: String newLinkHref = newLink
1406: .getAttribute(XLINK_NAMESPACE_PREFIX + ":"
1407: + XLINK_HREF_ATTR_NAME);
1408: if (newLinkHref.equals(oldLinkHref)) {
1409: return newPort;
1410: }
1411: }
1412: }
1413: }
1414:
1415: return null;
1416: }
1417:
1418: /**
1419: * Gets the Endpoint object in the given CASA document with the given
1420: * endpoint ID.
1421: *
1422: * @param casaDocument CASA document
1423: * @param endpointID ID of an endpoint
1424: *
1425: * @return an Endpoint object
1426: */
1427: static Endpoint getEndpoint(Document casaDocument, String endpointID) {
1428: NodeList endpointList = casaDocument
1429: .getElementsByTagName(CASA_ENDPOINT_ELEM_NAME);
1430: for (int i = 0; i < endpointList.getLength(); i++) {
1431: Element endpoint = (Element) endpointList.item(i);
1432: if (endpoint.getAttribute(CASA_NAME_ATTR_NAME).equals(
1433: endpointID)) {
1434: return getEndpointInCASA(endpoint);
1435: }
1436: }
1437:
1438: return null;
1439: }
1440:
1441: /**
1442: * Gets a non-null list of Endpoints defined in the given CASA document.
1443: */
1444: private static List<Endpoint> getEndpoints(Document casaDocument) {
1445: List<Endpoint> ret = new ArrayList<Endpoint>();
1446:
1447: if (casaDocument != null) {
1448: NodeList endpointList = casaDocument
1449: .getElementsByTagName(CASA_ENDPOINT_ELEM_NAME);
1450: for (int i = 0; i < endpointList.getLength(); i++) {
1451: Element endpointElement = (Element) endpointList
1452: .item(i);
1453: Endpoint endpoint = getEndpointInCASA(endpointElement);
1454: ret.add(endpoint);
1455: }
1456: }
1457:
1458: return ret;
1459: }
1460:
1461: /**
1462: * Computes a non-null list of endpoints that are defined in the WSDL files
1463: * in the compapp project and the component projects.
1464: */
1465: // Loop through all WSDL files, create an allWSDLEndpoints list which
1466: // contains all the ports defined in the WSDL files in the compapp
1467: // project and the component projects.
1468: private List<Endpoint> getNewWsdlEndpoints() {
1469: if (newWsdlEndpoints == null) {
1470: newWsdlEndpoints = new ArrayList<Endpoint>();
1471:
1472: for (WSDLModel model : wsdlRepository.getWsdlCollection()) {
1473: String tns = model.getDefinitions()
1474: .getTargetNamespace(); // model.getRootComponent().getPeer().getAttribute("targetNamespace");
1475: for (Service service : model.getDefinitions()
1476: .getServices()) {
1477: QName serviceQName = new QName(tns, service
1478: .getName());
1479: for (Port port : service.getPorts()) {
1480: String portName = port.getName();
1481: Binding binding = port.getBinding().get();
1482: if (binding != null) {
1483: QName interfaceQName = binding.getType()
1484: .getQName();
1485: Endpoint endpoint = new Endpoint(portName,
1486: serviceQName, interfaceQName);
1487: if (!newWsdlEndpoints.contains(endpoint)) {
1488: newWsdlEndpoints.add(endpoint);
1489: }
1490: }
1491: }
1492: }
1493: }
1494: }
1495:
1496: return newWsdlEndpoints;
1497: }
1498:
1499: /**
1500: * Computes a non-null list of endpoints that need to go into the new
1501: * CASA document.
1502: */
1503: // Those endpoints come from either the old CASA document, or the new WSDL
1504: // files added into compapp. The following rules apply:
1505: // (1) All the old endpoints with owning WSDL no longer in compapp need to
1506: // be removed, whether the endpoint was connected, unconnected, or
1507: // marked as "deleted";
1508: // (2) All the old endpoints with owning WSDL still in compapp need to
1509: // be preserved; whether the endpoint was connected, unconnected, or
1510: // marked as "deleted";
1511: // (3) All the old endpoints without owning WSDL (external endpoints)
1512: // need to be preserved;
1513: // (4) Only the connected endpoints in the newly added WSDLs need to be added;
1514: private List<Endpoint> getNewCasaEndpoints(Document jbiDocument) {
1515:
1516: List<Endpoint> oldCasaEndpoints = getEndpoints(oldCasaDocument);
1517:
1518: // Loop through all jbiServiceUnits/$suName/jbi.xml, create a
1519: // newSUEndpoints list
1520: List<Endpoint> newSUEndpoints = new ArrayList<Endpoint>();
1521:
1522: if (jbiDocument == null) {
1523: return new ArrayList<Endpoint>();
1524: }
1525: NodeList jbiSUs = jbiDocument
1526: .getElementsByTagName(JBI_SERVICE_UNIT_ELEM_NAME);
1527: for (int i = 0; i < jbiSUs.getLength(); i++) {
1528: Element jbiSU = (Element) jbiSUs.item(i);
1529: String suName = getJBIServiceUnitName(jbiSU);
1530: List<Endpoint> suEndpoints = loadSUEndpoints(suName);
1531: su2Endpoints.put(suName, suEndpoints);
1532: if (suEndpoints != null) {
1533: for (Endpoint suEndpoint : suEndpoints) {
1534: if (!newSUEndpoints.contains(suEndpoint)) {
1535: newSUEndpoints.add(suEndpoint);
1536: }
1537: }
1538: }
1539: }
1540:
1541: // Compute externalAndWsdlEndpoints:
1542: // externalAndWsdlEndpoints =
1543: // externalEndpoints + newWsdlEndpoints
1544: List<Endpoint> externalAndWsdlEndpoints = new ArrayList<Endpoint>();
1545: externalAndWsdlEndpoints.addAll(getExternalEndpoints());
1546: externalAndWsdlEndpoints.addAll(getNewWsdlEndpoints());
1547:
1548: // Compute newCasaEndpoints:
1549: // newCasaEndpoints =
1550: // Intersection(oldCasaEndpoints, externalEndpoints + newWsdlEndpoints)
1551: // + newSUEndpoints
1552: // When computing the list of newCasaEndpoints, we want to preserve the
1553: // order (and therefore the ID) of endpoints in the oldCasaEndpoints
1554: // list as much as possible to avoid unnecessary (endpoint ID) changes
1555: // across compapp builds.
1556: List<Endpoint> newCasaEndpoints = new ArrayList<Endpoint>();
1557: for (Endpoint oldCasaEndpoint : oldCasaEndpoints) {
1558: for (Endpoint endpoint : externalAndWsdlEndpoints) {
1559: if (oldCasaEndpoint.equals(endpoint)) {
1560: newCasaEndpoints.add(oldCasaEndpoint);
1561: break;
1562: }
1563: }
1564: }
1565:
1566: for (Endpoint suEndpoint : newSUEndpoints) {
1567: if (!newCasaEndpoints.contains(suEndpoint)) {
1568: newCasaEndpoints.add(suEndpoint);
1569: }
1570: }
1571:
1572: debugLog("old CASA Endpoints:");
1573: for (Endpoint endpoint : oldCasaEndpoints) {
1574: debugLog(" " + endpoint.getFullyQualifiedName());
1575: }
1576: debugLog("new WSDL Endpoints:");
1577: for (Endpoint endpoint : newWsdlEndpoints) {
1578: debugLog(" " + endpoint.getFullyQualifiedName());
1579: }
1580: debugLog("external Endpoints:");
1581: for (Endpoint endpoint : externalEndpoints) {
1582: debugLog(" " + endpoint.getFullyQualifiedName());
1583: }
1584: debugLog("new SU Endpoints:");
1585: for (Endpoint endpoint : newSUEndpoints) {
1586: debugLog(" " + endpoint.getFullyQualifiedName());
1587: }
1588: debugLog("new CASA Endpoints:");
1589: for (Endpoint endpoint : newCasaEndpoints) {
1590: debugLog(" " + endpoint.getFullyQualifiedName());
1591: }
1592:
1593: return newCasaEndpoints;
1594: }
1595:
1596: /**
1597: * Creates the Endpoints element in the new casa document.
1598: */
1599: private Element createEndpoints(Document jbiDocument) {
1600:
1601: Element endpoints = newCasaDocument
1602: .createElement(CASA_ENDPOINTS_ELEM_NAME);
1603: Element casaRoot = (Element) newCasaDocument
1604: .getElementsByTagName("casa").item(0);
1605: casaRoot.appendChild(endpoints);
1606:
1607: List<Endpoint> newCasaEndpoints = getNewCasaEndpoints(jbiDocument);
1608: for (Endpoint endpoint : newCasaEndpoints) {
1609: addEndpoint(endpoint);
1610: }
1611:
1612: return endpoints;
1613: }
1614:
1615: /**
1616: * Adds an endpoint to the new casa document. Do nothing if the given
1617: * endpoint already exists.
1618: *
1619: * @return the ID of the endpoint
1620: */
1621: private String addEndpoint(Endpoint endpoint) {
1622:
1623: String key = endpoint.getFullyQualifiedName();
1624: String endpointID = newEndpointMap.get(key);
1625:
1626: if (endpointID == null) {
1627: endpointID = "endpoint" + endpointIndex;
1628: endpointIndex++;
1629: newEndpointMap.put(key, endpointID);
1630:
1631: Element endpoints = (Element) newCasaDocument
1632: .getElementsByTagName("endpoints").item(0);
1633:
1634: Element casaEndpoint = newCasaDocument
1635: .createElement(CASA_ENDPOINT_ELEM_NAME);
1636: casaEndpoint.setAttribute(CASA_NAME_ATTR_NAME, endpointID);
1637: casaEndpoint.setAttribute(CASA_ENDPOINT_NAME_ATTR_NAME,
1638: endpoint.getEndpointName());
1639: setAttributeQName(casaEndpoint,
1640: CASA_SERVICE_NAME_ATTR_NAME, endpoint
1641: .getServiceQName());
1642: setAttributeQName(casaEndpoint,
1643: CASA_INTERFACE_NAME_ATTR_NAME, endpoint
1644: .getInterfaceQName());
1645:
1646: if (endpoint instanceof EndpointWithExtension) {
1647: EndpointWithExtension endpointWithExtension = (EndpointWithExtension) endpoint;
1648:
1649: String displayName = endpointWithExtension
1650: .getDisplayName();
1651: String processName = endpointWithExtension
1652: .getProcessName();
1653: String filePath = endpointWithExtension.getFilePath();
1654:
1655: if (displayName != null && displayName.length() > 0) {
1656: casaEndpoint.setAttribute(
1657: JBI_ENDPOINT_EXTENSION_DISPLAY_NAME,
1658: displayName);
1659: }
1660:
1661: if (processName != null && processName.length() > 0) {
1662: casaEndpoint.setAttribute(
1663: JBI_ENDPOINT_EXTENSION_PROCESS_NAME,
1664: processName);
1665: }
1666:
1667: if (filePath != null && filePath.length() > 0) {
1668: casaEndpoint.setAttribute(
1669: JBI_ENDPOINT_EXTENSION_FILE_PATH, filePath);
1670: }
1671: }
1672:
1673: endpoints.appendChild(casaEndpoint);
1674: }
1675:
1676: return endpointID;
1677: }
1678:
1679: /**
1680: * Gets the ID of an endpoint in the new casa document.
1681: */
1682: private String getNewEndpointID(QName serviceQName,
1683: String endpointName) {
1684: String key = serviceQName.toString() + "." + endpointName;
1685: return newEndpointMap.get(key);
1686: }
1687:
1688: /**
1689: * Gets the ID of an endpoint in the new casa document.
1690: */
1691: private String getNewEndpointID(Endpoint endpoint) {
1692: String key = endpoint.getFullyQualifiedName();
1693: return newEndpointMap.get(key);
1694: }
1695:
1696: // TODO
1697: // Mapping namespace URI to namespace prefix
1698: private Map<String, String> nsMap = new HashMap<String, String>();
1699: private int prefixID = 1;
1700:
1701: private void setAttributeQName(Element element, String attrName,
1702: QName attrValueQName) {
1703: String attrValueNamespace = attrValueQName.getNamespaceURI();
1704: String attrValue = attrValueQName.getLocalPart();
1705:
1706: String attrQValue;
1707:
1708: if (attrValueNamespace.equals("") && attrValue.equals("")) {
1709: attrQValue = "";
1710: } else {
1711: String prefix = nsMap.get(attrValueNamespace);
1712: if (prefix == null) {
1713: prefix = "ns" + prefixID;
1714: prefixID++;
1715: element.getOwnerDocument().getDocumentElement()
1716: .setAttribute("xmlns:" + prefix,
1717: attrValueNamespace);
1718: nsMap.put(attrValueNamespace, prefix);
1719: }
1720: attrQValue = prefix + ":" + attrValue;
1721: }
1722:
1723: element.setAttribute(attrName, attrQValue);
1724: }
1725:
1726: private List<Endpoint> loadSUEndpoints(String suName) {
1727:
1728: List<Endpoint> suEndpointList = new ArrayList<Endpoint>();
1729:
1730: File suJbiFile = new File(serviceUnitsDirLoc + suName
1731: + File.separator + "jbi.xml"); // NOI18N
1732: if (suJbiFile.exists()) {
1733: DocumentBuilderFactory factory = DocumentBuilderFactory
1734: .newInstance();
1735: factory.setValidating(false);
1736: factory.setNamespaceAware(true);
1737: try {
1738: DocumentBuilder documentBuilder = factory
1739: .newDocumentBuilder();
1740: Document suJbiDocument = documentBuilder
1741: .parse(suJbiFile);
1742: NodeList servicesElements = suJbiDocument
1743: .getElementsByTagNameNS(JBI_NAMESPACE_URI,
1744: JBI_SERVICES_ELEM_NAME);
1745: for (int i = 0; i < servicesElements.getLength(); i++) {
1746: Element servicesElement = (Element) servicesElements
1747: .item(i);
1748: NodeList children = servicesElement.getChildNodes();
1749: for (int k = 0; k < children.getLength(); k++) {
1750: Node child = children.item(k);
1751: if (child instanceof Element) {
1752: Element e = (Element) child;
1753: String endpointName = e
1754: .getAttribute(JBI_ENDPOINT_NAME_ATTR_NAME);
1755:
1756: String serviceName = e
1757: .getAttribute(JBI_SERVICE_NAME_ATTR_NAME);
1758: String serviceNS = null;
1759: int idx = serviceName.indexOf(':');
1760: if (idx > 0) {
1761: String prefix = serviceName.substring(
1762: 0, idx);
1763: serviceNS = suJbiDocument
1764: .getDocumentElement()
1765: .getAttribute("xmlns:" + prefix);
1766: serviceName = serviceName
1767: .substring(idx + 1);
1768: }
1769:
1770: String interfaceName = e
1771: .getAttribute(JBI_INTERFACE_NAME_ATTR_NAME);
1772: String interfaceNS = "";
1773: idx = interfaceName.indexOf(':');
1774: if (idx > 0) {
1775: String prefix = interfaceName
1776: .substring(0, idx);
1777: interfaceNS = suJbiDocument
1778: .getDocumentElement()
1779: .getAttribute("xmlns:" + prefix);
1780: interfaceName = interfaceName
1781: .substring(idx + 1);
1782: }
1783:
1784: // 06/05/07, T. Li skip extension elements.
1785: if ((interfaceName != null)
1786: && (interfaceName.length() > 0)) {
1787: EndpointWithExtension endpoint = new EndpointWithExtension(
1788: endpointName,
1789: new QName(serviceNS,
1790: serviceName),
1791: new QName(interfaceNS,
1792: interfaceName), e
1793: .getLocalName().equals(
1794: "consumes"));
1795:
1796: // NodeList endpointExtensions =
1797: // e.getElementsByTagNameNS(
1798: // JBI_ENDPOINT_EXTENSION_NAMESPACE,
1799: // JBI_ENDPOINT_EXTENSION_ELEMENT);
1800: //
1801: // if (endpointExtensions.getLength() == 1) {
1802: // Element endpointExtension = (Element) endpointExtensions.item(0);
1803: //
1804: // String displayName = endpointExtension.getAttribute(JBI_ENDPOINT_EXTENSION_DISPLAY_NAME);
1805: // String processName = endpointExtension.getAttribute(JBI_ENDPOINT_EXTENSION_PROCESS_NAME);
1806: // String filePath = endpointExtension.getAttribute(JBI_ENDPOINT_EXTENSION_FILE_PATH);
1807: //
1808: // endpoint.setDisplayName(displayName);
1809: // endpoint.setProcessName(processName);
1810: // endpoint.setFilePath(filePath);
1811: // }
1812:
1813: NodeList displayNameElements = e
1814: .getElementsByTagNameNS(
1815: JBI_ENDPOINT_EXTENSION_NAMESPACE,
1816: JBI_ENDPOINT_EXTENSION_DISPLAY_NAME);
1817: if (displayNameElements.getLength() == 1) {
1818: String displayName = displayNameElements
1819: .item(0).getTextContent();
1820: endpoint
1821: .setDisplayName(displayName);
1822: }
1823:
1824: NodeList processNameElements = e
1825: .getElementsByTagNameNS(
1826: JBI_ENDPOINT_EXTENSION_NAMESPACE,
1827: JBI_ENDPOINT_EXTENSION_PROCESS_NAME);
1828: if (processNameElements.getLength() == 1) {
1829: String processName = processNameElements
1830: .item(0).getTextContent();
1831: endpoint
1832: .setProcessName(processName);
1833: }
1834:
1835: NodeList filePathElements = e
1836: .getElementsByTagNameNS(
1837: JBI_ENDPOINT_EXTENSION_NAMESPACE,
1838: JBI_ENDPOINT_EXTENSION_FILE_PATH);
1839: if (filePathElements.getLength() == 1) {
1840: String filePath = filePathElements
1841: .item(0).getTextContent();
1842: endpoint.setFilePath(filePath);
1843: }
1844:
1845: suEndpointList.add(endpoint);
1846: }
1847: }
1848: }
1849: }
1850: } catch (Exception e) {
1851: e.printStackTrace();
1852: }
1853: return suEndpointList;
1854:
1855: }
1856: return null;
1857: }
1858:
1859: private boolean isInEndpointList(List<Endpoint> endpointList,
1860: QName serviceQName, String portName) {
1861: if (endpointList != null) {
1862: // TODO?: change Endpoint.equals() to ignore interface checking
1863: // and use List.contains() here
1864: for (Endpoint endpoint : endpointList) {
1865: if (endpoint.getEndpointName().equals(portName)
1866: && endpoint.getServiceQName().equals(
1867: serviceQName)) {
1868: return true;
1869: }
1870: }
1871: }
1872:
1873: return false;
1874: }
1875:
1876: /**
1877: * Creates a complete Ports element for a BC SU in the new casa document.
1878: *
1879: * @param bcName name of a BC SU, e.x., sun-jms-binding
1880: */
1881: private Element createPorts(String bcName) {
1882: debugLog("create Ports for binding component " + bcName);
1883:
1884: // Create casa ports element.
1885: Element ports = newCasaDocument
1886: .createElement(CASA_PORTS_ELEM_NAME);
1887:
1888: // Mapping fully qualified port names to casa port elements in the
1889: // new casa document. (This is to solve the duplicate WSDL problem.)
1890: // Note that this map is scoped by each BC SU and should not be used
1891: // across different BC SUs!
1892: Map<String, Element> casaPortMap = new HashMap<String, Element>();
1893:
1894: List<Endpoint> suEndpoints = su2Endpoints.get(bcName);
1895:
1896: // 02/12/08, used to skip ports from duplicate copies of wsdl files
1897: Map<String, Port> portMap = new HashMap<String, Port>();
1898:
1899: // Loop through all WSDLs and add casa port elements of the given
1900: // BC type. This includes:
1901: // (1) BC endpoints in the corresponding SU's jbi.xml,
1902: // (2) unconnected BC endpoints from old casa that are still live, and
1903: // (3) "deleted" BC endpoints from old casa that are still live.
1904: for (WSDLModel model : wsdlRepository.getWsdlCollection()) {
1905: /*
1906: if (wsdlRepository.isJavaEEWsdl(model)) {
1907: continue;
1908: }
1909: */
1910:
1911: String relativePath = MyFileUtil.getRelativePath(new File(
1912: confDirLoc), getFile(model));
1913: debugLog(" WSDL: " + relativePath);
1914: String tns = model.getRootComponent().getPeer()
1915: .getAttribute("targetNamespace");
1916: //wsdlDocument.getDocumentElement().getAttribute("targetNamespace");
1917:
1918: // Add casa port
1919: for (Service s : model.getDefinitions().getServices()) {
1920: String serviceName = s.getName();
1921: QName serviceQName = new QName(tns, serviceName);
1922: for (Port p : s.getPorts()) {
1923: String portName = p.getName();
1924: debugLog(" Endpoint: " + serviceQName
1925: + ":" + portName);
1926: String key = tns + ":" + serviceName + ":"
1927: + portName;
1928: if (portMap.get(key) == null) {
1929: portMap.put(key, p);
1930:
1931: boolean isSUEndpoint = isInEndpointList(
1932: suEndpoints, serviceQName, portName);
1933: boolean isLiveDeletedBCEndpoint = false;
1934: boolean isLiveUnconnectedEndpoint = false;
1935:
1936: if (isSUEndpoint) {
1937: debugLog(" is a SU endpoint.");
1938: } else {
1939: List<Endpoint> deletedBCEndpoints = deletedBCEndpointsMap
1940: .get(bcName);
1941: if (isInEndpointList(deletedBCEndpoints,
1942: serviceQName, portName)
1943: && isInEndpointList(
1944: newWsdlEndpoints,
1945: serviceQName, portName)) {
1946: isLiveDeletedBCEndpoint = true;
1947: debugLog(" is a live deleted endpoint.");
1948: }
1949:
1950: if (!isLiveDeletedBCEndpoint) {
1951: List<Endpoint> unconnectedBCEndpoints = oldUnconnectedBCEndpointsMap
1952: .get(bcName);
1953: if (isInEndpointList(
1954: unconnectedBCEndpoints,
1955: serviceQName, portName)
1956: && isInEndpointList(
1957: newWsdlEndpoints,
1958: serviceQName, portName)) {
1959: isLiveUnconnectedEndpoint = true;
1960: debugLog(" is a live unconnected endpoint.");
1961: }
1962: }
1963: }
1964:
1965: if (isSUEndpoint || isLiveDeletedBCEndpoint
1966: || isLiveUnconnectedEndpoint) {
1967: // Instead of creating a new casa port every time, check
1968: // if a casa port has already been created. This allows
1969: // multiple (duplicate) WSDL Ports to share the same
1970: // CASA Port element.
1971: String fullyQualifiedPortName = serviceQName
1972: .toString()
1973: + "." + portName;
1974: Element port = casaPortMap
1975: .get(fullyQualifiedPortName);
1976: if (port == null) {
1977: // Create new casa port
1978: port = createPort(relativePath,
1979: serviceQName, portName);
1980: ports.appendChild(port);
1981: casaPortMap.put(fullyQualifiedPortName,
1982: port);
1983:
1984: // Mark casa port as "deleted" if the old casa says so.
1985: if (isLiveDeletedBCEndpoint) {
1986: port.setAttribute(
1987: CASA_STATE_ATTR_NAME,
1988: CASA_DELETED_ATTR_VALUE);
1989: }
1990: } else {
1991: // Reuse old casa port by adding a new link
1992: Element casaLinkElement = createLinkForWsdlPort(
1993: relativePath, serviceName,
1994: portName);
1995: port.appendChild(casaLinkElement);
1996: }
1997: }
1998: }
1999: }
2000: }
2001: }
2002:
2003: return ports;
2004: }
2005:
2006: /**
2007: * Creates a Port element for a BC SU in the new casa document.
2008: */
2009: private Element createPort(String relativePath, QName serviceQName,
2010: String portName) {
2011: // 1. Create casa port
2012: Element ret = newCasaDocument
2013: .createElement(CASA_PORT_ELEM_NAME);
2014: ret.setAttribute(CASA_X_ATTR_NAME, "0");
2015: ret.setAttribute(CASA_Y_ATTR_NAME, "-1");
2016:
2017: // 2. Add link. (Note that additional links might be added later.)
2018: Element linkElement = createLinkForWsdlPort(relativePath,
2019: serviceQName.getLocalPart(), portName);
2020: ret.appendChild(linkElement);
2021:
2022: // 3. Add one consumes and one provides to the casa port
2023: String endpointID = getNewEndpointID(serviceQName, portName);
2024:
2025: Element cEndpointRef = newCasaDocument
2026: .createElement(CASA_CONSUMES_ELEM_NAME);
2027: cEndpointRef.setAttribute(CASA_ENDPOINT_ATTR_NAME, endpointID);
2028: ret.appendChild(cEndpointRef);
2029:
2030: Element pEndpointRef = newCasaDocument
2031: .createElement(CASA_PROVIDES_ELEM_NAME);
2032: pEndpointRef.setAttribute(CASA_ENDPOINT_ATTR_NAME, endpointID);
2033: ret.appendChild(pEndpointRef);
2034:
2035: return ret;
2036: }
2037:
2038: /**
2039: * Creates a Link element in the new casa document for a WSDL port.
2040: */
2041: private Element createLinkForWsdlPort(String relativePath,
2042: String serviceName, String portName) {
2043: String uri = "/definitions/service[@name='" + serviceName
2044: + "']/port[@name='" + portName + "']";
2045: return createLink(relativePath, uri);
2046: }
2047:
2048: /**
2049: * Creates a Link element in the new casa document.
2050: */
2051: private Element createLink(String relativePath, String uri) {
2052: Element ret = newCasaDocument
2053: .createElement(CASA_LINK_ELEM_NAME);
2054: ret.setAttribute(XLINK_NAMESPACE_PREFIX + ":type", "simple");
2055: ret.setAttribute(XLINK_NAMESPACE_PREFIX + ":href", relativePath
2056: + "#xpointer(" + uri + ")");
2057: return ret;
2058: }
2059:
2060: private void log(String msg) {
2061: task.log(msg);
2062: }
2063:
2064: private void debugLog(String msg) {
2065: task.log(msg, Project.MSG_DEBUG);
2066: }
2067: }
|