You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by rf...@apache.org on 2009/09/28 21:15:07 UTC

svn commit: r819680 [1/5] - in /tuscany/java/sca/modules/builder/src: main/java/org/apache/tuscany/sca/builder/ main/java/org/apache/tuscany/sca/builder/impl/ main/java/org/apache/tuscany/sca/policy/builder/impl/ test/java/org/apache/tuscany/sca/builde...

Author: rfeng
Date: Mon Sep 28 19:15:06 2009
New Revision: 819680

URL: http://svn.apache.org/viewvc?rev=819680&view=rev
Log:
Start to copy builders from assembly module

Added:
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/BaseBuilderImpl.java   (with props)
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/BindingURIBuilderImpl.java   (with props)
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java   (with props)
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentReferenceBindingBuilderImpl.java   (with props)
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentReferencePromotionBuilderImpl.java   (with props)
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentServiceBindingBuilderImpl.java   (with props)
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentServicePromotionBuilderImpl.java   (with props)
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/CompositeCloneBuilderImpl.java   (with props)
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/CompositeComponentTypeBuilderImpl.java   (with props)
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/CompositeIncludeBuilderImpl.java   (with props)
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/CompositePolicyBuilderImpl.java   (with props)
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointBuilderImpl.java   (with props)
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java   (with props)
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ModelBuilderImpl.java   (with props)
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/PolicyAttachmentBuilderImpl.java
      - copied, changed from r819676, tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/policy/builder/impl/PolicyAttachmentBuilderImpl.java
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ReferenceConfigurationUtil.java   (with props)
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ServiceConfigurationUtil.java   (with props)
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/StructuralURIBuilderImpl.java   (with props)
    tuscany/java/sca/modules/builder/src/test/java/org/apache/tuscany/sca/builder/
    tuscany/java/sca/modules/builder/src/test/java/org/apache/tuscany/sca/builder/impl/
      - copied from r819676, tuscany/java/sca/modules/builder/src/test/java/org/apache/tuscany/sca/policy/builder/impl/
Removed:
    tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/policy/builder/impl/
    tuscany/java/sca/modules/builder/src/test/java/org/apache/tuscany/sca/policy/builder/impl/
Modified:
    tuscany/java/sca/modules/builder/src/test/java/org/apache/tuscany/sca/builder/impl/MockPolicy.java
    tuscany/java/sca/modules/builder/src/test/java/org/apache/tuscany/sca/builder/impl/PolicyAttachmentTestCase.java
    tuscany/java/sca/modules/builder/src/test/java/org/apache/tuscany/sca/builder/impl/TestPolicyProcessor.java

