summaryrefslogtreecommitdiffstats
path: root/tags/java/sca/2.0-M3-RC5/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/ComponentServiceEndpointBuilderImpl.java
blob: 00674b1f278ce2dddaf1f6dd1bc6cc05c4148220 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
/*
 * 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.assembly.builder.impl;

import java.util.List;
import java.util.Vector;

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.ComponentService;
import org.apache.tuscany.sca.assembly.Composite;
import org.apache.tuscany.sca.assembly.CompositeService;
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.Reference;
import org.apache.tuscany.sca.assembly.Service;
import org.apache.tuscany.sca.assembly.builder.CompositeBuilder;
import org.apache.tuscany.sca.assembly.builder.CompositeBuilderException;
import org.apache.tuscany.sca.definitions.Definitions;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.monitor.Monitor;
import org.apache.tuscany.sca.policy.Intent;
import org.apache.tuscany.sca.policy.PolicySet;

/**
 * A composite builder that creates endpoint models for component services.
 *
 * @version $Rev$ $Date$
 */
public class ComponentServiceEndpointBuilderImpl implements CompositeBuilder {
    private AssemblyFactory assemblyFactory;
    
	// Testing
	//boolean useNew = true;
	boolean useNew = false;

    public ComponentServiceEndpointBuilderImpl(AssemblyFactory assemblyFactory) {
        this.assemblyFactory = assemblyFactory;
    }

    public String getID() {
        return "org.apache.tuscany.sca.assembly.builder.ComponentReferenceEndpointReferenceBuilder";
    }

    /**
     * Create endpoint models for all component services.
     * 
     * @param composite - the top-level composite to build the models for
     * @param definitions
     * @param monitor - a Monitor for logging errors
     */
    public void build(Composite composite, Definitions definitions, Monitor monitor) throws CompositeBuilderException {
    
        // process component services
    	if( !useNew ) {
    		processComponentServices(composite);
    	} // end if
        processComponentServices2( composite );
 
    } // end method build
       
    private void processComponentServices(Composite composite) {

        for (Component component : composite.getComponents()) {
           
            // recurse for composite implementations
            Implementation implementation = component.getImplementation();
            if (implementation instanceof Composite) {
                processComponentServices((Composite)implementation);
            }

            // create an endpoint for each component service binding
            for (ComponentService service : component.getServices()) {
                
                Component endpointComponent = component;
                ComponentService endpointService = service;
                
                // TODO - EPR - We maintain all endpoints at the right level now
                //              but endpoints for promoting services must point down
                //              to the services they promote. 
                if (service.getService() instanceof CompositeService) {
                    CompositeService compositeService = (CompositeService)service.getService();
                    endpointService = ServiceConfigurationUtil.getPromotedComponentService(compositeService);
                    endpointComponent = ServiceConfigurationUtil.getPromotedComponent(compositeService);
                } // end if
                               
                for (Binding binding : service.getBindings()){
                    Endpoint endpoint = assemblyFactory.createEndpoint();
                    endpoint.setComponent(endpointComponent);
                    endpoint.setService(endpointService);
                    endpoint.setBinding(binding);
                    endpoint.setUnresolved(false);
                    service.getEndpoints().add(endpoint);
                } // end for
            }
        }
    } // end method processComponentServices
    
    /**
     * @param composite - the composite which contains the component services
     */
    private void processComponentServices2(Composite composite) {
    	for( Component component : composite.getComponents() ) {
    		for( ComponentService service : component.getServices() ) {
    			EndpointInfo theInfo = scanComponentService( component, service, null );
            	
            	List<Binding> theBindings = theInfo.getBindings();
            	// Create an endpoint for each binding which applies to this service
            	// and copy across the information relating to the endpoint.
            	for( Binding binding : theBindings ) {
        			Endpoint endpoint = assemblyFactory.createEndpoint();
                    endpoint.setComponent(theInfo.getComponent());
                    endpoint.setService(theInfo.getComponentService());
                    endpoint.setBinding(binding);
                    endpoint.setInterfaceContract(theInfo.getInterfaceContract());
                    endpoint.getRequiredIntents().addAll(theInfo.getIntents());
                    endpoint.getPolicySets().addAll(theInfo.getPolicySets());
                    endpoint.setUnresolved(false);
                    // Add the endpoint to the component service
                    if( useNew ) {
                    	// Add to top level and leaf level services, if different
                    	service.getEndpoints().add(endpoint);
                    	ComponentService leafService = theInfo.getComponentService();
                    	if( service != leafService ) {
                    		leafService.getEndpoints().add(endpoint);
                    	} // end if 
                    } // end if
                    // debug
                    // disabled for the time being - SL
                    //System.out.println( "Endpoint created for Component = " + component.getName() + " Leaf component = " + 
                    //		endpoint.getComponent().getName() + " service = " + 
                    //		endpoint.getService().getName() + " binding = " + endpoint.getBinding() );
            	} // end for	
    		} // end for
    		// Handle composites as implementations
    		if( component.getImplementation() instanceof Composite ) {
    			processComponentServices2( (Composite) component.getImplementation() );
    		} // end if
    	} // end for
    } // end method processComponentServices2
    
