/* * 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.assembly.builder.impl; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.tuscany.sca.assembly.AssemblyFactory; 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.CompositeReference; import org.apache.tuscany.sca.assembly.CompositeService; import org.apache.tuscany.sca.assembly.ConfiguredOperation; import org.apache.tuscany.sca.assembly.Endpoint; import org.apache.tuscany.sca.assembly.EndpointFactory; import org.apache.tuscany.sca.assembly.Implementation; import org.apache.tuscany.sca.assembly.Multiplicity; import org.apache.tuscany.sca.assembly.OperationsConfigurator; import org.apache.tuscany.sca.assembly.OptimizableBinding; import org.apache.tuscany.sca.assembly.Reference; import org.apache.tuscany.sca.assembly.SCABinding; import org.apache.tuscany.sca.assembly.Service; import org.apache.tuscany.sca.assembly.Wire; import org.apache.tuscany.sca.assembly.builder.DefaultEndpointBuilder; import org.apache.tuscany.sca.assembly.builder.EndpointBuilder; 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.monitor.impl.ProblemImpl; import org.apache.tuscany.sca.policy.util.PolicyComputationUtils; /** * A composite builder that handles wiring inside a composite. * * @version $Rev$ $Date$ */ class BaseWireBuilderImpl { private Monitor monitor; private AssemblyFactory assemblyFactory; private EndpointFactory endpointFactory; private InterfaceContractMapper interfaceContractMapper; private Map bindingMap; private EndpointBuilder endpointBuilder; protected BaseWireBuilderImpl(AssemblyFactory assemblyFactory, EndpointFactory endpointFactory, InterfaceContractMapper interfaceContractMapper, Monitor monitor, Map bindingMap) { this.assemblyFactory = assemblyFactory; this.endpointFactory = endpointFactory; this.interfaceContractMapper = interfaceContractMapper; this.monitor = monitor; this.bindingMap = bindingMap; this.endpointBuilder = new DefaultEndpointBuilder(monitor, bindingMap); } /** * Wire component references to component services and connect promoted * services/references to component services/references inside a composite. * * @param composite */ protected void wireComponentReferences(Composite composite) { // Wire nested composites recursively for (Component component : composite.getComponents()) { Implementation implementation = component.getImplementation(); if (implementation instanceof Composite) { wireComponentReferences((Composite)implementation); } } // Index components, services and references Map components = new HashMap(); Map componentServices = new HashMap(); Map componentReferences = new HashMap(); indexComponentsServicesAndReferences(composite, components, componentServices, componentReferences); // Connect composite services and references to the component // services and references that they promote //connectCompositeServices(composite, components, componentServices); //connectCompositeReferences(composite, componentReferences); // Compute the policies before connecting component references //computePolicies(composite); // Connect component references as described in wires connectWires(composite, componentServices, componentReferences); // Connect component references to their targets connectComponentReferences(composite, components, componentServices, componentReferences); // Validate that references are wired or promoted, according // to their multiplicity for (ComponentReference componentReference : componentReferences.values()) { if (!ReferenceConfigurationUtil.validateMultiplicityAndTargets(componentReference.getMultiplicity(), componentReference .getTargets(), componentReference.getBindings())) { if (componentReference.getTargets().isEmpty()) { // No warning if the reference is promoted out of the current composite boolean promoted = false; for (Reference reference : composite.getReferences()) { CompositeReference compositeReference = (CompositeReference)reference; if (compositeReference.getPromotedReferences().contains(componentReference)) { promoted = true; break; } } if (!promoted && !componentReference.isCallback()) { warning("ReferenceWithoutTargets", composite, composite.getName().toString(), componentReference.getName()); } } else { warning("TooManyReferenceTargets", composite, componentReference.getName()); } } } // Finally clear the original reference target lists as we now have // bindings to represent the targets for (ComponentReference componentReference : componentReferences.values()) { componentReference.getTargets().clear(); } } /** * Index components, services and references inside a composite. * @param composite * @param components * @param componentServices * @param componentReferences */ private void indexComponentsServicesAndReferences(Composite composite, Map components, Map componentServices, Map 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); 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.isCallback()) && (!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); } } } /** * Report a warning. * * @param problems * @param message * @param model */ private void warning(String message, Object model, String... messageParameters) { if (monitor != null) { Problem problem = new ProblemImpl(this.getClass().getName(), "assembly-validation-messages", Severity.WARNING, model, message, (Object[])messageParameters); monitor.problem(problem); } } /** * Report a exception. * * @param problems * @param message * @param model */ private void error(String message, Object model, Exception ex) { if (monitor != null) { Problem problem = null; problem = new ProblemImpl(this.getClass().getName(), "assembly-validation-messages", Severity.ERROR, model, message, ex); monitor.problem(problem); } } /** * Connect composite references and services to the reference and services that they promote. * * @param composite * @param componentServices * @param problems */ protected void connectCompositeReferencesAndServices(Composite composite){ // Wire nested composites recursively for (Component component : composite.getComponents()) { Implementation implementation = component.getImplementation(); if (implementation instanceof Composite) { connectCompositeReferencesAndServices((Composite)implementation); } } // Index components, services and references Map components = new HashMap(); Map componentServices = new HashMap(); Map componentReferences = new HashMap(); indexComponentsServicesAndReferences(composite, components, componentServices, componentReferences); // Connect composite services and references to the component // services and references that they promote connectCompositeServices(composite, components, componentServices); connectCompositeReferences(composite, componentReferences); } /** * Connect composite services to the component services that they promote. * * @param composite * @param componentServices * @param problems */ private void connectCompositeServices(Composite composite, Map components, Map componentServices) { // Propagate interfaces from inner composite components' services to // their component services for (Component component : composite.getComponents()) { if (component.getImplementation() instanceof Composite) { for (ComponentService componentService : component.getServices()) { Service service = componentService.getService(); if (service != null) { if (componentService.getInterfaceContract() == null) { componentService.setInterfaceContract(service.getInterfaceContract()); } } } } } // Connect composite services to the component services that they // promote for (Service service : composite.getServices()) { CompositeService compositeService = (CompositeService)service; ComponentService componentService = compositeService.getPromotedService(); if (componentService != null && componentService.isUnresolved()) { String promotedComponentName = compositeService.getPromotedComponent().getName(); String promotedServiceName; if (componentService.getName() != null) { promotedServiceName = promotedComponentName + '/' + componentService.getName(); } else { promotedServiceName = promotedComponentName; } ComponentService promotedService = componentServices.get(promotedServiceName); if (promotedService != null) { // Point to the resolved component Component promotedComponent = components.get(promotedComponentName); compositeService.setPromotedComponent(promotedComponent); // Point to the resolved component service compositeService.setPromotedService(promotedService); // Use the interface contract from the component service if // none is specified on the composite service InterfaceContract compositeServiceInterfaceContract = compositeService.getInterfaceContract(); InterfaceContract promotedServiceInterfaceContract = promotedService.getInterfaceContract(); if (compositeServiceInterfaceContract == null) { compositeService.setInterfaceContract(promotedServiceInterfaceContract); } else if (promotedServiceInterfaceContract != null) { // Check the compositeServiceInterfaceContract and promotedServiceInterfaceContract boolean isCompatible = interfaceContractMapper.isCompatible(compositeServiceInterfaceContract, promotedServiceInterfaceContract); if(!isCompatible){ warning("ServiceInterfaceNotSubSet", compositeService, promotedServiceName); } } } else { warning("PromotedServiceNotFound", composite, composite.getName().toString(), promotedServiceName); } } } } /** * Resolves promoted references. * * @param composite * @param componentReferences * @param problems */ private void connectCompositeReferences(Composite composite, Map componentReferences) { // Propagate interfaces from inner composite components' references to // their component references for (Component component : composite.getComponents()) { if (component.getImplementation() instanceof Composite) { for (ComponentReference componentReference : component.getReferences()) { Reference reference = componentReference.getReference(); if (reference != null) { if (componentReference.getInterfaceContract() == null) { componentReference.setInterfaceContract(reference.getInterfaceContract()); } } } } } // Connect composite references to the component references // that they promote for (Reference reference : composite.getReferences()) { CompositeReference compositeReference = (CompositeReference)reference; List promotedReferences = compositeReference.getPromotedReferences(); for (int i = 0, n = promotedReferences.size(); i < n; i++) { ComponentReference componentReference = promotedReferences.get(i); if (componentReference.isUnresolved()) { String componentReferenceName = componentReference.getName(); componentReference = componentReferences.get(componentReferenceName); if (componentReference != null) { // Point to the resolved component reference promotedReferences.set(i, componentReference); // Use the interface contract from the component // reference if none // is specified on the composite reference InterfaceContract compositeReferenceInterfaceContract = compositeReference.getInterfaceContract(); InterfaceContract componentReferenceInterfaceContract = componentReference.getInterfaceContract(); if (compositeReferenceInterfaceContract == null) { compositeReference.setInterfaceContract(componentReferenceInterfaceContract); } else if (componentReferenceInterfaceContract != null) { // Check the compositeInterfaceContract and componentInterfaceContract boolean isCompatible = interfaceContractMapper.isCompatible(compositeReferenceInterfaceContract, componentReferenceInterfaceContract); if (!isCompatible) { warning("ReferenceInterfaceNotSubSet", compositeReference, componentReferenceName); } } } else { warning("PromotedReferenceNotFound", composite, composite.getName().toString(), componentReferenceName); } } } } } private List createComponentReferenceTargets(Composite composite, Map components, Map componentServices, ComponentReference componentReference) { List endpoints = new ArrayList(); if (!componentReference.getTargets().isEmpty()) { // Check if the component reference does not mix the use of endpoints specified via // binding elements with target endpoints specified via the target attribute for (Binding binding : componentReference.getBindings()) { if (binding.getURI() != null) { warning("ReferenceEndPointMixWithTarget", composite, componentReference.getName()); } } // Resolve targets specified on the component reference for (ComponentService componentService : componentReference.getTargets()) { // Resolve the target component and service String name = componentService.getName(); ComponentService targetComponentService = componentServices.get(name); Component targetComponent; int s = name.indexOf('/'); if (s == -1) { targetComponent = components.get(name); } else { targetComponent = components.get(name.substring(0, s)); } if (targetComponentService != null) { // Check that the target component service provides // a superset of the component reference interface if (componentReference.getInterfaceContract() == null || interfaceContractMapper.isCompatible(componentReference.getInterfaceContract(), targetComponentService.getInterfaceContract())) { Endpoint endpoint = endpointFactory.createEndpoint(); endpoint.setTargetName(targetComponent.getName()); endpoint.setSourceComponent(null); // TODO - fixed up at start endpoint.setSourceComponentReference(componentReference); endpoint.setInterfaceContract(componentReference.getInterfaceContract()); endpoint.setTargetComponent(targetComponent); endpoint.setTargetComponentService(targetComponentService); endpoint.getCandidateBindings().addAll(componentReference.getBindings()); endpoints.add(endpoint); // mark the reference target as resolved. Used later when we are looking to // see if an sca binding is associated with a resolved target or not componentService.setUnresolved(false); } else { warning("ReferenceIncompatibleInterface", composite, composite.getName().toString(), componentReference.getName(), componentService.getName()); } } else { // add all the reference bindings into the target so that they // can be used for comparison when the target is resolved at runtime componentService.getBindings().addAll(componentReference.getBindings()); Endpoint endpoint = endpointFactory.createEndpoint(); endpoint.setTargetName(name); endpoint.setSourceComponent(null); // TODO - fixed up at start endpoint.setSourceComponentReference(componentReference); endpoint.setInterfaceContract(componentReference.getInterfaceContract()); endpoint.getCandidateBindings().addAll(componentReference.getBindings()); endpoints.add(endpoint); // The bindings will be cloned back into the reference when the // target is finally resolved. warning("ComponentReferenceTargetNotFound", composite, composite.getName().toString(), componentService.getName()); } } } else if ((componentReference.getReference() != null) && (!componentReference.getReference().getTargets().isEmpty())) { // Resolve targets from the corresponding reference in the // componentType for (ComponentService componentService : componentReference.getReference().getTargets()) { // Resolve the target component and service String name = componentService.getName(); ComponentService targetComponentService = componentServices.get(name); Component targetComponent; int s = name.indexOf('/'); if (s == -1) { targetComponent = components.get(name); } else { targetComponent = components.get(name.substring(0, s)); } if (targetComponentService != null) { // Check that the target component service provides // a superset of // the component reference interface if (componentReference.getInterfaceContract() == null || interfaceContractMapper.isCompatible(componentReference.getInterfaceContract(), targetComponentService.getInterfaceContract())) { Endpoint endpoint = endpointFactory.createEndpoint(); endpoint.setTargetName(targetComponent.getName()); endpoint.setSourceComponent(null); // TODO - fixed up at start endpoint.setSourceComponentReference(componentReference); endpoint.setInterfaceContract(componentReference.getInterfaceContract()); endpoint.setTargetComponent(targetComponent); endpoint.setTargetComponentService(targetComponentService); endpoint.getCandidateBindings().addAll(componentReference.getBindings()); endpoints.add(endpoint); // mark the reference target as resolved. Used later when we are looking to // see if an sca binding is associated with a resolved target or not componentService.setUnresolved(false); } else { warning("ComponentIncompatibleInterface", composite, componentReference.getName(), componentService.getName()); } } else { // add all the reference bindings into the target so that they // can be used for comparison when the target is resolved at runtime componentService.getBindings().addAll(componentReference.getBindings()); // The bindings will be cloned back into the reference when the // target is finally resolved. Endpoint endpoint = endpointFactory.createEndpoint(); endpoint.setTargetName(name); endpoint.setSourceComponent(null); // TODO - fixed up at start endpoint.setSourceComponentReference(componentReference); endpoint.setInterfaceContract(componentReference.getInterfaceContract()); endpoint.getCandidateBindings().addAll(componentReference.getBindings()); endpoints.add(endpoint); warning("ComponentReferenceTargetNotFound", composite, composite.getName().toString(), componentService.getName()); } } } else if (componentReference.getAutowire() == Boolean.TRUE) { // Find suitable targets in the current composite for an // autowired reference Multiplicity multiplicity = componentReference.getMultiplicity(); for (Component targetComponent : composite.getComponents()) { // prevent autowire connecting to self boolean skipSelf = false; for (ComponentReference targetComponentReference : targetComponent.getReferences()) { if (componentReference == targetComponentReference){ skipSelf = true; } } if (!skipSelf){ for (ComponentService targetComponentService : targetComponent.getServices()) { if (componentReference.getInterfaceContract() == null || interfaceContractMapper.isCompatible(componentReference.getInterfaceContract(), targetComponentService.getInterfaceContract())) { Endpoint endpoint = endpointFactory.createEndpoint(); endpoint.setTargetName(targetComponent.getName()); endpoint.setSourceComponent(null); // TODO - fixed up at start endpoint.setSourceComponentReference(componentReference); endpoint.setInterfaceContract(componentReference.getInterfaceContract()); endpoint.setTargetComponent(targetComponent); endpoint.setTargetComponentService(targetComponentService); endpoint.getCandidateBindings().addAll(componentReference.getBindings()); endpoints.add(endpoint); if (multiplicity == Multiplicity.ZERO_ONE || multiplicity == Multiplicity.ONE_ONE) { break; } } } } } if (multiplicity == Multiplicity.ONE_N || multiplicity == Multiplicity.ONE_ONE) { if (endpoints.size() == 0) { warning("NoComponentReferenceTarget", componentReference, componentReference.getName()); } } } // if no endpoints have found so far retrieve any target names that are in binding URIs if (endpoints.isEmpty()){ for (Binding binding : componentReference.getBindings()) { String uri = binding.getURI(); // user hasn't put a uri on the binding so it's not a target name if (uri == null) { continue; } // user might have put a local target name in the uri so get // the path part and see if it refers to a target we know about // - if it does the reference binding will be matched with a service binding // - if it doesn't it is assumed to be an external reference Component targetComponent = null; ComponentService targetComponentService = null; String path = null; try { path = URI.create(uri).getPath(); } catch(Exception ex){ // just assume that no target is identified if // a URI related exception is thrown } if (path != null) { if (path.startsWith("/")) { path = path.substring(1); } // Resolve the target component and service targetComponentService = componentServices.get(path); int s = path.indexOf('/'); if (s == -1) { targetComponent = components.get(path); } else { targetComponent = components.get(path.substring(0, s)); } } // if the path of the binding URI matches a component in the // composite then configure an endpoint with this component as the target // if not then the binding URI will be assumed to reference an external service if (targetComponentService != null) { // Check that the target component service provides // a superset of the component reference interface if (componentReference.getInterfaceContract() == null || interfaceContractMapper.isCompatible(componentReference.getInterfaceContract(), targetComponentService.getInterfaceContract())) { Endpoint endpoint = endpointFactory.createEndpoint(); endpoint.setTargetName(targetComponent.getName()); endpoint.setSourceComponent(null); // TODO - fixed up at start endpoint.setSourceComponentReference(componentReference); endpoint.setInterfaceContract(componentReference.getInterfaceContract()); endpoint.setTargetComponent(targetComponent); endpoint.setTargetComponentService(targetComponentService); endpoint.getCandidateBindings().add(binding); endpoints.add(endpoint); } else { warning("ReferenceIncompatibleInterface", composite, composite.getName().toString(), componentReference.getName(), uri); } } else { // create endpoints for manually configured bindings Endpoint endpoint = endpointFactory.createEndpoint(); endpoint.setTargetName(uri); endpoint.setSourceComponent(null); // TODO - fixed up at start endpoint.setSourceComponentReference(componentReference); endpoint.setInterfaceContract(componentReference.getInterfaceContract()); endpoint.setSourceBinding(binding); endpoints.add(endpoint); } } } return endpoints; } /** * Connect references to their targets. * * @param composite * @param componentServices * @param componentReferences * @param problems */ private void connectComponentReferences(Composite composite, Map components, Map componentServices, Map componentReferences){ for (ComponentReference componentReference : componentReferences.values()) { List endpoints = createComponentReferenceTargets(composite, components, componentServices, componentReference); componentReference.getEndpoints().addAll(endpoints); // the result of calculating the endpoints is either that bindings have been // configured manually using a URI or that targets have been provided and the // endpoint remains unresolved. So all endpoints should be either resved or uresolved. boolean endpointsRequireAutomaticResolution = false; for(Endpoint endpoint : endpoints){ endpointsRequireAutomaticResolution = endpoint.isUnresolved(); } // build each endpoint if (endpointsRequireAutomaticResolution) { for(Endpoint endpoint : endpoints){ endpointBuilder.build(endpoint); } // TODO - The following step ensures that the reference binding list remains // as the record of resolved targets for now. This needs fixing so // that the endpoint takes on this responsibility. componentReference.getBindings().clear(); if (componentReference.getCallback() != null){ componentReference.getCallback().getBindings().clear(); } for(Endpoint endpoint : endpoints){ if (endpoint.isUnresolved() == false){ componentReference.getBindings().add(endpoint.getSourceBinding()); if (componentReference.getCallback() != null){ componentReference.getCallback().getBindings().add(endpoint.getSourceCallbackBinding()); } } } } else { // do nothing as no targets have been specified so the bindings // in the reference binding list are assumed to be manually configured } /* // Select the reference bindings matching the target service bindings List selectedBindings = new ArrayList(); List selectedCallbackBindings = null; // Handle callback boolean bidirectional = false; if (componentReference.getInterfaceContract() != null && componentReference.getInterfaceContract().getCallbackInterface() != null) { bidirectional = true; selectedCallbackBindings = new ArrayList(); } for (Target target : targets) { Component targetComponent = target.getComponent(); ComponentService targetComponentService = target.getService(); if (targetComponentService.getService() instanceof CompositeService) { CompositeService compositeService = (CompositeService) targetComponentService.getService(); // Find the promoted component service targetComponentService = ServiceConfigurationUtil.getPromotedComponentService(compositeService); } try { PolicyConfigurationUtil.determineApplicableBindingPolicySets(componentReference, targetComponentService); } catch ( Exception e ) { warning("Policy related exception: " + e, e); //throw new RuntimeException(e); } // Match the binding against the bindings of the target service Binding selected = BindingConfigurationUtil.resolveBindings(componentReference, targetComponent, targetComponentService, bindingMap); if (selected == null) { warning("NoMatchingBinding", componentReference, componentReference.getName(), targetComponentService.getName()); } else { selectedBindings.add(selected); } if (bidirectional) { Binding selectedCallback = BindingConfigurationUtil.resolveCallbackBindings(componentReference, targetComponent, targetComponentService, bindingMap); if (selectedCallback != null) { selectedCallbackBindings.add(selectedCallback); } } } */ // Need to tidy up the reference binding list and add in the bindings that // have been selected above. The situation so far... // Wired reference (1 or more targets are specified) // Binding.uri = null - remove as it's left over from target resolution // the binding will have been moved to the target from where // it will be resolved later // Binding.uri != null - the selected and resolved reference binding // Unwired reference (0 targets) // Binding.uri = null - Either a callback reference or the reference is yet to be wired // by the implementation so leave the binding where it is // Binding.uri != null - from the composite file so leave it /* if ((componentReference.getTargets().size() > 0) || (!targets.isEmpty())) { // Add all the effective bindings componentReference.getBindings().clear(); componentReference.getBindings().addAll(selectedBindings); if (bidirectional) { componentReference.getCallback().getBindings().clear(); componentReference.getCallback().getBindings().addAll(selectedCallbackBindings); } // add in sca bindings to represent all unresolved targets. The sca binding // will try to resolve the target at a later date. for (ComponentService service : componentReference.getTargets()) { if (service.isUnresolved()) { SCABinding scaBinding = null; // find the sca binding amongst the candidate binding list. We want to // find this one and clone it as it may have been configured with // policies for (Binding binding : service.getBindings()) { if (binding instanceof SCABinding) { try { scaBinding = (SCABinding)((OptimizableBinding)binding).clone(); } catch (CloneNotSupportedException ex){ // we know it is supported on the SCA binding } break; } } if (scaBinding != null) { // configure the cloned SCA binding for this reference target scaBinding.setName(service.getName()); // this service object holds the list of candidate bindings which // can be used for later matching ((OptimizableBinding)scaBinding).setTargetComponentService(service); componentReference.getBindings().add(scaBinding); } else { // not sure we need to raise a warning here as a warning will already been // thrown previously to indicate the reason why there is no sca binding // warning("NoSCABindingAvailableForUnresolvedService", componentReference, componentReference.getName(), service.getName()); } } } } */ // Connect the optimizable bindings to their target component and // service /* for (Binding binding : componentReference.getBindings()) { if (!(binding instanceof OptimizableBinding)) { continue; } OptimizableBinding optimizableBinding = (OptimizableBinding)binding; if (optimizableBinding.getTargetComponentService() != null) { continue; } String uri = optimizableBinding.getURI(); if (uri == null) { continue; } uri = URI.create(uri).getPath(); if (uri.startsWith("/")) { uri = uri.substring(1); } // Resolve the target component and service ComponentService targetComponentService = componentServices.get(uri); Component targetComponent; int s = uri.indexOf('/'); if (s == -1) { targetComponent = components.get(uri); } else { targetComponent = components.get(uri.substring(0, s)); } if (targetComponentService != null) { // Check that the target component service provides // a superset of the component reference interface if (componentReference.getInterfaceContract() == null || interfaceContractMapper.isCompatible(componentReference.getInterfaceContract(), targetComponentService.getInterfaceContract())) { } else { warning("ReferenceIncompatibleInterface", composite, composite.getName().toString(), componentReference.getName(), uri); } optimizableBinding.setTargetComponent(targetComponent); optimizableBinding.setTargetComponentService(targetComponentService); optimizableBinding.setTargetBinding(targetComponentService.getBinding(optimizableBinding.getClass())); } } */ } } /** * Resolve wires and connect the sources to their targets * * @param composite * @param componentServices * @param componentReferences * @param problems */ private void connectWires(Composite composite, Map componentServices, Map componentReferences) { // For each wire, resolve the source reference, the target service, and // add it to the list of targets of the reference List wires = composite.getWires(); for (int i = 0, n = wires.size(); i < n; i++) { Wire wire = wires.get(i); ComponentReference resolvedReference; ComponentService resolvedService; // Resolve the source reference ComponentReference source = wire.getSource(); if (source != null && source.isUnresolved()) { resolvedReference = componentReferences.get(source.getName()); if (resolvedReference != null) { wire.setSource(resolvedReference); } else { warning("WireSourceNotFound", composite, source.getName()); } } else { resolvedReference = wire.getSource(); } // Resolve the target service ComponentService target = wire.getTarget(); if (target != null && target.isUnresolved()) { resolvedService = componentServices.get(target.getName()); if (resolvedService != null) { wire.setTarget(target); } else { warning("WireTargetNotFound", composite, source.getName()); } } else { resolvedService = wire.getTarget(); } // Add the target service to the list of targets of the // reference if (resolvedReference != null && resolvedService != null) { // Check that the target component service provides // a superset of // the component reference interface if (resolvedReference.getInterfaceContract() == null || interfaceContractMapper .isCompatible(resolvedReference.getInterfaceContract(), resolvedService.getInterfaceContract())) { //resolvedReference.getTargets().add(resolvedService); resolvedReference.getTargets().add(wire.getTarget()); } else { warning("WireIncompatibleInterface", composite, source.getName(), target.getName()); } } } // Clear the list of wires composite.getWires().clear(); } private void addPoliciesFromPromotedService(CompositeService compositeService) { //inherit intents and policies from promoted service PolicyComputationUtils.addInheritedIntents(compositeService.getPromotedService().getRequiredIntents(), compositeService.getRequiredIntents()); PolicyComputationUtils.addInheritedPolicySets(compositeService.getPromotedService().getPolicySets(), compositeService.getPolicySets(), true); addInheritedOperationConfigurations(compositeService.getPromotedService(), compositeService); } private void addPoliciesFromPromotedReference(CompositeReference compositeReference) { for ( Reference promotedReference : compositeReference.getPromotedReferences() ) { PolicyComputationUtils.addInheritedIntents(promotedReference.getRequiredIntents(), compositeReference.getRequiredIntents()); PolicyComputationUtils.addInheritedPolicySets(promotedReference.getPolicySets(), compositeReference.getPolicySets(), true); addInheritedOperationConfigurations(promotedReference, compositeReference); } } protected void computePolicies(Composite composite) { // compute policies recursively for (Component component : composite.getComponents()) { Implementation implementation = component.getImplementation(); if (implementation instanceof Composite) { computePolicies((Composite)implementation); } } for (Component component : composite.getComponents()) { // Inherit default policies from the component to component-level contracts. // This must be done BEFORE computing implementation policies because the // implementation policy computer removes from the component any // intents and policy sets that don't apply to implementations. PolicyConfigurationUtil.inheritDefaultPolicies(component, component.getServices()); PolicyConfigurationUtil.inheritDefaultPolicies(component, component.getReferences()); Implementation implemenation = component.getImplementation(); try { PolicyConfigurationUtil.computeImplementationIntentsAndPolicySets(implemenation, component); } catch ( Exception e ) { error("PolicyRelatedException", implemenation, e); //throw new RuntimeException(e); } for (ComponentService componentService : component.getServices()) { Service service = componentService.getService(); if (service != null) { // reconcile intents and policysets from componentType PolicyComputationUtils.addInheritedIntents(service.getRequiredIntents(), componentService.getRequiredIntents()); PolicyComputationUtils.addInheritedPolicySets(service.getPolicySets(), componentService.getPolicySets(), true); //reconcile intents and policysets for operations boolean notFound; List opsFromComponentType = new ArrayList(); for ( ConfiguredOperation ctsConfOp : service.getConfiguredOperations() ) { notFound = true; for ( ConfiguredOperation csConfOp : componentService.getConfiguredOperations() ) { if ( csConfOp.getName().equals(ctsConfOp.getName()) ) { PolicyComputationUtils.addInheritedIntents(ctsConfOp.getRequiredIntents(), csConfOp.getRequiredIntents()); PolicyComputationUtils.addInheritedPolicySets(ctsConfOp.getPolicySets(), csConfOp.getPolicySets(), true); notFound = false; } } if ( notFound ) { opsFromComponentType.add(ctsConfOp); } } componentService.getConfiguredOperations().addAll(opsFromComponentType); } try { //compute the intents for operations under service element PolicyConfigurationUtil.computeIntentsForOperations(componentService); //compute intents and policyset for each binding //addInheritedOpConfOnBindings(componentService); PolicyConfigurationUtil.computeBindingIntentsAndPolicySets(componentService); PolicyConfigurationUtil.determineApplicableBindingPolicySets(componentService, null); } catch ( Exception e ) { error("PolicyRelatedException", componentService, e); //throw new RuntimeException(e); } } for (ComponentReference componentReference : component.getReferences()) { Reference reference = componentReference.getReference(); if (reference != null) { // reconcile intents and policysets PolicyComputationUtils.addInheritedIntents(reference.getRequiredIntents(), componentReference.getRequiredIntents()); PolicyComputationUtils.addInheritedPolicySets(reference.getPolicySets(), componentReference.getPolicySets(), true); } try { //compute the intents for operations under reference element PolicyConfigurationUtil.computeIntentsForOperations(componentReference); //compute intents and policyset for each binding //addInheritedOpConfOnBindings(componentReference); PolicyConfigurationUtil.computeBindingIntentsAndPolicySets(componentReference); PolicyConfigurationUtil.determineApplicableBindingPolicySets(componentReference, null); if ( componentReference.getCallback() != null ) { PolicyComputationUtils.addInheritedIntents(componentReference.getRequiredIntents(), componentReference.getCallback().getRequiredIntents()); PolicyComputationUtils.addInheritedPolicySets(componentReference.getPolicySets(), componentReference.getCallback().getPolicySets(), false); } } catch ( Exception e ) { error("PolicyRelatedException", componentReference, e); //throw new RuntimeException(e); } } } PolicyConfigurationUtil.inheritDefaultPolicies(composite, composite.getServices()); PolicyConfigurationUtil.inheritDefaultPolicies(composite, composite.getReferences()); //compute policies for composite service bindings for (Service service : composite.getServices()) { addPoliciesFromPromotedService((CompositeService)service); try { //compute the intents for operations under service element PolicyConfigurationUtil.computeIntentsForOperations(service); //add or merge service operations to the binding //addInheritedOpConfOnBindings(service); PolicyConfigurationUtil.computeBindingIntentsAndPolicySets(service); PolicyConfigurationUtil.determineApplicableBindingPolicySets(service, null); } catch ( Exception e ) { error("PolicyRelatedException", service, e); //throw new RuntimeException(e); } } for (Reference reference : composite.getReferences()) { CompositeReference compReference = (CompositeReference)reference; addPoliciesFromPromotedReference(compReference); try { //compute the intents for operations under service element PolicyConfigurationUtil.computeIntentsForOperations(reference); //addInheritedOpConfOnBindings(reference); if (compReference.getCallback() != null) { PolicyComputationUtils.addInheritedIntents(compReference.getRequiredIntents(), compReference.getCallback().getRequiredIntents()); PolicyComputationUtils.addInheritedPolicySets(compReference.getPolicySets(), compReference.getCallback().getPolicySets(), false); } PolicyConfigurationUtil.computeBindingIntentsAndPolicySets(reference); PolicyConfigurationUtil.determineApplicableBindingPolicySets(reference, null); } catch ( Exception e ) { error("PolicyRelatedException", reference, e); //throw new RuntimeException(e); } } } private void addInheritedOperationConfigurations(OperationsConfigurator source, OperationsConfigurator target) { boolean found = false; List additionalOperations = new ArrayList(); for ( ConfiguredOperation sourceConfOp : source.getConfiguredOperations() ) { for ( ConfiguredOperation targetConfOp : target.getConfiguredOperations() ) { if ( sourceConfOp.getName().equals(targetConfOp.getName())) { PolicyComputationUtils.addInheritedIntents(sourceConfOp.getRequiredIntents(), targetConfOp.getRequiredIntents()); PolicyComputationUtils.addInheritedPolicySets(sourceConfOp.getPolicySets(), targetConfOp.getPolicySets(), true); found = true; break; } } if ( !found ) { additionalOperations.add(sourceConfOp); } } if ( !additionalOperations.isEmpty() ) { target.getConfiguredOperations().addAll(additionalOperations); } } }