private void processComponentReference()

in modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/EndpointReferenceBuilderImpl.java [160:353]


    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 targets 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 URI
                    }
    
                    // 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;

                    String[] parts = getSCATargetParts(uri);
                        
                    if (parts != null){
                        // 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);
                        if (binding instanceof SCABinding) {
                            // TUSCANY-3941
                            // if it's an SCA binding we store it to influence the matching at runtime
                            endpointRef.setBinding(binding);
                        }
                        endpointRef.setStatus(EndpointReference.Status.WIRED_TARGET_IN_BINDING_URI);
                    } else { 
                        // 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);
                        endpoint.setRemote(true);
                        endpointRef.setStatus(EndpointReference.Status.RESOLVED_BINDING);
                    }
                    
                    endpointRef.setTargetEndpoint(endpoint);   
                    reference.getEndpointReferences().add(endpointRef);
                }
            }
        } finally {
            context.getMonitor().popContext();
        }             
    }