/* * 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.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.logging.Logger; 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.Endpoint; import org.apache.tuscany.sca.assembly.EndpointReference; import org.apache.tuscany.sca.assembly.Implementation; import org.apache.tuscany.sca.assembly.Multiplicity; import org.apache.tuscany.sca.assembly.Reference; import org.apache.tuscany.sca.assembly.SCABinding; import org.apache.tuscany.sca.assembly.builder.BuilderContext; import org.apache.tuscany.sca.assembly.builder.CompositeBuilderException; import org.apache.tuscany.sca.assembly.builder.Messages; 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.interfacedef.InterfaceContractMapper; import org.apache.tuscany.sca.monitor.Monitor; import org.apache.tuscany.sca.policy.Intent; import org.oasisopen.sca.ServiceRuntimeException; /** * Creates endpoint reference models. */ public class EndpointReferenceBuilderImpl { private final Logger logger = Logger.getLogger(EndpointReferenceBuilderImpl.class.getName()); private AssemblyFactory assemblyFactory; private InterfaceContractMapper interfaceContractMapper; // causes dependency between builders and core //private EndpointReferenceBinder endpointReferenceBinder; public EndpointReferenceBuilderImpl(ExtensionPointRegistry registry) { UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class); interfaceContractMapper = utilities.getUtility(InterfaceContractMapper.class); FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class); assemblyFactory = modelFactories.getFactory(AssemblyFactory.class); // causes dependency between builders and core //endpointReferenceBinder = registry.getExtensionPoint(EndpointReferenceBinder.class); } /** * Create endpoint references for all component references. * * @param composite */ public Composite build(Composite composite, BuilderContext context) throws CompositeBuilderException { // create endpoint references for each reference createEndpointReferences(composite, context); // validate component references // left until this stage, after all endpoints have been created, // to to catch more complex cases caused by reference promotion validateComponentReferences(composite, context.getMonitor()); // TODO - move the following buld time matching code // to somewhere else because of // the dependency between builders and core // create temporary local registry for all available local endpoints //EndpointRegistry registry = new EndpointRegistryImpl(); // populate the registry with all the endpoints that are present in the model //populateLocalRegistry(composite, registry, context); // match all local services against the endpoint references // we've just created //matchEndpointReferences(composite, registry, context); return composite; } /** * Iterate down through the composites creating end point references for * all component references * * @param composite * @param context */ private void createEndpointReferences(Composite composite, BuilderContext context){ context.getMonitor().pushContext("Composite: " + composite.getName().toString()); try { for (Component component : composite.getComponents()) { context.getMonitor().pushContext("Component: " + component.getName()); try { // recurse for composite implementations Implementation implementation = component.getImplementation(); if (implementation instanceof Composite) { createEndpointReferences((Composite)implementation, context); } for (ComponentReference reference : component.getReferences()) { // create the endpoint references for this component reference processComponentReference(composite, component, reference, context); // we assume that endpoints have already been created so we can now // create the links between enpoint references and endpoints that // represent callbacks fixUpCallbackLinks(component, reference); // 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, context.getMonitor()); } // Validate that references are wired or promoted, according // 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, context.getMonitor()); } finally { context.getMonitor().popContext(); } } } finally { context.getMonitor().popContext(); } } /** * Create endpoint references for a component references. Endpoint references can be * implied by refrence targets, autowire or binding settings * * @param composite * @param component * @param reference * @param context */ private void processComponentReference(Composite composite, Component component, ComponentReference reference, BuilderContext context){ context.getMonitor().pushContext("Reference: " + reference.getName()); try { // Get reference targets List<ComponentService> refTargets = getReferenceTargets(reference); // This autowire processing really needs to move to the matching // algorithm but dependency problems means it has to stay here for now if (Boolean.TRUE.equals(reference.getAutowire()) && reference.getTargets().isEmpty()) { // Find suitable targets in the current composite for an // autowired reference Multiplicity multiplicity = reference.getMultiplicity(); for (Component targetComponent : composite.getComponents()) { // Tuscany specific selection of the first autowire reference // when there are more than one (ASM_60025) if ((multiplicity == Multiplicity.ZERO_ONE || multiplicity == Multiplicity.ONE_ONE) && (reference.getEndpointReferences().size() != 0)) { break; } // Prevent autowire connecting to self if (targetComponent == component) continue; for (ComponentService targetComponentService : targetComponent.getServices()) { if (reference.getInterfaceContract() == null || interfaceContractMapper.isCompatibleSubset(reference.getInterfaceContract(), targetComponentService.getInterfaceContract())) { if (intentsMatch(reference.getRequiredIntents(), targetComponentService.getRequiredIntents())) { EndpointReference endpointRef = createEndpointRef(component, reference, false); endpointRef.setTargetEndpoint(createEndpoint(targetComponent, targetComponentService, true)); endpointRef.setStatus(EndpointReference.Status.WIRED_TARGET_NOT_FOUND); reference.getEndpointReferences().add(endpointRef); // Stop with the first match for 0..1 and 1..1 references if (multiplicity == Multiplicity.ZERO_ONE || multiplicity == Multiplicity.ONE_ONE) { break; } // end if } } // end if } // end for } // end for if (multiplicity == Multiplicity.ONE_N || multiplicity == Multiplicity.ONE_ONE) { if (reference.getEndpointReferences().size() == 0) { Monitor.error(context.getMonitor(), this, Messages.ASSEMBLY_VALIDATION, "NoComponentReferenceTarget", reference.getName()); } } setSingleAutoWireTarget(reference); // as this is the autowire case we ignore any further configuration return; } // check to see if explicit reference targets have been specified if (!refTargets.isEmpty()) { // Check that the component reference does not mix the use of endpoint references // specified via the target attribute with the presence of binding elements if (bindingsIdentifyTargets(reference)) { Monitor.error(context.getMonitor(), this, Messages.ASSEMBLY_VALIDATION, "ReferenceEndPointMixWithTarget", composite.getName().toString(), component.getName(), reference.getName()); } // create endpoint references for targets for (ComponentService target : refTargets) { EndpointReference endpointRef = createEndpointRef(component, reference, true); endpointRef.setTargetEndpoint(createEndpoint(component, target.getName())); endpointRef.setStatus(EndpointReference.Status.WIRED_TARGET_NOT_FOUND); reference.getEndpointReferences().add(endpointRef); // There is a special case where the user has defined policies on a // non-targetted, i.e. no URI, binding.sca in order to control the // intended QoS of the wire when matching takes place. If any other // bindings are specified then the test later on will complain about // mixing targts with bindings if (reference.getBindings().size() == 1){ Binding binding = reference.getBindings().get(0); if ((binding instanceof SCABinding) && (binding.getURI() == null)){ endpointRef.setBinding(binding); } } } } // if no endpoints have been found so far the bindings hold the targets. if (reference.getEndpointReferences().isEmpty()) { for (Binding binding : reference.getBindings()) { String uri = binding.getURI(); // user hasn't put a uri on the binding so it's not a target name and the assumption is that // the target is established via configuration of the binding element itself if (uri == null) { // Regular forward references are UNWIRED with no endpoint if they have an SCABinding with NO targets // and NO URI set - but Callbacks with an SCABinding are wired and need an endpoint if (!reference.isForCallback() && (binding instanceof SCABinding)) continue; // create endpoint reference for manually configured bindings with a resolved endpoint to // signify that this reference is pointing at some unwired endpoint EndpointReference endpointRef = createEndpointRef(component, reference, binding, null, false); if (binding instanceof SCABinding) { // Assume that the system needs to resolve this binding later as // it's the SCA binding endpointRef.setTargetEndpoint(createEndpoint(true)); endpointRef.setStatus(EndpointReference.Status.NOT_CONFIGURED); } else { // The user has configured a binding so assume they know what // they are doing and mark in as already resolved. endpointRef.setTargetEndpoint(createEndpoint(false)); endpointRef.setStatus(EndpointReference.Status.RESOLVED_BINDING); } reference.getEndpointReferences().add(endpointRef); continue; } // end if // if it's an absolute URI then assume that it's a resolved binding try { URI tmpURI = new URI(uri); if (tmpURI.isAbsolute()){ // The user has configured a binding with an absolute URI so assume // they know what they are doing and mark in as already resolved. EndpointReference endpointRef = createEndpointRef(component, reference, binding, null, false); endpointRef.setTargetEndpoint(createEndpoint(false)); endpointRef.setStatus(EndpointReference.Status.RESOLVED_BINDING); reference.getEndpointReferences().add(endpointRef); continue; } } catch (Exception ex){ // do nothing and go to the next bit of code // which assumes that the URI is an SCA usi } // The user has put something in the binding uri but we don't know if it's // a real URI or a target name. We can't tell until we have access to the // fully populated registry at run time. The "createComponent()" call here // will do its best to parse out component/service/binding elements assuming // that the getSCATargetParts detects that there are three "/" separated // parts in the uri. EndpointReference endpointRef = createEndpointRef(component, reference, binding, null, false); Endpoint endpoint = null; try { getSCATargetParts(uri); // the target uri might be an SCA target so create an endpoint // so that the binder can test it against the fully populated // registry endpoint = createEndpoint(component, uri); endpointRef.setStatus(EndpointReference.Status.WIRED_TARGET_IN_BINDING_URI); } catch (Exception ex) { // the target string definitely isn't an SCA target string // so we can assume here that the user has configured a // resolved binding endpoint = createEndpoint(false); endpoint.setURI(uri); endpoint.setBinding(binding); endpointRef.setStatus(EndpointReference.Status.RESOLVED_BINDING); } endpointRef.setTargetEndpoint(endpoint); reference.getEndpointReferences().add(endpointRef); } } } finally { context.getMonitor().popContext(); } } private boolean intentsMatch(List<Intent> referenceIntents, List<Intent> serviceIntents) { Set<Intent> referenceIntentSet = new HashSet<Intent>(referenceIntents); Set<Intent> serviceIntentSet = new HashSet<Intent>(serviceIntents); return referenceIntentSet.equals(serviceIntentSet); } /** * The validate stage is separate from the process stage as endpoint 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(); } } /** * Reference targets have to be resolved in the context in which they are * defined so they can't be pushed down the hierarchy during the static build. * So we wait until we have calculated the endpoint 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()) { // If the user has entered an incorrect promotion string an error will be reported to // tell them but the processing will still reach here so only continue processing // if the promotion chain is well formed if (componentReference != null){ 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) { throw new ServiceRuntimeException(e); } // end try // Copy across details of the inner reference //ComponentReference ref = epRefClone.getReference(); //FIXME epRefClone.setReference(promotedReference); return epRefClone; } /** * For all references in a component check that multiplicity is correct * * @param composite * @param component * @param monitor */ private void validateReferenceMultiplicity(Composite composite, Component component, Monitor monitor) { for (ComponentReference componentReference : component.getReferences()) { if (!validateMultiplicity(componentReference.getMultiplicity(), componentReference.getEndpointReferences())) { if (componentReference.getEndpointReferences().isEmpty()) { // No error 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.isForCallback() && !componentReference.isWiredByImpl()) { Monitor.error(monitor, this, Messages.ASSEMBLY_VALIDATION, "ReferenceWithoutTargets", composite.getName().toString(), componentReference.getName()); } } else { // no error if reference is autowire and more targets // than multiplicity have been found if (Boolean.TRUE.equals(componentReference.getAutowire())) { break; } Monitor.error(monitor, this, Messages.ASSEMBLY_VALIDATION, "TooManyReferenceTargets", componentReference.getName()); } } } } /** * For a single component reference check that multiplicity is correct * * @param multiplicity * @param endpointReferences * @return */ 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. * @param reference - the reference * @return true if the bindings identify a target, false otherwise */ private boolean bindingsIdentifyTargets(ComponentReference reference) { for (Binding binding : reference.getBindings()) { // <binding.sca without a URI does not identify a target if ((binding instanceof SCABinding) && (binding.getURI() == null)) continue; // any other binding implies a target // TODO Processing for other binding types return true; } // end for return false; } // end bindingsIdentifyTargets /** * Helper method which obtains a list of targets for a reference * @param reference - Component reference * @return - the list of targets, which will be empty if there are no targets */ private List<ComponentService> getReferenceTargets(ComponentReference reference) { List<ComponentService> theTargets = reference.getTargets(); if (theTargets.isEmpty()) { // Component reference list of targets is empty, try the implementation reference if (reference.getReference() != null) { theTargets = reference.getReference().getTargets(); } // end if } // end if return theTargets; } // end method getReferenceTargets /** * Helper method to create an Endpoint Reference * @param component * @param reference * @param binding * @param endpoint * @param unresolved * @return the endpoint reference */ private EndpointReference createEndpointRef(Component component, ComponentReference reference, Binding binding, Endpoint endpoint, boolean unresolved) { EndpointReference endpointRef = createEndpointRef(component, reference, unresolved); endpointRef.setBinding(binding); endpointRef.setTargetEndpoint(endpoint); return endpointRef; } // end method /** * Helper method to create an Endpoint Reference * @param component * @param reference * @param unresolved * @return the endpoint reference */ private EndpointReference createEndpointRef(Component component, ComponentReference reference, boolean unresolved) { EndpointReference endpointRef = assemblyFactory.createEndpointReference(); endpointRef.setComponent(component); endpointRef.setReference(reference); endpointRef.setUnresolved(unresolved); return endpointRef; } // end method createEndpointRef /** * Helper method to create an Endpoint * @param unresolved * @return the endpoint */ private Endpoint createEndpoint(boolean unresolved) { Endpoint endpoint = assemblyFactory.createEndpoint(); endpoint.setUnresolved(unresolved); return endpoint; } // end method createEndpoint /** * Separates a target name into component/service/binding parts. Throws an exceptions * if the number of parts <1 or > 3 * @param targetName * @return String[] the recovered target parts */ private String[] getSCATargetParts(String targetName){ String[] parts = targetName.split("/"); if (parts.length < 1 || parts.length > 3) { throw new IllegalArgumentException("Invalid target URI: " + targetName); } return parts; } /** * Helper method to create an Endpoint * * @param component The component that owns the reference * @param targetName It can be one of the following formats * <ul> * <li>componentName * <li>componentName/serviceName * <li>componentName/serviceName/bindingName * </ul> * @return the endpoint */ private Endpoint createEndpoint(Component component, String targetName) { String[] parts = getSCATargetParts(targetName); // Find the parent uri String uri = component.getURI(); int index = uri.lastIndexOf('/'); if (index == -1) { uri = ""; } else { uri = uri.substring(0, index); } if (parts.length >= 1) { // Append the target component name if (uri.length() == 0) { uri = parts[0]; } else { uri = uri + "/" + parts[0]; } } if (parts.length == 3) { // <componentURI>#service-binding(serviceName/bindingName) uri = uri + "#service-binding(" + parts[1] + "/" + parts[2] + ")"; } else if (parts.length == 2) { // <componentURI>#service(serviceName) uri = uri + "#service(" + parts[1] + ")"; } Endpoint endpoint = assemblyFactory.createEndpoint(); endpoint.setUnresolved(true); endpoint.setURI(uri); return endpoint; } // end method createEndpoint /** * Helper method to create an endpoint * @param component * @param service * @param unresolved * @return the endpoint */ private Endpoint createEndpoint(Component component, ComponentService service, boolean unresolved) { Endpoint endpoint = createEndpoint(unresolved); endpoint.setComponent(component); endpoint.setService(service); endpoint.setUnresolved(unresolved); return endpoint; } // end method createEndpoint /** * ASM_5021: where a <reference/> of a <component/> has @autowire=true * and where the <reference/> has a <binding/> child element which * declares a single target service, the reference is wired only to * the single service identified by the <wire/> element */ private void setSingleAutoWireTarget(ComponentReference reference) { if (reference.getEndpointReferences().size() > 1 && reference.getBindings() != null && reference.getBindings().size() == 1) { String uri = reference.getBindings().get(0).getURI(); if (uri != null) { if (uri.indexOf('/') > -1) { // TODO: must be a way to avoid this fiddling int i = uri.indexOf('/'); String c = uri.substring(0, i); String s = uri.substring(i + 1); uri = c + "#service(" + s + ")"; } for (EndpointReference er : reference.getEndpointReferences()) { if (er.getTargetEndpoint() != null && uri.equals(er.getTargetEndpoint().getURI())) { reference.getEndpointReferences().clear(); reference.getEndpointReferences().add(er); return; } } } } } /** * The SCA callback model causes services and references to be automatically created * to present the callback services and references. These are identifiable as their names * will match the name of the forward reference or service to which they relate. In the general * endpoint reference and endpoint processing we will have created endpoints and endpoint references * for these callback services and references. We now need to related forward enspoint references with * callback endpoints and forward endpoints with callback endpoint references. Here's the model... * * Client Component Target Component * Reference (with callback iface) Service (with callback iface) * EndpointReference ----------------------------------> Endpoint * | | * | | * Service \/ (for the callback) Reference \/ (for the callback) * Endpoint <--------------------------------------------EndpointReference * * TODO - there are issues here with callback binding multiplicities and which callback * endpoint is associated with which endpointreference * * @param reference * @param component */ private void fixUpCallbackLinks (Component component, ComponentReference reference){ // fix up the links between endpoint references and endpoints that represent callbacks // [rfeng] Populate the callback endpoints if (reference.getCallbackService() != null) { List<Endpoint> callbackEndpoints = reference.getCallbackService().getEndpoints(); if (!callbackEndpoints.isEmpty()) { for (EndpointReference endpointReference : reference.getEndpointReferences()){ // [rfeng] FIXME: how to select the callback endpoints? endpointReference.setCallbackEndpoint(callbackEndpoints.get(0)); } } } // fix up links between endpoints and endpoint references that represent callbacks for (ComponentService service : component.getServices()) { if ((service.getInterfaceContract() != null) && (service.getInterfaceContract() .getCallbackInterface() != null)) { if (reference.getName().equals(service.getName())) { for (Endpoint endpoint : service.getEndpoints()) { endpoint.getCallbackEndpointReferences().addAll(reference .getEndpointReferences()); } break; } } } } //========================================================================= // methods below related to build time matching which is currently disabled /* private void populateLocalRegistry(Composite composite, EndpointRegistry registry, BuilderContext context){ for (Component component : composite.getComponents()) { // recurse for composite implementations Implementation implementation = component.getImplementation(); if (implementation instanceof Composite) { populateLocalRegistry((Composite)implementation, registry, context); } for (ComponentService service : component.getServices()) { for (Endpoint endpoint : service.getEndpoints()){ registry.addEndpoint(endpoint); } } for (ComponentReference reference : component.getReferences()) { for (EndpointReference epr : reference.getEndpointReferences()){ registry.addEndpointReference(epr); } } // remove all autowire place holders so they don't cause wires to be created // have to pass in reference as we don't have access to the registry in // the builders for (EndpointReference epr : registry.getEndpointReferences()){ if (epr.getStatus() == EndpointReference.Status.AUTOWIRE_PLACEHOLDER){ epr.getReference().getEndpointReferences().remove(epr); } } } } private void matchEndpointReferences(Composite composite, EndpointRegistry registry, BuilderContext context){ // look at all the endpoint references and try to match them to // endpoints for (EndpointReference endpointReference : registry.getEndpointReferences()){ endpointReferenceBinder.bindBuildTime(registry, endpointReference); } } */ }