    /**
     * Scan a component service for endpoint information, recursing down to the leafmost promoted service if the component service is
     * implemented by a Composite service
     * @param component - the component
     * @param service - the component service
     * @param theInfo - an EndpointInfo object in which the endpoint information is accumulated. If null on entry, a new EndpointInfo object is created
     * @return - the EndpointInfo object containing the information about the component service
     */
    private EndpointInfo scanComponentService( Component component, ComponentService service, EndpointInfo theInfo ) {
    	if( theInfo == null ) { 
    		theInfo = new EndpointInfo(); 
    	} // end if
    	
        theInfo.setBindings(service.getBindings());
    	theInfo.setInterfaceContract(service.getInterfaceContract());
    	theInfo.setIntents(service.getRequiredIntents());
    	theInfo.setPolicySets(service.getPolicySets());
    	
    	Service implService = service.getService();
    	if( implService instanceof CompositeService ) {
    		// If it is implemented by a Composite, scan through the promoted service
            ComponentService promotedService = ((CompositeService)implService).getPromotedService();
            Component promotedComponent = ((CompositeService)implService).getPromotedComponent();
            if (promotedService != null) {
            	scanComponentService( promotedComponent, promotedService, theInfo );
            } else {
            	// If its a composite service with no promoted component service, it's an error
            } // end if
    	} else {
    		// Otherwise the component and service are the ones at this level
        	theInfo.setComponent(component);
        	theInfo.setComponentService(service);
    	} //end if
    	
        return theInfo;
    } // end method scanPromotedComponentService
    
    private class EndpointInfo {
    	private Component 			leafComponent = null;
    	private ComponentService 	leafComponentService = null;
    	private List<Binding>		bindings = null;
    	private InterfaceContract	contract;
    	private List<Intent>		intents = new Vector<Intent>();
    	private List<PolicySet>		policySets = null;
    	
    	void setComponent( Component component ){
    		leafComponent = component;
    	} // end method
    	
    	Component getComponent() {
    		return leafComponent;
    	} // end method
    	
    	void setComponentService( ComponentService service ) {
    		leafComponentService = service;
    	} // end method
    	
    	ComponentService getComponentService() {
    		return leafComponentService;
    	} // end method
    	
    	void setBindings( List<Binding> theBindings ) {
    		// RULE: Bindings from higher in the hierarchy take precedence
    		if( bindings == null ) {
    			bindings = theBindings;
    		} // end if
    	} // end method
    	
    	List<Binding> getBindings() {
    		return bindings;
    	} // end method
    	
    	void setInterfaceContract( InterfaceContract theInterface ) {
    		// RULE: Interface contract from higher in the hierarchy takes precedence
    		if( contract == null ) {
    			contract = theInterface;
    		} // end if
    	} // end method
    	
    	InterfaceContract getInterfaceContract() {
    		return contract;
    	} // end method

		List<Intent> getIntents() {
			return intents;
		} // end method

		void setIntents(List<Intent> intents) {
			// RULE: Intents accumulate from all levels in the hierarchy
			this.intents.addAll( intents );
		} // end method

		List<PolicySet> getPolicySets() {
			return policySets;
		} // end method

		void setPolicySets(List<PolicySet> policySets) {
			// RULE: Policy Sets from higher in the hierarchy override those lower
			if( this.policySets == null ) {
				this.policySets = policySets;
			} // end if
		} // end method
    	
    	
    } // end class EndpointInfo

} // end class