private List createComponentReferenceTargets()

in modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/BaseWireBuilderImpl.java [400:664]


    private List<Endpoint> createComponentReferenceTargets(Composite composite,
                                                           Map<String, Component> components,
                                                           Map<String, ComponentService> componentServices,
                                                          ComponentReference componentReference) {

        List<Endpoint> endpoints = new ArrayList<Endpoint>();
        
        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;
    }