private void createReferenceEndpointReferences()

in modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/WireBuilderImpl.java [323:603]


    private void createReferenceEndpointReferences(Composite composite,
                                                   Component component,
                                                   ComponentReference reference,
                                                   Map<String, Component> components,
                                                   Map<String, ComponentService> componentServices,
                                                   Monitor monitor) {

        monitor.pushContext("Reference: " + reference.getName());

        // Get reference targets
        List<ComponentService> refTargets = getReferenceTargets(reference);
        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_FOUND_READY_FOR_MATCHING);
                            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(monitor,
                                  this,
                                  Messages.ASSEMBLY_VALIDATION,
                                  "NoComponentReferenceTarget",
                                  reference.getName());
                }
            }

            setSingleAutoWireTarget(reference);

        } else 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(monitor,
                              this,
                              Messages.ASSEMBLY_VALIDATION,
                              "ReferenceEndPointMixWithTarget",
                              composite.getName().toString(),
                              component.getName(),
                              reference.getName());
            }

            // Resolve targets specified on the component reference
            for (ComponentService target : refTargets) {

                String targetName = getComponentServiceName(target.getName());
                String bindingName = getBindingName(target.getName());
                ComponentService targetComponentService = componentServices.get(targetName);

                Component targetComponent = getComponentFromTargetName(components, targetName);

                if (targetComponentService != null) {
                    // Check that target component service provides a superset of the component reference interface
                    if (reference.getInterfaceContract() == null || interfaceContractMapper.isCompatibleSubset(reference
                        .getInterfaceContract(), targetComponentService.getInterfaceContract())) {

                        if (bindingName != null) {
                            // the user has selected a binding as part of the target name
                            Binding targetBinding = null;

                            for (Binding tmp : targetComponentService.getBindings()) {
                                if (tmp.getName().equals(bindingName)) {
                                    targetBinding = tmp;
                                    continue;
                                }
                            }

                            if (targetBinding != null) {
                                EndpointReference endpointRef = createEndpointRef(component, reference, false);
                                endpointRef.setTargetEndpoint(createEndpoint(targetComponent,
                                                                             targetComponentService,
                                                                             targetBinding,
                                                                             true));
                                endpointRef.setStatus(EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED);
                                // relying on the registry here to resolve the real endpoint
                                reference.getEndpointReferences().add(endpointRef);

                            } else {
                                EndpointReference endpointRef = createEndpointRef(component, reference, true);
                                endpointRef.setTargetEndpoint(createEndpoint(component, targetName));
                                endpointRef.setStatus(EndpointReference.Status.WIRED_TARGET_NOT_FOUND);
                                reference.getEndpointReferences().add(endpointRef);
                                Monitor.warning(monitor,
                                                this,
                                                Messages.ASSEMBLY_VALIDATION,
                                                "ComponentReferenceTargetNotFound",
                                                composite.getName().toString(),
                                                targetName);
                            }

                        } else {
                            // the user hasn't selected a binding as part of the target name

                            EndpointReference endpointRef = createEndpointRef(component, reference, false);
                            endpointRef
                                .setTargetEndpoint(createEndpoint(targetComponent, targetComponentService, true));
                            endpointRef.setStatus(EndpointReference.Status.WIRED_TARGET_FOUND_READY_FOR_MATCHING);
                            reference.getEndpointReferences().add(endpointRef);
                        }
                    } else {
                        Monitor.error(monitor,
                                      this,
                                      Messages.ASSEMBLY_VALIDATION,
                                      "ReferenceIncompatibleInterface",
                                      composite.getName().toString(),
                                      component.getName() + "." + reference.getName(),
                                      targetName);
                    }
                } else {
                    // add an unresolved endpoint reference with an unresolved endpoint to go with it
                    EndpointReference endpointRef = createEndpointRef(component, reference, true);
                    endpointRef.setTargetEndpoint(createEndpoint(component, targetName));
                    endpointRef.setStatus(EndpointReference.Status.WIRED_TARGET_NOT_FOUND);
                    reference.getEndpointReferences().add(endpointRef);
                    Monitor.warning(monitor,
                                    this,
                                    Messages.ASSEMBLY_VALIDATION,
                                    "ComponentReferenceTargetNotFound",
                                    composite.getName().toString(),
                                    targetName);
                } // end if
            } // end for
        } // end if

        // if no endpoints have 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

                // user might have put a local target name in the uri - 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
                if (uri.startsWith("/")) {
                    uri = uri.substring(1);
                }

                String targetName = getComponentServiceName(uri);
                String bindingName = getBindingName(uri);

                // Resolve the target component and service
                ComponentService targetComponentService = componentServices.get(targetName);
                Component targetComponent = getComponentFromTargetName(components, targetName);

                // If the binding URI matches a component in the composite, configure an endpoint reference with
                // this component as the target.
                // If not, the binding URI is assumed to reference an external service
                if (targetComponentService != null) {

                    // Check that the target component service provides
                    // a superset of the component reference interface
                    if (reference.getInterfaceContract() == null || interfaceContractMapper.isCompatibleSubset(reference
                        .getInterfaceContract(), targetComponentService.getInterfaceContract())) {
                        if (bindingName != null) {
                            // the user has selected a binding as part of the target name
                            Binding targetBinding = null;

                            for (Binding tmp : targetComponentService.getBindings()) {
                                if (tmp.getName().equals(bindingName)) {
                                    targetBinding = tmp;
                                    continue;
                                }
                            }

                            if (targetBinding != null) {
                                EndpointReference endpointRef = createEndpointRef(component, reference, false);
                                endpointRef.setTargetEndpoint(createEndpoint(targetComponent,
                                                                             targetComponentService,
                                                                             targetBinding,
                                                                             true));
                                endpointRef.setStatus(EndpointReference.Status.WIRED_TARGET_NOT_FOUND);
                                // relying on the registry here to resolve the real endpoint
                                reference.getEndpointReferences().add(endpointRef);

                            } else {
                                EndpointReference endpointRef = createEndpointRef(component, reference, true);
                                endpointRef.setTargetEndpoint(createEndpoint(component, targetName));
                                endpointRef.setStatus(EndpointReference.Status.WIRED_TARGET_NOT_FOUND);
                                reference.getEndpointReferences().add(endpointRef);
                                Monitor.warning(monitor,
                                                this,
                                                Messages.ASSEMBLY_VALIDATION,
                                                "ComponentReferenceTargetNotFound",
                                                composite.getName().toString(),
                                                targetName);
                            }

                        } else {
                            // create endpoint reference with dummy endpoint which will be replaced when policies
                            // are matched and bindings are configured later
                            EndpointReference endpointRef =
                                createEndpointRef(component, reference, binding, null, false);
                            endpointRef
                                .setTargetEndpoint(createEndpoint(targetComponent, targetComponentService, true));
                            endpointRef.setStatus(EndpointReference.Status.WIRED_TARGET_FOUND_READY_FOR_MATCHING);
                            reference.getEndpointReferences().add(endpointRef);
                        }
                    } else {
                        Monitor.warning(monitor,
                                        this,
                                        Messages.ASSEMBLY_VALIDATION,
                                        "ReferenceIncompatibleInterface",
                                        composite.getName().toString(),
                                        reference.getName(),
                                        uri);
                    }
                } else {
                    // create endpoint reference for manually configured bindings with resolved endpoint
                    // to signify that this reference is pointing at some unwired endpoint. The endpoint
                    // is given the configured binding as a representation of the endpoint configuration. 
                    EndpointReference endpointRef = createEndpointRef(component, reference, binding, null, false);
                    Endpoint endpoint = createEndpoint(false);
                    endpoint.setBinding(binding);
                    endpointRef.setTargetEndpoint(endpoint);
                    endpointRef.setStatus(EndpointReference.Status.RESOLVED_BINDING);
                    reference.getEndpointReferences().add(endpointRef);
                } // end if
            }
        }

        monitor.popContext();

    } // end method