public void bind()

in modules/core/src/main/java/org/apache/tuscany/sca/core/runtime/impl/EndpointReferenceBinderImpl.java [148:381]


    public void bind(DomainRegistry domainRegistry,  
                     EndpointReference endpointReference,
                     BuilderContext builderContext,
                     boolean runtime){
        
        logger.fine("Binding " + endpointReference.toString());
        
        Audit matchAudit = new Audit();
             
        // This logic does post build autowire matching but isn't actually used at the moment
        // as problems with dependencies mean we still do this during build
        if (endpointReference.getStatus() == EndpointReference.Status.AUTOWIRE_PLACEHOLDER){ 
           
            // do autowire matching
            // will only be called at build time at the moment
            Multiplicity multiplicity = endpointReference.getReference().getMultiplicity();
            for (Endpoint endpoint : domainRegistry.getEndpoints()){
//              if (endpoint is in the same composite as endpoint reference){
                    if ((multiplicity == Multiplicity.ZERO_ONE || 
                         multiplicity == Multiplicity.ONE_ONE) && 
                        (endpointReference.getReference().getEndpointReferences().size() > 1)) {
                        break;
                    }

                    // Prevent autowire connecting to self
                    if (endpointReference.getComponent() == 
                        endpoint.getComponent()) {
                        continue;
                    }
                    
                    if (haveMatchingPolicy(endpointReference, endpoint, matchAudit, builderContext) &&
                        haveMatchingInterfaceContracts(endpointReference, endpoint, matchAudit)){
                        // matching service so find if this reference already has 
                        // an endpoint reference for this endpoint
                        Endpoint autowireEndpoint = null;
                        
                        for (EndpointReference epr : endpointReference.getReference().getEndpointReferences()){
                            if (epr.getTargetEndpoint() == endpoint){
                                autowireEndpoint = endpoint;
                                break;
                            }
                        }
                        
                        if (autowireEndpoint == null){
                            // create new EPR for autowire
                            EndpointReference autowireEndpointRefrence = null;
                            try {
                                autowireEndpointRefrence = (EndpointReference)endpointReference.clone();
                            } catch (Exception ex){
                                // won't happen as clone is supported
                            }
                            
                            autowireEndpointRefrence.setTargetEndpoint(endpoint);
                            autowireEndpointRefrence.setBinding(endpoint.getBinding());
                            autowireEndpointRefrence.setStatus(EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED);
                            endpointReference.getReference().getEndpointReferences().add(autowireEndpointRefrence);  
                        }
                    }
//              }
            }
            
            if (multiplicity == Multiplicity.ONE_N || multiplicity == Multiplicity.ONE_ONE) {
                if (endpointReference.getReference().getEndpointReferences().size() == 1) {
                    Monitor.error(monitor,
                                  this,
                                  "endpoint-validation-messages",
                                  "NoComponentReferenceTarget",
                                  endpointReference.getReference().getName());
                    //throw new ServiceRuntimeException("Unable to bind " +
                    //                                  monitor.getLastProblem().toString());
                }
            }
            
            setSingleAutoWireTarget(endpointReference.getReference());
            
        } else if ( endpointReference.getStatus() == EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED||
                    endpointReference.getStatus() == EndpointReference.Status.RESOLVED_BINDING ) {
            // The endpoint reference is already resolved to either
            // a service endpoint local to this composite or it has
            // a remote binding. Just make sure the binding is built
            build(endpointReference);
            
            // still need to check that the callback endpoint is set correctly
            if (hasCallback(endpointReference) && 
                (endpointReference.getCallbackEndpoint() == null 
                    || endpointReference.getCallbackEndpoint().isUnresolved())) {
                selectCallbackEndpoint(endpointReference,
                                       endpointReference.getReference().getCallbackService(),
                                       matchAudit, 
                                       builderContext, 
                                       runtime);
            } 
        } else if (endpointReference.getStatus() == EndpointReference.Status.WIRED_TARGET_FOUND_READY_FOR_MATCHING ){
            // The endpoint reference is already resolved to either
            // a service endpoint but no binding was specified in the 
            // target URL and/or the policies have yet to be matched.
            // Used when $self references are resolved
            
            selectForwardEndpoint(endpointReference,
                                  endpointReference.getTargetEndpoint().getService().getEndpoints(),
                                  matchAudit,
                                  builderContext,
                                  runtime);

            if (hasCallback(endpointReference)){
                selectCallbackEndpoint(endpointReference,
                                       endpointReference.getReference().getCallbackService(),
                                       matchAudit,
                                       builderContext, 
                                       runtime);
            }             
        } else if (endpointReference.getStatus() == EndpointReference.Status.WIRED_TARGET_IN_BINDING_URI ||
                   endpointReference.getStatus() == EndpointReference.Status.WIRED_TARGET_NOT_FOUND ||
                   endpointReference.getStatus() == EndpointReference.Status.NOT_CONFIGURED){
            // The reference is not yet matched to a service
          
            // find the service in the endpoint registry
            List<Endpoint> endpoints = domainRegistry.findEndpoint(endpointReference);
            
            if (endpoints.size() > 0){
                selectForwardEndpoint(endpointReference,
                        endpoints,
                        matchAudit,
                        builderContext, 
                        runtime);

                // If the reference was matched try to match the callback
                if (endpointReference.getStatus().equals(EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED) &&
                    hasCallback(endpointReference)){
                    selectCallbackEndpoint(endpointReference,
                                           endpointReference.getReference().getCallbackService(),
                                           matchAudit,
                                           builderContext, 
                                           runtime);
                } 
            } else if (runtime) {
                // tweak to test if this could be a resolved binding. This is the back end of the test
                // in the builder that pulls the URI out of the binding if there are no targets
                // on the reference. have to wait until here to see if the binding uri matches any
                // available services. If not we assume here that it's a resolved binding
                if (endpointReference.getStatus() == EndpointReference.Status.WIRED_TARGET_IN_BINDING_URI){
                    endpointReference.getTargetEndpoint().setBinding(endpointReference.getBinding());
                    endpointReference.setStatus(EndpointReference.Status.RESOLVED_BINDING);
                } else {
                    processUnknownEndpoint(endpointReference, matchAudit);
                    
                    if (!endpointReference.getStatus().equals(EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED)){
                        Monitor.error(monitor, 
                                      this, 
                                      "endpoint-validation-messages", 
                                      "NoEndpointsFound", 
                                      endpointReference.toString()); 
                        throw new ServiceRuntimeException(monitor.getMessageString(EndpointReferenceBinderImpl.class.getName(),
                                                                                   "endpoint-validation-messages", 
                                                                                   "UnableToBind") + 
                                                          " " +
                                                          monitor.getLastProblem().toString());
                    }
                }
            } else {
                // it's build time so just give the UnknownEndpoint code a chance
                // without regard for the result
                processUnknownEndpoint(endpointReference, matchAudit);
            }
        } 
        
        logger.fine(matchAudit.toString());

        if (endpointReference.getStatus() != EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED &&
            endpointReference.getStatus() != EndpointReference.Status.RESOLVED_BINDING){
            
            if (runtime){
                Monitor.error(monitor, 
                              this, 
                              "endpoint-validation-messages", 
                              "EndpointReferenceCantBeMatched", 
                              endpointReference.toString(),
                              matchAudit);
                throw new ServiceRuntimeException(monitor.getMessageString(EndpointReferenceBinderImpl.class.getName(),
                                                                           "endpoint-validation-messages", 
                                                                           "UnableToBind") + 
                                                  " " +
                                                  monitor.getLastProblem().toString());
            } else {
                Monitor.warning(monitor, 
                                this, 
                                "endpoint-validation-messages", 
                                "ComponentReferenceTargetNotFound", 
                                endpointReference.toString());
                return;
            }
               

        }
        
        // [rfeng] Setup the target endpoint if the reference uses an explicit binding
        if (endpointReference.getTargetEndpoint().getBinding() == null) {
            endpointReference.getTargetEndpoint().setBinding(endpointReference.getBinding());
        }
        
        // Now the endpoint reference is resolved check that the binding interfaces contract
        // and the reference contract are compatible
        try {
            ((RuntimeEndpointReference)endpointReference).validateReferenceInterfaceCompatibility();
        } catch (ServiceRuntimeException ex) {
            // don't re-throw this exception at build time just record the
            // error. If it's thrown here is messes up the order in which
            // build time errors are reported and that in turn messes
            // up the output of the compliance tests. 
            if (runtime){
                throw ex;
            } else {
                Monitor.error(monitor, 
                        this, 
                        "endpoint-validation-messages", 
                        "EndpointReferenceCantBeMatched", 
                        endpointReference.toString(),
                        ex.getMessage());
            }
        }
        
        // TUSCANY-3783
        // if the reference is an async reference and the binding doesn't support
        // async natively fluff up the response service/endpoint
        ReferenceBindingProvider referenceBindingProvider = ((RuntimeEndpointReference)endpointReference).getBindingProvider();
        if ( referenceBindingProvider instanceof EndpointReferenceAsyncProvider &&
             !((EndpointReferenceAsyncProvider)referenceBindingProvider).supportsNativeAsync() &&
             endpointReference.isAsyncInvocation() && 
             endpointReference.getCallbackEndpoint() == null) {
            ((RuntimeEndpointReference)endpointReference).createAsyncCallbackEndpoint();
        }
    
        // System.out.println("MATCH AUDIT:" + matchAudit.toString());
    }