diff options
Diffstat (limited to 'java/sca/modules')
5 files changed, 205 insertions, 38 deletions
diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/Reference.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/Reference.java index 702826d43e..a20ad4eca6 100644 --- a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/Reference.java +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/Reference.java @@ -46,23 +46,6 @@ public interface Reference extends AbstractReference, Contract { */ void setWiredByImpl(boolean wiredByImpl); - /** - * Returns a boolean value, "false" by default, which indicates whether - * the configuration of this reference is a promotion override for - * another more deeply nested reference. - * - * @return true if the reference is a promotion override - */ - boolean isPromotionOverride(); - - /** - * Sets a boolean value, "false" by default, which indicates whether - * the configuration of this reference is a promotion override for - * another more deeply nested reference. - * - * @param promotionOverride whether the reference is a promotion override - */ - void setPromotionOverride(boolean promotionOverride); /** * Returns the targets of this reference. diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/ReferenceImpl.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/ReferenceImpl.java index af4b3559c5..69d76f238d 100644 --- a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/ReferenceImpl.java +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/ReferenceImpl.java @@ -40,7 +40,6 @@ public class ReferenceImpl extends AbstractReferenceImpl implements Reference, C private boolean wiredByImpl; private List<ComponentService> targets = new ArrayList<ComponentService>(); private Callback callback; - private boolean promotionOverride; private boolean overridingBindings; private List<EndpointReference> endpointReferences = new ArrayList<EndpointReference>(); @@ -99,14 +98,6 @@ public class ReferenceImpl extends AbstractReferenceImpl implements Reference, C this.wiredByImpl = wiredByImpl; } - public boolean isPromotionOverride() { - return promotionOverride; - } - - public void setPromotionOverride(boolean promotionOverride) { - this.promotionOverride = promotionOverride; - } - public List<ComponentService> getTargets() { return targets; } diff --git a/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java b/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java index 431d21179c..85fa783451 100644 --- a/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java +++ b/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java @@ -107,6 +107,7 @@ public class ComponentBuilderImpl { /** * Configure the component based on its component type using OASIS rules * + * @Param outerCompoment the component that uses the parentComposite as its implementation * @Param parentComposite the composite that contains the component being configured. Required for property processing * @param component the component to be configured */ @@ -288,8 +289,8 @@ public class ComponentBuilderImpl { createCallbackService(component, componentReference); // intents - done later in CompositePolicyBuilder - discuss with RF - //calculateIntents(componentService, - // componentTypeService); + // calculateIntents(componentService, + // componentTypeService); // policy sets - done later in CompositePolicyBuilder - discuss with RF // calculatePolicySets(componentService, @@ -301,10 +302,13 @@ public class ComponentBuilderImpl { componentReference.setAutowire(component.getAutowire()); } - // Reconcile targets copying then up the promotion hierarchy - if (componentReference.getTargets().isEmpty()) { - componentReference.getTargets().addAll(componentTypeReference.getTargets()); - } + // TODO - we shouldn't do this as targets must be resolved in the + // context in which they are defined. Leaving here as a reminder + // for the time being + // Reconcile targets copying them up the promotion hierarchy + //if (componentReference.getTargets().isEmpty()) { + // componentReference.getTargets().addAll(componentTypeReference.getTargets()); + //} } } diff --git a/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java b/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java index b1cc873914..cfecb2be17 100644 --- a/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java +++ b/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java @@ -19,6 +19,7 @@ package org.apache.tuscany.sca.builder.impl; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -71,8 +72,12 @@ public class EndpointReferenceBuilderImpl { throws CompositeBuilderException { Monitor monitor = context.getMonitor(); - // process component services + // process component references processComponentReferences(composite, monitor); + + // validate component references + validateComponentReferences(composite, monitor); + return composite; } @@ -123,10 +128,23 @@ public class EndpointReferenceBuilderImpl { } // end if } // end if } // end for + + // push down endpoint references into the leaf component references + // in the case where this component reference promotes a reference from + // a composite implementation + pushDownEndpointReferences(composite, + component, + reference, + monitor); + } // end for // Validate that references are wired or promoted, according - // to their multiplicity + // to their multiplicity. This validates as we go and catches cases + // where a reference has been configured directly incorrectly with its + // immediate multiplicity setting. We re-run this validation again later + // to catch to more complex cases where reference promotion causes + // multiplicity errors. validateReferenceMultiplicity(composite, component, monitor); } finally { @@ -139,6 +157,45 @@ public class EndpointReferenceBuilderImpl { } } // end method processCompoenntReferences + + + /** + * The validate stage is separate from the process stage as enpoint references are + * pushed down the hierarchy. We don't know the full set of endpoint references until + * all processing is complete. Hence we can't validate as we go + * + * @param composite + * @param monitor + */ + private void validateComponentReferences(Composite composite, Monitor monitor) { + + monitor.pushContext("Composite: " + composite.getName().toString()); + try { + // create endpoint references for each component's references + for (Component component : composite.getComponents()) { + monitor.pushContext("Component: " + component.getName()); + + try { + + // recurse for composite implementations + Implementation implementation = component.getImplementation(); + if (implementation instanceof Composite) { + validateComponentReferences((Composite)implementation, monitor); + } + // Validate that references are wired or promoted, according + // to their multiplicity + validateReferenceMultiplicity(composite, component, monitor); + + } finally { + monitor.popContext(); + } + } + + } finally { + monitor.popContext(); + } + + } protected void indexComponentsServicesAndReferences(Composite composite, Map<String, Component> components, @@ -551,11 +608,111 @@ public class EndpointReferenceBuilderImpl { monitor.popContext(); } // end method + + /** + * Reference targets have to be resolved in the context in which they are + * defined so they can't be push down the hierarchy during the static build. + * So we wait until we have calculated the enpoint references before pushing them + * down. Muliplicity errors will be caught by the multiplicity validation check that + * comes next + * + * @param composite + * @param component + * @param reference + * @param monitor + */ + private void pushDownEndpointReferences(Composite composite, + Component component, + ComponentReference componentReference, + Monitor monitor) { + Reference reference = componentReference.getReference(); + + if (reference instanceof CompositeReference) { + List<ComponentReference> leafComponentReferences = getPromotedComponentReferences((CompositeReference)reference); + + // for each leaf component reference copy in the endpoint references for this + // higher level (promoting) reference + // TODO - the elements are inserted starting at 0 here because the code allows references multiplicity + // validation constraints to be broken if the reference is autowire. At runtime the + // first one is chosen if max multiplicity is 1. We have an OSOA test that assumes that + // promoted references overwrite leaf references. This insert gives the same effect in the + // autowire case. We need to think about if there is a more correct answer. + for (ComponentReference leafRef : leafComponentReferences){ + int insertLocation = 0; + for (EndpointReference epr : componentReference.getEndpointReferences()){ + // copy the epr + EndpointReference eprCopy = copyHigherReference(epr, leafRef); + leafRef.getEndpointReferences().add(insertLocation, eprCopy); + insertLocation++; + } + } + } + + // TODO - what to do about callbacks in the reference promotion case + } + + /** + * Follow a reference promotion chain down to the innermost (non composite) + * component references. + * + * @param compositeReference + * @return + */ + private List<ComponentReference> getPromotedComponentReferences(CompositeReference compositeReference) { + List<ComponentReference> componentReferences = new ArrayList<ComponentReference>(); + collectPromotedComponentReferences(compositeReference, componentReferences); + return componentReferences; + } + + /** + * Follow a reference promotion chain down to the innermost (non composite) + * component references. + * + * @param compositeReference + * @param componentReferences + * @return + */ + private void collectPromotedComponentReferences(CompositeReference compositeReference, + List<ComponentReference> componentReferences) { + for (ComponentReference componentReference : compositeReference.getPromotedReferences()) { + Reference reference = componentReference.getReference(); + if (reference instanceof CompositeReference) { + + // Continue to follow the reference promotion chain + collectPromotedComponentReferences((CompositeReference)reference, componentReferences); + + } else if (reference != null) { + + // Found a non-composite reference + componentReferences.add(componentReference); + } + } + } + + /** + * Copy a higher level EndpointReference down to a lower level reference which it promotes + * @param epRef - the endpoint reference + * @param promotedReference - the promoted reference + * @return - a copy of the EndpointReference with data merged from the promoted reference + */ + private EndpointReference copyHigherReference(EndpointReference epRef, ComponentReference promotedReference) { + EndpointReference epRefClone = null; + try { + epRefClone = (EndpointReference)epRef.clone(); + } catch (Exception e) { + // Ignore (we know that EndpointReference2 can be cloned) + } // end try + // Copy across details of the inner reference + ComponentReference ref = epRefClone.getReference(); + //FIXME + epRefClone.setReference(promotedReference); + return epRefClone; + } private void validateReferenceMultiplicity(Composite composite, Component component, Monitor monitor) { for (ComponentReference componentReference : component.getReferences()) { - if (!ReferenceConfigurationUtil.validateMultiplicityAndTargets(componentReference.getMultiplicity(), - componentReference.getEndpointReferences())) { + if (!validateMultiplicity(componentReference.getMultiplicity(), + componentReference.getEndpointReferences())) { if (componentReference.getEndpointReferences().isEmpty()) { // No error if the reference is promoted out of the current composite @@ -592,6 +749,38 @@ public class EndpointReferenceBuilderImpl { } } + + private boolean validateMultiplicity(Multiplicity multiplicity, List<EndpointReference> endpointReferences) { + + // In some tests multiplicity is not set + if (multiplicity == null) { + return true; + } + + // Count targets + int count = endpointReferences.size(); + + switch (multiplicity) { + case ZERO_N: + break; + case ZERO_ONE: + if (count > 1) { + return false; + } + break; + case ONE_ONE: + if (count != 1) { + return false; + } + break; + case ONE_N: + if (count < 1) { + return false; + } + break; + } + return true; + } /** * Evaluates whether the bindings attached to a reference identify one or more target services. diff --git a/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ModelBuilderImpl.java b/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ModelBuilderImpl.java index 206afb98da..5679b1751d 100644 --- a/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ModelBuilderImpl.java +++ b/java/sca/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ModelBuilderImpl.java @@ -98,7 +98,7 @@ public class ModelBuilderImpl implements CompositeBuilder { // and discards the included composite composite = compositeIncludeBuilder.build(composite, context); - // Set up the structural URIs for components (services/references/bindings?) + // Set up the structural URIs for components (services/references/bindings) composite = structuralURIBuilder.build(composite, context); // need to apply policy external attachment @@ -127,7 +127,7 @@ public class ModelBuilderImpl implements CompositeBuilder { composite = componentReferenceBindingBuilder.build(composite, context); // binding specific build endpointBuilder.build(composite, context); endpointReferenceBuilder.build(composite, context); - composite = componentReferencePromotionBuilder.build(composite, context); // move into the static build? + //composite = componentReferencePromotionBuilder.build(composite, context); // move into the static build? composite = compositePolicyBuilder.build(composite, context); // the rest of the policy processing? // For debugging - in success cases |