Added: tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/BaseBuilderImpl.java
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/BaseBuilderImpl.java?rev=819680&view=auto
==============================================================================
--- tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/BaseBuilderImpl.java (added)
+++ tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/BaseBuilderImpl.java Mon Sep 28 19:15:06 2009
@@ -0,0 +1,705 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.builder.impl;
+
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.TransformerFactory;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentProperty;
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.Contract;
+import org.apache.tuscany.sca.assembly.Implementation;
+import org.apache.tuscany.sca.assembly.Property;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.SCABinding;
+import org.apache.tuscany.sca.assembly.SCABindingFactory;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.assembly.builder.BuilderExtensionPoint;
+import org.apache.tuscany.sca.assembly.builder.CompositeBuilder;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.definitions.Definitions;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.Problem;
+import org.apache.tuscany.sca.monitor.Problem.Severity;
+import org.apache.tuscany.sca.policy.ExtensionType;
+import org.apache.tuscany.sca.policy.PolicySubject;
+import org.w3c.dom.Document;
+
+/**
+ * Base class for Builder implementations
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class BaseBuilderImpl implements CompositeBuilder {
+    protected static final String SCA11_NS = "http://docs.oasis-open.org/ns/opencsa/sca/200903";
+    protected static final String BINDING_SCA = "binding.sca";
+    protected static final QName BINDING_SCA_QNAME = new QName(SCA11_NS, BINDING_SCA);
+
+    protected AssemblyFactory assemblyFactory;
+    protected SCABindingFactory scaBindingFactory;
+    protected InterfaceContractMapper interfaceContractMapper;
+    protected DocumentBuilderFactory documentBuilderFactory;
+    protected TransformerFactory transformerFactory;
+    protected BuilderExtensionPoint builders;
+
+    protected BaseBuilderImpl(BuilderExtensionPoint builders,
+                              AssemblyFactory assemblyFactory,
+                              SCABindingFactory scaBindingFactory,
+                              DocumentBuilderFactory documentBuilderFactory,
+                              TransformerFactory transformerFactory,
+                              InterfaceContractMapper interfaceContractMapper) {
+        this.builders = builders;
+        this.assemblyFactory = assemblyFactory;
+        this.scaBindingFactory = scaBindingFactory;
+        this.documentBuilderFactory = documentBuilderFactory;
+        this.transformerFactory = transformerFactory;
+        this.interfaceContractMapper = interfaceContractMapper;
+    }
+
+    /**
+     * Construct a builder from the extension point registry
+     * @param registry
+     */
+    protected BaseBuilderImpl(ExtensionPointRegistry registry) {
+        this.builders = registry.getExtensionPoint(BuilderExtensionPoint.class);
+        FactoryExtensionPoint factoryExtensionPoint = registry.getExtensionPoint(FactoryExtensionPoint.class);
+        this.assemblyFactory = factoryExtensionPoint.getFactory(AssemblyFactory.class);
+        this.scaBindingFactory = factoryExtensionPoint.getFactory(SCABindingFactory.class);
+        this.documentBuilderFactory = factoryExtensionPoint.getFactory(DocumentBuilderFactory.class);
+        this.transformerFactory = factoryExtensionPoint.getFactory(TransformerFactory.class);
+        this.interfaceContractMapper =
+            registry.getExtensionPoint(UtilityExtensionPoint.class).getUtility(InterfaceContractMapper.class);
+    }
+
+    /**
+     * Report a warning.
+     *
+     * @param monitor
+     * @param problems
+     * @param message
+     * @param model
+     */
+    protected void warning(Monitor monitor, String message, Object model, Object... messageParameters) {
+        if (monitor != null) {
+            Problem problem =
+                monitor.createProblem(this.getClass().getName(),
+                                      "assembly-validation-messages",
+                                      Severity.WARNING,
+                                      model,
+                                      message,
+                                      messageParameters);
+            monitor.problem(problem);
+        }
+    }
+
+    /**
+     * Report a error.
+     *
+     * @param monitor
+     * @param problems
+     * @param message
+     * @param model
+     */
+    protected void error(Monitor monitor, String message, Object model, Object... messageParameters) {
+        if (monitor != null) {
+            Problem problem =
+                monitor.createProblem(this.getClass().getName(),
+                                      "assembly-validation-messages",
+                                      Severity.ERROR,
+                                      model,
+                                      message,
+                                      messageParameters);
+            monitor.problem(problem);
+        }
+    }
+
+    /**
+     * Report a exception.
+     *
+     * @param problems
+     * @param message
+     * @param model
+     */
+    protected void error(Monitor monitor, String message, Object model, Exception ex) {
+        if (monitor != null) {
+            Problem problem = null;
+            problem =
+                monitor.createProblem(this.getClass().getName(),
+                                      "assembly-validation-messages",
+                                      Severity.ERROR,
+                                      model,
+                                      message,
+                                      ex);
+            monitor.problem(problem);
+        }
+    }
+
+    /**
+     * Index components inside a composite
+     *
+     * @param composite
+     * @param componentServices
+
+     */
+    protected void indexComponents(Composite composite, Map<String, Component> components) {
+        for (Component component : composite.getComponents()) {
+            // Index components by name
+            components.put(component.getName(), component);
+        }
+    }
+
+    /**
+     * Index services inside a composite
+     *
+     * @param composite
+     * @param componentServices
+     */
+    protected void indexServices(Composite composite, Map<String, ComponentService> componentServices) {
+
+        for (Component component : composite.getComponents()) {
+
+            ComponentService nonCallbackService = null;
+            int nonCallbackServiceCount = 0;
+
+            for (ComponentService componentService : component.getServices()) {
+                // Index component services by component name / service name
+                String uri = component.getName() + '/' + componentService.getName();
+                componentServices.put(uri, componentService);
+
+                // count how many non-callback there are
+                if (!componentService.isForCallback()) {
+
+                    if (nonCallbackServiceCount == 0) {
+                        nonCallbackService = componentService;
+                    }
+                    nonCallbackServiceCount++;
+                }
+            }
+            if (nonCallbackServiceCount == 1) {
+                // If we have a single non callback service, index it by
+                // component name as well
+                componentServices.put(component.getName(), nonCallbackService);
+            }
+        }
+    }
+
+    /**
+     * Index components, services and references inside a composite.
+     * @param composite
+     * @param components
+     * @param componentServices
+     * @param componentReferences
+     */
+    protected void indexComponentsServicesAndReferences(Composite composite,
+                                                        Map<String, Component> components,
+                                                        Map<String, ComponentService> componentServices,
+                                                        Map<String, ComponentReference> componentReferences) {
+
+        for (Component component : composite.getComponents()) {
+
+            // Index components by name
+            components.put(component.getName(), component);
+
+            ComponentService nonCallbackService = null;
+            int nonCallbackServices = 0;
+            for (ComponentService componentService : component.getServices()) {
+
+                // Index component services by component name / service name
+                String uri = component.getName() + '/' + componentService.getName();
+                componentServices.put(uri, componentService);
+
+                // TODO - EPR - $promoted$ no longer used but it doesn't do any harm here
+                boolean promotedService = false;
+                if (componentService.getName() != null && componentService.getName().indexOf("$promoted$") > -1) {
+                    promotedService = true;
+                }
+
+                // count how many non-callback, non-promoted services there are
+                // if there is only one the component name also acts as the service name
+                if ((!componentService.isForCallback()) && (!promotedService)) {
+
+                    // Check how many non callback non-promoted services we have
+                    if (nonCallbackServices == 0) {
+                        nonCallbackService = componentService;
+                    }
+                    nonCallbackServices++;
+                }
+
+            }
+
+            if (nonCallbackServices == 1) {
+                // If we have a single non callback service, index it by
+                // component name as well
+                componentServices.put(component.getName(), nonCallbackService);
+            }
+
+            // Index references by component name / reference name
+            for (ComponentReference componentReference : component.getReferences()) {
+                String uri = component.getName() + '/' + componentReference.getName();
+                componentReferences.put(uri, componentReference);
+            }
+        }
+    }
+
+    protected void indexComponentPropertiesServicesAndReferences(Component component,
+                                                                 Map<String, ComponentService> componentServices,
+                                                                 Map<String, ComponentReference> componentReferences,
+                                                                 Map<String, ComponentProperty> componentProperties,
+                                                                 Monitor monitor) {
+        for (ComponentService componentService : component.getServices()) {
+            if (componentServices.containsKey(componentService.getName())) {
+                // [MJE 13/05/2009] Changed to "error" since allowing these violates the OASIS spec
+                error(monitor, "DuplicateComponentServiceName", component, component.getName(), componentService
+                    .getName());
+            } else {
+                componentServices.put(componentService.getName(), componentService);
+            }
+        }
+        for (ComponentReference componentReference : component.getReferences()) {
+            if (componentReferences.containsKey(componentReference.getName())) {
+                // [MJE 13/05/2009] Changed to "error" since allowing these violates the OASIS spec
+                error(monitor, "DuplicateComponentReferenceName", component, component.getName(), componentReference
+                    .getName());
+            } else {
+                componentReferences.put(componentReference.getName(), componentReference);
+            }
+        }
+        for (ComponentProperty componentProperty : component.getProperties()) {
+            if (componentProperties.containsKey(componentProperty.getName())) {
+                // [MJE 13/05/2009] Changed to "error" since allowing these violates the OASIS spec
+                error(monitor, "DuplicateComponentPropertyName", component, component.getName(), componentProperty
+                    .getName());
+            } else {
+                componentProperties.put(componentProperty.getName(), componentProperty);
+            }
+        }
+
+    }
+
+    protected void indexImplementationPropertiesServicesAndReferences(Component component,
+                                                                      Map<String, Service> services,
+                                                                      Map<String, Reference> references,
+                                                                      Map<String, Property> properties,
+                                                                      Monitor monitor) {
+        // First check that the component has a resolved implementation
+        Implementation implementation = component.getImplementation();
+        if (implementation == null) {
+            // A component must have an implementation
+            error(monitor, "NoComponentImplementation", component, component.getName());
+
+        } else if (implementation.isUnresolved()) {
+
+            // The implementation must be fully resolved
+            error(monitor, "UnresolvedComponentImplementation", component, component.getName(), implementation.getURI());
+
+        } else {
+
+            // Index properties, services and references, also check for
+            // duplicates
+            for (Property property : implementation.getProperties()) {
+                if (properties.containsKey(property.getName())) {
+                    // [MJE 13/05/2009] Changed to "error" since allowing these violates the OASIS spec
+                    error(monitor, "DuplicateImplementationPropertyName", component, component.getName(), property
+                        .getName());
+                } else {
+                    properties.put(property.getName(), property);
+                }
+            }
+            for (Service service : implementation.getServices()) {
+                if (services.containsKey(service.getName())) {
+                    // [MJE 13/05/2009] Changed to "error" since allowing these violates the OASIS spec
+                    error(monitor, "DuplicateImplementationServiceName", component, component.getName(), service
+                        .getName());
+                } else {
+                    services.put(service.getName(), service);
+                }
+            }
+            for (Reference reference : implementation.getReferences()) {
+                if (references.containsKey(reference.getName())) {
+                    // [MJE 13/05/2009] Changed to "error" since allowing these violates the OASIS spec
+                    error(monitor, "DuplicateImplementationReferenceName", component, component.getName(), reference
+                        .getName());
+                } else {
+                    references.put(reference.getName(), reference);
+                }
+            }
+        }
+
+    }
+
+    /**
+     * Reconcile component properties and the properties defined by the
+     * component type.
+     *
+     * @param component
+     * @param properties
+     * @param componentProperties
+     * @param problems
+     */
+    protected void reconcileProperties(Component component,
+                                       Map<String, Property> properties,
+                                       Map<String, ComponentProperty> componentProperties,
+                                       Monitor monitor) {
+
+        // Connect component properties to their properties
+        for (ComponentProperty componentProperty : component.getProperties()) {
+            Property property = properties.get(componentProperty.getName());
+            if (property != null) {
+                componentProperty.setProperty(property);
+            } else {
+                error(monitor, "PropertyNotFound", component, component.getName(), componentProperty.getName());
+            }
+        }
+
+        // Create component properties for all properties
+        if (component.getImplementation() != null) {
+            for (Property property : component.getImplementation().getProperties()) {
+                if (!componentProperties.containsKey(property.getName())) {
+                    ComponentProperty componentProperty = assemblyFactory.createComponentProperty();
+                    componentProperty.setName(property.getName());
+                    componentProperty.setValue(property.getValue());
+                    componentProperty.setMany(property.isMany());
+                    componentProperty.setMustSupply(property.isMustSupply());
+                    componentProperty.setXSDElement(property.getXSDElement());
+                    componentProperty.setXSDType(property.getXSDType());
+                    componentProperty.setProperty(property);
+                    component.getProperties().add(componentProperty);
+                }
+            }
+        }
+
+        // Reconcile component properties and their properties
+        for (ComponentProperty componentProperty : component.getProperties()) {
+            Property property = componentProperty.getProperty();
+            if (property != null) {
+
+                // Check that a component property does not override the
+                // mustSupply attribute
+                if (!property.isMustSupply() && componentProperty.isMustSupply()) {
+                    warning(monitor,
+                            "PropertyMustSupplyIncompatible",
+                            component,
+                            component.getName(),
+                            componentProperty.getName());
+                }
+
+                // Default to the mustSupply attribute specified on the property
+                if (!componentProperty.isMustSupply())
+                    componentProperty.setMustSupply(property.isMustSupply());
+
+                // Default to the value specified on the component type property
+                if (!isPropertyValueSet(componentProperty)) {
+                    componentProperty.setValue(property.getValue());
+                }
+
+                // Override the property value for the composite
+                if (component.getImplementation() instanceof Composite) {
+                    property.setValue(componentProperty.getValue());
+                }
+
+                // Check that a value is supplied
+                if (!isPropertyValueSet(componentProperty) && property.isMustSupply()) {
+                    error(monitor, "PropertyMustSupplyNull", component, component.getName(), componentProperty
+                        .getName());
+                }
+
+                // Check that a component property does not override the
+                // many attribute
+                if (!property.isMany() && componentProperty.isMany()) {
+
+                    warning(monitor, "PropertyOverrideManyAttribute", component, component.getName(), componentProperty
+                        .getName());
+                }
+
+                // Default to the many attribute defined on the property
+                componentProperty.setMany(property.isMany());
+
+                // Default to the type and element defined on the property
+                if (componentProperty.getXSDType() == null) {
+                    componentProperty.setXSDType(property.getXSDType());
+                }
+                if (componentProperty.getXSDElement() == null) {
+                    componentProperty.setXSDElement(property.getXSDElement());
+                }
+
+                // Check that a type or element are specified
+                if (componentProperty.getXSDElement() == null && componentProperty.getXSDType() == null) {
+                    warning(monitor, "NoTypeForComponentProperty", component, component.getName(), componentProperty
+                        .getName());
+                }
+            }
+        }
+    }
+
+    /**
+     * Look to see if any value elements have been set into the property
+     * A bit involved as the value is stored as a DOM Document
+     * 
+     * @param property the property to be tested
+     * @return true is values are present
+     */
+    private boolean isPropertyValueSet(Property property) {
+        Document value = (Document)property.getValue();
+
+        if (value == null) {
+            return false;
+        }
+
+        if (value.getFirstChild() == null) {
+            return false;
+        }
+
+        if (value.getFirstChild().getChildNodes().getLength() == 0) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Reconcile component references with the references defined on the
+     * component type.
+     *
+     * @param component
+     * @param references
+     * @param componentReferences
+     * @param monitor
+     */
+    protected void reconcileReferences(Component component,
+                                       Map<String, Reference> references,
+                                       Map<String, ComponentReference> componentReferences,
+                                       Monitor monitor) {
+
+        // Connect each component reference to the corresponding reference
+        for (ComponentReference componentReference : component.getReferences()) {
+            if (componentReference.getReference() != null || componentReference.isForCallback()) {
+                continue;
+            }
+            Reference reference = references.get(componentReference.getName());
+            if (reference != null) {
+                componentReference.setReference(reference);
+            } else {
+                if (!componentReference.getName().startsWith("$self$.")) {
+                    error(monitor, "ReferenceNotFound", component, component.getName(), componentReference.getName());
+                }
+            }
+        }
+
+        // Create a Component reference for each reference for which there is no declared Component reference
+        if (component.getImplementation() != null) {
+            for (Reference reference : component.getImplementation().getReferences()) {
+                if (!componentReferences.containsKey(reference.getName())) {
+                    ComponentReference componentReference = assemblyFactory.createComponentReference();
+                    componentReference.setForCallback(reference.isForCallback());
+                    componentReference.setName(reference.getName());
+                    componentReference.setReference(reference);
+                    component.getReferences().add(componentReference);
+                }
+            }
+        }
+
+        // Reconcile each component reference with its reference
+        for (ComponentReference componentReference : component.getReferences()) {
+            Reference reference = componentReference.getReference();
+            if (reference != null) {
+                // Reconcile multiplicity
+                if (componentReference.getMultiplicity() != null) {
+                    if (!ReferenceConfigurationUtil.isValidMultiplicityOverride(reference.getMultiplicity(),
+                                                                                componentReference.getMultiplicity())) {
+                        error(monitor,
+                              "ReferenceIncompatibleMultiplicity",
+                              component,
+                              component.getName(),
+                              componentReference.getName());
+                    }
+                } else {
+                    componentReference.setMultiplicity(reference.getMultiplicity());
+                }
+
+                // Reconcile interface
+                InterfaceContract interfaceContract = reference.getInterfaceContract();
+                if (componentReference.getInterfaceContract() != null) {
+                    if (interfaceContract != null && !componentReference.getInterfaceContract().equals(reference
+                        .getInterfaceContract())) {
+                        if (!interfaceContractMapper.isCompatible(interfaceContract, componentReference
+                            .getInterfaceContract())) {
+                            error(monitor,
+                                  "ReferenceIncompatibleComponentInterface",
+                                  component,
+                                  component.getName(),
+                                  componentReference.getName());
+                        }
+                    }
+                } else {
+                    componentReference.setInterfaceContract(interfaceContract);
+                }
+
+                // Reconcile bindings
+                if (componentReference.getBindings().isEmpty()) {
+                    componentReference.getBindings().addAll(reference.getBindings());
+                }
+
+                // Reconcile callback bindings
+                if (componentReference.getCallback() == null) {
+                    componentReference.setCallback(reference.getCallback());
+                    if (componentReference.getCallback() == null) {
+                        // Create an empty callback to avoid null check
+                        componentReference.setCallback(assemblyFactory.createCallback());
+                    }
+
+                } else if (componentReference.getCallback().getBindings().isEmpty() && reference.getCallback() != null) {
+                    componentReference.getCallback().getBindings().addAll(reference.getCallback().getBindings());
+                }
+
+                // Propagate autowire setting from the component
+                if (componentReference.getAutowire() == null) {
+                    componentReference.setAutowire(component.getAutowire());
+                }
+
+                // Reconcile targets
+                if (componentReference.getTargets().isEmpty()) {
+                    componentReference.getTargets().addAll(reference.getTargets());
+                }
+            }
+        }
+    }
+
+    /**
+     * Reconcile component services and services defined on the component type.
+     *
+     * @param component
+     * @param services
+     * @param componentServices
+     * @param monitor
+     */
+    protected void reconcileServices(Component component,
+                                     Map<String, Service> services,
+                                     Map<String, ComponentService> componentServices,
+                                     Monitor monitor) {
+
+        // Connect each component service to the corresponding service
+        for (ComponentService componentService : component.getServices()) {
+            if (componentService.getService() != null || componentService.isForCallback()) {
+                continue;
+            }
+            Service service = services.get(componentService.getName());
+            if (service != null) {
+                componentService.setService(service);
+            } else {
+                warning(monitor, "ServiceNotFoundForComponentService", component, component.getName(), componentService
+                    .getName());
+            }
+        }
+
+        // Create a component service for each service
+        if (component.getImplementation() != null) {
+            for (Service service : component.getImplementation().getServices()) {
+                if (!componentServices.containsKey(service.getName())) {
+                    ComponentService componentService = assemblyFactory.createComponentService();
+                    componentService.setForCallback(service.isForCallback());
+                    String name = service.getName();
+                    componentService.setName(name);
+                    componentService.setService(service);
+                    component.getServices().add(componentService);
+                    componentServices.put(name, componentService);
+                }
+            }
+        }
+
+        //Reconcile each component service with its service
+        for (ComponentService componentService : component.getServices()) {
+            Service service = componentService.getService();
+            if (service != null) {
+                // Reconcile interface
+                InterfaceContract interfaceContract = service.getInterfaceContract();
+                if (componentService.getInterfaceContract() != null) {
+                    if (interfaceContract != null && !componentService.getInterfaceContract().equals(interfaceContract)) {
+                        if (!interfaceContractMapper.isCompatible(componentService.getInterfaceContract(),
+                                                                  interfaceContract)) {
+                            // MJE, 16/05/2009 - Upgraded from "warning" to "error" since this is a fatal problem - TUSCANY-3036
+                            error(monitor,
+                                  "ServiceIncompatibleComponentInterface",
+                                  component,
+                                  component.getName(),
+                                  componentService.getName());
+                        }
+                    }
+                } else {
+                    componentService.setInterfaceContract(interfaceContract);
+                }
+
+                // Reconcile bindings
+                if (componentService.getBindings().isEmpty()) {
+                    componentService.getBindings().addAll(service.getBindings());
+                }
+
+                // Reconcile callback bindings
+                if (componentService.getCallback() == null) {
+                    componentService.setCallback(service.getCallback());
+                    if (componentService.getCallback() == null) {
+                        // Create an empty callback to avoid null check
+                        componentService.setCallback(assemblyFactory.createCallback());
+                    }
+                } else if (componentService.getCallback().getBindings().isEmpty() && service.getCallback() != null) {
+                    componentService.getCallback().getBindings().addAll(service.getCallback().getBindings());
+                }
+            }
+        }
+    }
+
+    protected void attachSCABinding(Contract contract, Definitions definitions) {
+        if (!contract.getBindings().isEmpty()) {
+            contract.setOverridingBindings(true);
+            // No need to set binding.sca
+            return;
+        }
+        contract.setOverridingBindings(false);
+
+        // Only add binding.sca for services
+        // FIXME: The latest OASIS spec only adds binding.sca to services
+        /*
+        if (!(contract instanceof Service)) {
+            return;
+        }
+        */
+        SCABinding scaBinding = scaBindingFactory.createSCABinding();
+
+        if (definitions != null) {
+            for (ExtensionType attachPointType : definitions.getBindingTypes()) {
+                if (attachPointType.getType().equals(BINDING_SCA_QNAME)) {
+                    ((PolicySubject)scaBinding).setExtensionType(attachPointType);
+                }
+            }
+        }
+
+        contract.getBindings().add(scaBinding);
+    }
+}

Propchange: tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/BaseBuilderImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/BaseBuilderImpl.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/BindingURIBuilderImpl.java
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/BindingURIBuilderImpl.java?rev=819680&view=auto
==============================================================================
--- tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/BindingURIBuilderImpl.java (added)
+++ tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/BindingURIBuilderImpl.java Mon Sep 28 19:15:06 2009
@@ -0,0 +1,509 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.builder.impl;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.Contract;
+import org.apache.tuscany.sca.assembly.Implementation;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.assembly.builder.CompositeBuilderException;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.definitions.Definitions;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.MonitorFactory;
+
+/**
+ * Configuration of binding URIs.
+ *
+ * @version $Rev$ $Date$
+ */
+public class BindingURIBuilderImpl {
+
+    private Monitor monitor;
+
+    public BindingURIBuilderImpl(ExtensionPointRegistry registry) {
+        UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class);
+        MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class);
+        monitor = monitorFactory.createMonitor();
+    }
+
+    /**
+     * Called by CompositeBindingURIBuilderImpl
+     *
+     * @param composite the composite to be configured
+     */
+    protected void configureBindingURIsAndNames(Composite composite, Definitions definitions, Monitor monitor)
+        throws CompositeBuilderException {
+        configureBindingURIs(composite, null, definitions, null, monitor);
+        configureBindingNames(composite, monitor);
+    }
+
+    /**
+     * Fully resolve the binding URIs based on available information. This includes information
+     * from the ".composite" files, from resources associated with the binding, e.g. WSDL files,
+     * from any associated policies and from the default information for each binding type.
+     *
+     * @param composite the composite to be configured
+     * @param defaultBindings list of default binding configurations
+     */
+    protected void configureBindingURIs(Composite composite,
+                                        Definitions definitions,
+                                        Map<QName, List<String>> defaultBindings,
+                                        Monitor monitor) throws CompositeBuilderException {
+        configureBindingURIs(composite, null, definitions, defaultBindings, monitor);
+    }
+
+    /**
+     * Fully resolve the binding URIs based on available information. This includes information
+     * from the ".composite" files, from resources associated with the binding, e.g. WSDL files,
+     * from any associated policies and from the default information for each binding type.
+     *
+     * NOTE: This method repeats some of the processing performed by the configureComponents()
+     *       method above.  The duplication is needed because NodeConfigurationServiceImpl
+     *       calls this method without previously calling configureComponents().  In the
+     *       normal builder sequence used by CompositeBuilderImpl, both of these methods
+     *       are called.
+     *
+     * TODO: Share the URL calculation algorithm with the configureComponents() method above
+     *       although keeping the configureComponents() methods signature as is because when
+     *       a composite is actually build in a node the node default information is currently
+     *       available
+     *
+     * @param composite the composite to be configured
+     * @param uri the path to the composite provided through any nested composite component implementations
+     * @param defaultBindings list of default binding configurations
+     */
+    private void configureBindingURIs(Composite composite,
+                                      String uri,
+                                      Definitions definitions,
+                                      Map<QName, List<String>> defaultBindings,
+                                      Monitor monitor) throws CompositeBuilderException {
+
+        String parentComponentURI = uri;
+
+        monitor.pushContext("Composite: " + composite.getName().toString());
+        try {
+            // Process nested composites recursively
+            for (Component component : composite.getComponents()) {
+
+                // Initialize component URI
+                String componentURI;
+                if (parentComponentURI == null) {
+                    componentURI = component.getName();
+                } else {
+                    componentURI = URI.create(parentComponentURI + '/').resolve(component.getName()).toString();
+                }
+                component.setURI(componentURI);
+
+                Implementation implementation = component.getImplementation();
+                if (implementation instanceof Composite) {
+                    // Process nested composite
+                    configureBindingURIs((Composite)implementation, componentURI, definitions, defaultBindings, monitor);
+                }
+            }
+
+            // Initialize composite service binding URIs
+            List<Service> compositeServices = composite.getServices();
+            for (Service service : compositeServices) {
+
+                constructBindingNames(service, monitor);
+
+                // Initialize binding names and URIs
+                for (Binding binding : service.getBindings()) {
+                    constructBindingURI(parentComponentURI, composite, service, binding, defaultBindings, monitor);
+                }
+            }
+
+            // Initialize component service binding URIs
+            for (Component component : composite.getComponents()) {
+
+                monitor.pushContext("Component: " + component.getName());
+
+                try {
+
+                    for (ComponentService service : component.getServices()) {
+
+                        constructBindingNames(service, monitor);
+
+                        // Initialize binding names and URIs
+                        for (Binding binding : service.getBindings()) {
+                            constructBindingURI(component, service, binding, defaultBindings, monitor);
+                        }
+                    }
+                } finally {
+                    monitor.popContext();
+                }
+            }
+        } finally {
+            monitor.popContext();
+        }
+    }
+
+    /**
+     * Add default names for callback bindings and reference bindings.  Needs to be
+     * separate from configureBindingURIs() because configureBindingURIs() is called
+     * by NodeConfigurationServiceImpl as well as by CompositeBuilderImpl.
+     */
+    private void configureBindingNames(Composite composite, Monitor monitor) {
+
+        // Process nested composites recursively
+        for (Component component : composite.getComponents()) {
+
+            Implementation implementation = component.getImplementation();
+            if (implementation instanceof Composite) {
+
+                // Process nested composite
+                configureBindingNames((Composite)implementation, monitor);
+            }
+        }
+
+        // Initialize composite service callback binding names
+        for (Service service : composite.getServices()) {
+            constructBindingNames(service, monitor);
+        }
+
+        // Initialize composite reference binding names
+        for (Reference reference : composite.getReferences()) {
+            constructBindingNames(reference, monitor);
+        }
+
+        // Initialize component service and reference binding names
+        for (Component component : composite.getComponents()) {
+
+            // Initialize component service callback binding names
+            for (ComponentService service : component.getServices()) {
+                constructBindingNames(service, monitor);
+            }
+
+            // Initialize component reference binding names
+            for (ComponentReference reference : component.getReferences()) {
+                // Initialize binding names
+                constructBindingNames(reference, monitor);
+            }
+        }
+    }
+
+    /**
+     * If a binding name is not provided by the user, construct it based on the service
+     * or reference name
+     *
+     * @param contract the service or reference
+     */
+    private void constructBindingNames(Contract contract, Monitor monitor) {
+        List<Binding> bindings = contract.getBindings();
+        Map<String, Binding> bindingMap = new HashMap<String, Binding>();
+        for (Binding binding : bindings) {
+            // set the default binding name if one is required
+            // if there is no name on the binding then set it to the service or reference name
+            if (binding.getName() == null) {
+                binding.setName(contract.getName());
+            }
+            Binding existed = bindingMap.put(binding.getName(), binding);
+            // Check that multiple bindings do not have the same name
+            if (existed != null && existed != binding) {
+                if (contract instanceof Service) {
+                    Monitor.error(monitor, this, "assembly-validation-messages", "MultipleBindingsForService", contract
+                        .getName(), binding.getName());
+                } else {
+                    Monitor.error(monitor,
+                                  this,
+                                  "assembly-validation-messages",
+                                  "MultipleBindingsForReference",
+                                  contract.getName(),
+                                  binding.getName());
+                }
+            }
+        }
+
+        if (contract.getCallback() != null) {
+            bindings = contract.getCallback().getBindings();
+            bindingMap.clear();
+            for (Binding binding : bindings) {
+                // set the default binding name if one is required
+                // if there is no name on the binding then set it to the service or reference name
+                if (binding.getName() == null) {
+                    binding.setName(contract.getName());
+                }
+                Binding existed = bindingMap.put(binding.getName(), binding);
+                // Check that multiple bindings do not have the same name
+                if (existed != null && existed != binding) {
+                    if (contract instanceof Service) {
+                        Monitor.error(monitor,
+                                      this,
+                                      "assembly-validation-messages",
+                                      "MultipleBindingsForServiceCallback",
+                                      contract.getName(),
+                                      binding.getName());
+                    } else {
+                        Monitor.error(monitor,
+                                      this,
+                                      "assembly-validation-messages",
+                                      "MultipleBindingsForReferenceCallback",
+                                      contract.getName(),
+                                      binding.getName());
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * URI construction for composite bindings based on Assembly Specification section 1.7.2, This method
+     * assumes that the component URI part of the binding URI is formed from the part to the
+     * composite in question and just calls the generic constructBindingURI method with this
+     * information
+     *
+     * @param parentComponentURI
+     * @param composite
+     * @param service
+     * @param binding
+     * @param defaultBindings
+     */
+    private void constructBindingURI(String parentComponentURI,
+                                     Composite composite,
+                                     Service service,
+                                     Binding binding,
+                                     Map<QName, List<String>> defaultBindings,
+                                     Monitor monitor) throws CompositeBuilderException {
+        // This is a composite service so there is no component to provide a component URI
+        // The path to this composite (through nested composites) is used.
+        constructBindingURI(parentComponentURI, service, binding, defaultBindings, monitor);
+    }
+
+    /**
+     * URI construction for component bindings based on Assembly Specification section 1.7.2. This method
+     * calculates the component URI part based on component information before calling the generic
+     * constructBindingURI method
+     *
+     * @param component the component that holds the service
+     * @param service the service that holds the binding
+     * @param binding the binding for which the URI is being constructed
+     * @param defaultBindings the list of default binding configurations
+     */
+    private void constructBindingURI(Component component,
+                                     Service service,
+                                     Binding binding,
+                                     Map<QName, List<String>> defaultBindings,
+                                     Monitor monitor) throws CompositeBuilderException {
+        constructBindingURI(component.getURI(), service, binding, defaultBindings, monitor);
+    }
+
+    /**
+     * Generic URI construction for bindings based on Assembly Specification section 1.7.2
+     *
+     * @param componentURIString the string version of the URI part that comes from the component name
+     * @param service the service in question
+     * @param binding the binding for which the URI is being constructed
+     * @param includeBindingName when set true the serviceBindingURI part should be used
+     * @param defaultBindings the list of default binding configurations
+     * @throws CompositeBuilderException
+     */
+    private void constructBindingURI(String componentURIString,
+                                     Service service,
+                                     Binding binding,
+                                     Map<QName, List<String>> defaultBindings,
+                                     Monitor monitor) throws CompositeBuilderException {
+
+        try {
+
+            boolean includeBindingName = !service.getName().equals(binding.getName());
+
+            // calculate the service binding URI
+            URI bindingURI;
+            if (binding.getURI() != null) {
+                bindingURI = new URI(binding.getURI());
+
+                // if the user has provided an absolute binding URI then use it
+                if (bindingURI.isAbsolute()) {
+                    binding.setURI(bindingURI.toString());
+                    return;
+                }
+            } else {
+                bindingURI = null;
+            }
+
+            String serviceName = service.getName();
+            // Get the service binding name
+            String bindingName;
+            if (binding.getName() != null) {
+                bindingName = binding.getName();
+            } else {
+                bindingName = serviceName;
+            }
+
+            // calculate the component URI
+            URI componentURI;
+            if (componentURIString != null) {
+                componentURI = new URI(addSlashToPath(componentURIString));
+            } else {
+                componentURI = null;
+            }
+
+            // if the user has provided an absolute component URI then use it
+            if (componentURI != null && componentURI.isAbsolute()) {
+                binding.setURI(constructBindingURI(null,
+                                                   componentURI,
+                                                   bindingURI,
+                                                   serviceName,
+                                                   includeBindingName,
+                                                   bindingName));
+                return;
+            }
+
+            // calculate the base URI
+            URI baseURI = null;
+            if (defaultBindings != null) {
+                List<String> uris = defaultBindings.get(binding.getType());
+                if (uris != null && uris.size() > 0) {
+                    baseURI = new URI(addSlashToPath(uris.get(0)));
+                }
+            }
+
+            binding.setURI(constructBindingURI(baseURI,
+                                               componentURI,
+                                               bindingURI,
+                                               serviceName,
+                                               includeBindingName,
+                                               bindingName));
+        } catch (URISyntaxException ex) {
+            Monitor.error(monitor,
+                          this,
+                          "assembly-validation-messages",
+                          "URLSyntaxException",
+                          componentURIString,
+                          service.getName(),
+                          binding.getName());
+        }
+    }
+
+    /**
+     * Use to ensure that URI paths end in "/" as here we want to maintain the
+     * last path element of an base URI when other URI are resolved against it. This is
+     * not the default behaviour of URI resolution as defined in RFC 2369
+     *
+     * @param path the path string to which the "/" is to be added
+     * @return the resulting path with a "/" added if it not already there
+     */
+    private static String addSlashToPath(String path) {
+        if (path.endsWith("/") || path.endsWith("#")) {
+            return path;
+        } else {
+            return path + "/";
+        }
+    }
+
+    /**
+     * Concatenate binding URI parts together based on Assembly Specification section 1.7.2
+     *
+     * @param baseURI the base of the binding URI
+     * @param componentURI the middle part of the binding URI derived from the component name
+     * @param bindingURI the end part of the binding URI
+     * @param includeBindingName when set true the binding name part should be used
+     * @param bindingName the binding name
+     * @return the resulting URI as a string
+     */
+    private static String constructBindingURI(URI baseURI,
+                                              URI componentURI,
+                                              URI bindingURI,
+                                              String serviceName,
+                                              boolean includeBindingName,
+                                              String bindingName) {
+        String name = includeBindingName ? serviceName + "/" + bindingName : serviceName;
+        String uriString;
+
+        if (baseURI == null) {
+            if (componentURI == null) {
+                if (bindingURI != null) {
+                    uriString = name + "/" + bindingURI.toString();
+                } else {
+                    uriString = name;
+                }
+            } else {
+                if (bindingURI != null) {
+                    if (bindingURI.toString().startsWith("/")) {
+                        uriString = componentURI.resolve(bindingURI).toString();
+                    } else {
+                        uriString = componentURI.resolve(name + "/" + bindingURI).toString();
+                    }
+                } else {
+                    uriString = componentURI.resolve(name).toString();
+                }
+            }
+        } else {
+            if (componentURI == null) {
+                if (bindingURI != null) {
+                    uriString = basedURI(baseURI, bindingURI).toString();
+                } else {
+                    uriString = basedURI(baseURI, URI.create(name)).toString();
+                }
+            } else {
+                if (bindingURI != null) {
+                    uriString = basedURI(baseURI, componentURI.resolve(bindingURI)).toString();
+                } else {
+                    uriString = basedURI(baseURI, componentURI.resolve(name)).toString();
+                }
+            }
+        }
+
+        // tidy up by removing any trailing "/"
+        if (uriString.endsWith("/")) {
+            uriString = uriString.substring(0, uriString.length() - 1);
+        }
+
+        URI uri = URI.create(uriString);
+        if (!uri.isAbsolute()) {
+            uri = URI.create("/").resolve(uri);
+        }
+        return uri.toString();
+    }
+
+    /**
+     * Combine a URI with a base URI.
+     *
+     * @param baseURI
+     * @param uri
+     * @return
+     */
+    private static URI basedURI(URI baseURI, URI uri) {
+        if (uri.getScheme() != null) {
+            return uri;
+        }
+        String str = uri.toString();
+        if (str.startsWith("/")) {
+            str = str.substring(1);
+        }
+        return URI.create(baseURI.toString() + str).normalize();
+    }
+
+}

Propchange: tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/BindingURIBuilderImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tuscany/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/BindingURIBuilderImpl.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date