This project has retired. For details please refer to its Attic page.
BPEL2UDDI.java

BPEL2UDDI.java

/*
 * Copyright 2001-2011 The Apache Software Foundation.
 * 
 * Licensed 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.juddi.v3.client.mapping.wsdl;

import org.apache.juddi.v3.client.mapping.Common2UDDI;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.wsdl.Binding;
import javax.wsdl.Definition;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.WSDLException;
import javax.xml.namespace.QName;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.juddi.api_v3.AccessPointType;
import org.apache.juddi.jaxb.PrintUDDI;
import org.apache.juddi.v3.annotations.AnnotationProcessor;
import org.apache.juddi.v3.client.config.Property;
import org.apache.juddi.v3.client.config.UDDIClerk;
import org.apache.juddi.v3.client.config.UDDIKeyConvention;
import org.apache.juddi.v3.client.mapping.URLLocalizer;
import org.apache.juddi.v3.client.transport.TransportException;
import org.uddi.api_v3.AccessPoint;
import org.uddi.api_v3.BindingTemplate;
import org.uddi.api_v3.BusinessService;
import org.uddi.api_v3.CategoryBag;
import org.uddi.api_v3.FindBinding;
import org.uddi.api_v3.FindTModel;
import org.uddi.api_v3.GetTModelDetail;
import org.uddi.api_v3.InstanceDetails;
import org.uddi.api_v3.KeyedReference;
import org.uddi.api_v3.Name;
import org.uddi.api_v3.OverviewDoc;
import org.uddi.api_v3.OverviewURL;
import org.uddi.api_v3.TModel;
import org.uddi.api_v3.TModelBag;
import org.uddi.api_v3.TModelDetail;
import org.uddi.api_v3.TModelInfo;
import org.uddi.api_v3.TModelInstanceDetails;
import org.uddi.api_v3.TModelInstanceInfo;
import org.uddi.api_v3.TModelList;
import org.w3c.dom.Element;


/**
 * BPEL4WS abstract processes describe the observable behavior of Web services. They 
 * complement abstract WSDL interfaces (port types and operations) and the UDDI model 
 * by defining dependencies between service operations in the context of a message 
 * exchange. The technical note 'uddi-spec-tc-tn-bpel' describes the relationships 
 * between the three models and suggests how BPEL4WS abstract processes can be used 
 * in a UDDI Registry. This class implements the registrations suggestions as put 
 * forward in the technote.
 * 
 * * @author Kurt T Stam <kurt.stam@apache.org>
 *
 */
public class BPEL2UDDI extends AnnotationProcessor {
	
	private Log log = LogFactory.getLog(this.getClass());
	
	private String keyDomainURI;
	private UDDIClerk clerk;
	private String lang;
	private URLLocalizer urlLocalizer;
	private String businessKey;
	private Properties properties = new Properties();

	private WSDL2UDDI wsdl2UDDI;
	
	public BPEL2UDDI(UDDIClerk clerk, URLLocalizer urlLocalizer, Properties properties) throws ConfigurationException {
		super();
		
		this.clerk = clerk;
		this.urlLocalizer = urlLocalizer;
		this.properties = properties;
		
		//Obtaining values from the properties
		this.keyDomainURI = "uddi:" + properties.getProperty("keyDomain") + ":";
		this.businessKey = UDDIKeyConvention.getBusinessKey(properties);
		this.lang = properties.getProperty(Property.LANG,Property.DEFAULT_LANG);
		
		this.wsdl2UDDI = new WSDL2UDDI(clerk, urlLocalizer, properties);
	}
	
	public String getKeyDomainURI() {
		return keyDomainURI;
	}

	public void setKeyDomainURI(String keyDomainURI) {
		this.keyDomainURI = keyDomainURI;
	}
	
	public UDDIClerk getClerk() {
		return clerk;
	}

	public void setClerk(UDDIClerk clerk) {
		this.clerk = clerk;
	}
	
	public String getLang() {
		return lang;
	}

	public void setLang(String lang) {
		this.lang = lang;
	}
	
	public URLLocalizer getUrlLocalizer() {
		return urlLocalizer;
	}

	public void setUrlLocalizer(URLLocalizer urlLocalizer) {
		this.urlLocalizer = urlLocalizer;
	}

	/**
	 * 1. Register PortType tModels
	 * 2. Register WSDL BPEL4WS Process
	 * 3. Register WSDL Port
	 * 4. Register Process Service
	 * 5. Register Binding
	 * 
	 * @param serviceName - QName of the service
	 * @param portName - portName of the service
	 * @param serviceUrl - URL at which the service can be invoked
	 * @param wsdlDefinition - WSDL Definition of the Web Service
         * @return a binding template
	 * @throws WSDLException 
	 * @throws MalformedURLException 
	 * @throws TransportException 
	 * @throws ConfigurationException 
	 * @throws RemoteException 
	 */
	@SuppressWarnings("unchecked")
	public BindingTemplate register(QName serviceName, String portName, URL serviceUrl, Definition wsdlDefinition) 
		throws WSDLException, MalformedURLException, RemoteException, ConfigurationException, TransportException 
	{
		String targetNamespace = wsdlDefinition.getTargetNamespace();
		String genericWSDLURL  = wsdlDefinition.getDocumentBaseURI();   //TODO maybe point to repository version
		String bpelOverviewURL = "http://localhost:8080/bpel-console/"; //TODO maybe point to bpel in console
		
		String serviceKey = UDDIKeyConvention.getServiceKey(properties, serviceName.getLocalPart());
		BusinessService service = lookupService(serviceKey);
		if (service==null) {
			List<TModel> tModels = new ArrayList<TModel>();
			// Create the PortType tModels
			Map<QName,PortType> portTypes = (Map<QName,PortType>) wsdlDefinition.getAllPortTypes();
			tModels.addAll(createWSDLPortTypeTModels(genericWSDLURL, portTypes));
			// Create the Binding tModels
			Map<QName,Binding> bindings = (Map<QName,Binding>) wsdlDefinition.getAllBindings();
			tModels.addAll(createWSDLBindingTModels(genericWSDLURL, bindings));
			// Create the BPEL4WS tModel
			TModel bpel4WSTModel = createBPEL4WSProcessTModel(serviceName, targetNamespace, portTypes, bpelOverviewURL);
		    tModels.add(bpel4WSTModel);
		    // Register these tModels
		    for (TModel tModel : tModels) {
				clerk.register(tModel);
			}
		    // BPEL Service
		    service = createBusinessService(serviceName, wsdlDefinition);
		    // Register this BPEL Service
		    clerk.register(service);
		}
		//Add the BindingTemplate to this Service
		BindingTemplate binding = createBPELBinding(serviceName, portName, serviceUrl, wsdlDefinition);
		// Register BindingTemplate
		clerk.register(binding);
		return binding;
	}
	
	public String unRegister(QName serviceName, String portName, URL serviceUrl) throws RemoteException, ConfigurationException, TransportException {
		
		String serviceKey = UDDIKeyConvention.getServiceKey(properties, serviceName.getLocalPart());
		BusinessService service = lookupService(serviceKey);
		boolean isRemoveServiceIfNoTemplates = true; 
		String bindingKey = UDDIKeyConvention.getBindingKey(properties, serviceName, portName, serviceUrl);
		//check if this bindingKey is in the service's binding templates
		for (BindingTemplate bindingTemplate : service.getBindingTemplates().getBindingTemplate()) {
			if (bindingKey.equals(bindingTemplate.getBindingKey())) {
				clerk.unRegisterBinding(bindingKey);
				//if this is the last binding for this service, and 
				if (service.getBindingTemplates().getBindingTemplate().size()==1 && isRemoveServiceIfNoTemplates) {
					clerk.unRegisterService(serviceKey);
					
					FindTModel findTmodelForProcessName = createFindTModelForProcessName(serviceName);
					TModelList tModelList = clerk.findTModel(findTmodelForProcessName);
					if (tModelList!=null && tModelList.getTModelInfos()!=null && tModelList.getTModelInfos().getTModelInfo()!=null) {
						TModelInfo tModelInfo = tModelList.getTModelInfos().getTModelInfo().get(0);
						String bpel4WSTModelKey = tModelInfo.getTModelKey();
						clerk.unRegisterTModel(bpel4WSTModelKey);
						// now use this key to find the portType TModels
						GetTModelDetail findAllPortTypesForProcess = createFindAllPortTypesForProcess_1(bpel4WSTModelKey);
						TModelDetail tModelDetail = clerk.getTModelDetail(findAllPortTypesForProcess);
						if (tModelDetail!=null) {
							List<TModel> tModelPortTypeList = tModelDetail.getTModel();
							if (tModelPortTypeList!=null && tModelPortTypeList.size()>0) {
								TModel bpel4WSTModel = tModelPortTypeList.get(0);
								CategoryBag categoryBag = bpel4WSTModel.getCategoryBag();
								if (categoryBag!=null && categoryBag.getKeyedReference()!=null) {
									List<KeyedReference> portTypeTModelKeys = new ArrayList<KeyedReference>();
									KeyedReference namespaceRef = null;
									for (KeyedReference keyedReference : categoryBag.getKeyedReference()) {
										if ("uddi:uddi.org:wsdl:porttypereference".equals(keyedReference.getTModelKey()) ) {
											portTypeTModelKeys.add(keyedReference);
										}
										if ("uddi:uddi.org:xml:namespace".equals(keyedReference.getTModelKey()) ) {
											namespaceRef = keyedReference;
										}
									}
									String namespace = null;
									if (namespaceRef!=null) namespace = namespaceRef.getKeyValue();
									//find the bindingTModel
									for (KeyedReference keyedReference : portTypeTModelKeys) {
										FindTModel findBindingTModel = WSDL2UDDI.createFindBindingTModelForPortType(keyedReference.getKeyValue(), namespace);
										TModelList bindingTmodels = clerk.findTModel(findBindingTModel);
										if (bindingTmodels!=null && bindingTmodels.getTModelInfos()!=null && bindingTmodels.getTModelInfos().getTModelInfo()!=null) {
											for (TModelInfo bindingTModelInfo : bindingTmodels.getTModelInfos().getTModelInfo()) {
												//delete the Binding TModel
												clerk.unRegisterTModel(bindingTModelInfo.getTModelKey());
											}
										}
										//delete the PortType TModel
										clerk.unRegisterTModel(keyedReference.getKeyValue());	
									}
 								}
							}
						}
					}
				}
				break;
			}
		}
		return service.getServiceKey();	
	}
	/**
	 * Perform a lookup by serviceKey, and will return null if not found.
	 * @param serviceKey
	 * @return a business service
	 * @throws RemoteException
	 * @throws ConfigurationException
	 * @throws TransportException
	 */
	public BusinessService lookupService(String serviceKey) throws RemoteException, ConfigurationException, TransportException {
		
		//Checking if this serviceKey already exist
		BusinessService service = clerk.getServiceDetail(serviceKey);
		return service;
	}
	/**
	 * Registers the Service into UDDI.
	 * 
	 * @param serviceName
	 * @param wsdlDefinition
	 * @return a business service
	 */
	public BusinessService createBusinessService(QName serviceName, Definition wsdlDefinition) {
		
		log.debug("Constructing Service UDDI Information for " + serviceName);
		BusinessService service = new BusinessService();
		// BusinessKey
		service.setBusinessKey(businessKey);
		// ServiceKey
		service.setServiceKey(UDDIKeyConvention.getServiceKey(properties, serviceName.getLocalPart()));
		// Description
		String serviceDescription = properties.getProperty(Property.SERVICE_DESCRIPTION, Property.DEFAULT_SERVICE_DESCRIPTION);
		if (wsdlDefinition.getService(serviceName) !=null) {
			// Override with the service description from the WSDL if present
			Element docElement = wsdlDefinition.getService(serviceName).getDocumentationElement();
			if (docElement!=null && docElement.getTextContent()!=null) {
				serviceDescription = docElement.getTextContent();
			}
		}
		
		service.getDescription().addAll(Common2UDDI.mapDescription(serviceDescription, lang));
		// Service name
		Name sName = new Name();
		sName.setLang(lang);
		sName.setValue(serviceName.getLocalPart());
		service.getName().add(sName);
		
		//customization to add KeyedReferences into the categoryBag of the service
		if (properties.containsKey(Property.SERVICE_CATEGORY_BAG)) {
			String serviceCategoryBag = properties.getProperty(Property.SERVICE_CATEGORY_BAG);
			log.debug("Adding KeyedReferences '" +  serviceCategoryBag + "' to service " + serviceName.getLocalPart());
			CategoryBag categoryBag = parseCategoryBag(serviceCategoryBag);
	        service.setCategoryBag(categoryBag);
		}
		
		return service;
	}
	
	public Set<TModel> createWSDLPortTypeTModels(String wsdlURL, Map<QName,PortType> portTypes) throws WSDLException 
	{
		return wsdl2UDDI.createWSDLPortTypeTModels(wsdlURL, portTypes);
	}
	
	public Set<TModel> createWSDLBindingTModels(String wsdlURL, Map<QName,Binding> bindings) throws WSDLException 
	{
		return wsdl2UDDI.createWSDLBindingTModels(wsdlURL, bindings);
	}
	
	/**
	 * BPEL4WS abstract processes are published as separate UDDI tModels. They are named with the BPEL4WS process 
	 * name. They are categorized as BPEL4WS process definitions, using a category system defined in this 
	 * technical note. Their overviewDoc references an external BPEL4WS document that contains the process definition.
	 * All WSDL portTypes that are used in the BPEL4WS process definition (via the referenced BPEL4WS partnerLinkTypes) 
	 * are published as portType tModels according to [WSDL2UDDI]. The process tModel references all such WSDL portType
	 * tModels, using the WSDL portType Reference tModel defined in [WSDL2UDDI]. Note that it is a characteristic 
	 * of the BPEL4WS process that it defines a conversation based on WSDL portTypes. Thus, the relationship 
	 * between process tModel and portType tModel is to be published by the process tModel publisher, not by 
	 * the portType tModel publisher, which may be a different person.
	 * 
	 * In the current implementation it is all registered by the same publisher. 
	 * 
	 * @param serviceName
	 * @param targetNamespace
	 * @param portTypes
	 * @param bpelOverviewURL
	 * @return tmodels
	 */
    public TModel createBPEL4WSProcessTModel(QName serviceName, String targetNamespace, Map<QName,PortType> portTypes, String bpelOverviewURL) {
    	TModel tModel = new TModel();
    	// Set the Key
    	tModel.setTModelKey(keyDomainURI + serviceName.getLocalPart() + "Process");
    	// Set the Name
    	Name name = new Name();
    	name.setLang("en");
    	name.setValue(serviceName.getLocalPart());
    	tModel.setName(name);
    	// Set the OverviewURL
    	OverviewURL overviewURL = new OverviewURL();
    	overviewURL.setValue("http://localhost:8080/bpel-console/"); //should point to the bpel of this process, maybe in guvnor
    	OverviewDoc overviewDoc = new OverviewDoc();
    	overviewDoc.setOverviewURL(overviewURL);
    	tModel.getOverviewDoc().add(overviewDoc);
    	// Set the categoryBag
    	CategoryBag categoryBag = new CategoryBag();
    	
    	if (targetNamespace!=null) {
    		KeyedReference namespaceReference = WSDL2UDDI.newKeyedReference(
    			"uddi:uddi.org:xml:namespace", "uddi-org:xml:namespace", targetNamespace);
    		categoryBag.getKeyedReference().add(namespaceReference);
    	}
    	KeyedReference typesReference = WSDL2UDDI.newKeyedReference(
    			"uddi:uddi.org:bpel:types", "uddi-org:bpel:types", "process");
    	categoryBag.getKeyedReference().add(typesReference);
    	for (QName qName : portTypes.keySet()) {
    		String portTypeKey = keyDomainURI + qName.getLocalPart();
	    	KeyedReference portTypeReference = WSDL2UDDI.newKeyedReference(
	    			"uddi:uddi.org:wsdl:porttypereference", "uddi-org:wsdl:portTypeReference", portTypeKey);
	    	categoryBag.getKeyedReference().add(portTypeReference);
    	}
    	
    	tModel.setCategoryBag(categoryBag);
    	
    	if (log.isDebugEnabled()) {
    		log.debug(new PrintUDDI<TModel>().print(tModel));
    	}
    	
    	return tModel;
    }
    
    public BindingTemplate createBPELBinding(QName serviceName, String portName, URL serviceUrl, Definition wsdlDefinition) {
		
    	BindingTemplate bindingTemplate = new BindingTemplate();
		// Set BusinessService Key
		bindingTemplate.setServiceKey(UDDIKeyConvention.getServiceKey(properties, serviceName.getLocalPart()));
		// Set Binding Key
		String bindingKey = UDDIKeyConvention.getBindingKey(properties, serviceName, portName, serviceUrl);
		bindingTemplate.setBindingKey(bindingKey);
		// Set AccessPoint
		AccessPoint accessPoint = new AccessPoint();
		accessPoint.setUseType(AccessPointType.END_POINT.toString());
		accessPoint.setValue(urlLocalizer.rewrite(serviceUrl));
		bindingTemplate.setAccessPoint(accessPoint);
		
		Service service =  wsdlDefinition.getService(serviceName);
		
		if (service!=null) {
			TModelInstanceDetails tModelInstanceDetails = new TModelInstanceDetails();
			
			Port port = service.getPort(portName);
			if (port!=null) {
				Binding binding = port.getBinding();
				// Set the Binding Description
				String bindingDescription = properties.getProperty(Property.BINDING_DESCRIPTION, Property.DEFAULT_BINDING_DESCRIPTION);
				// Override with the service description from the WSDL if present
				Element docElement = binding.getDocumentationElement();
				if (docElement!=null && docElement.getTextContent()!=null) {
					bindingDescription = docElement.getTextContent();
				}
				
				bindingTemplate.getDescription().addAll(Common2UDDI.mapDescription(bindingDescription, lang));
				
				// reference wsdl:binding tModel
				TModelInstanceInfo tModelInstanceInfoBinding = new TModelInstanceInfo();
				tModelInstanceInfoBinding.setTModelKey(keyDomainURI + binding.getQName().getLocalPart());
				InstanceDetails instanceDetails = new InstanceDetails();
				instanceDetails.setInstanceParms(portName);  
				tModelInstanceInfoBinding.setInstanceDetails(instanceDetails);
				
				tModelInstanceInfoBinding.getDescription().addAll(Common2UDDI.mapDescription("The wsdl:binding that this wsdl:port implements. " + bindingDescription +
						" The instanceParms specifies the port local name.", lang));
				tModelInstanceDetails.getTModelInstanceInfo().add(tModelInstanceInfoBinding);
				
				// reference wsdl:portType tModel
				PortType portType = binding.getPortType();
				TModelInstanceInfo tModelInstanceInfoPortType = new TModelInstanceInfo();
				tModelInstanceInfoPortType.setTModelKey(keyDomainURI + portType.getQName().getLocalPart());
				String portTypeDescription = "";
				docElement = portType.getDocumentationElement();
				if (docElement!=null && docElement.getTextContent()!=null) {
					portTypeDescription = docElement.getTextContent();
				}
				
				tModelInstanceInfoPortType.getDescription().addAll(Common2UDDI.mapDescription("The wsdl:portType that this wsdl:port implements." + portTypeDescription, lang));
				tModelInstanceDetails.getTModelInstanceInfo().add(tModelInstanceInfoPortType);
				
				//reference bpel:process tModel
				TModelInstanceInfo tModelInstanceInfoBPEL = new TModelInstanceInfo();
				tModelInstanceInfoBPEL.setTModelKey(keyDomainURI + service.getQName().getLocalPart() + "Process");
				
				// Description
				String serviceDescription = properties.getProperty(Property.SERVICE_DESCRIPTION, Property.DEFAULT_SERVICE_DESCRIPTION);
				// Override with the service description from the WSDL if present
				docElement = wsdlDefinition.getService(serviceName).getDocumentationElement();
				if (docElement!=null && docElement.getTextContent()!=null) {
					serviceDescription = docElement.getTextContent();
				}
				
				tModelInstanceInfoBPEL.getDescription().addAll(Common2UDDI.mapDescription("The bpel:process this wsdl:port supports." + serviceDescription, lang));
				tModelInstanceDetails.getTModelInstanceInfo().add(tModelInstanceInfoBPEL);
				
				bindingTemplate.setTModelInstanceDetails(tModelInstanceDetails);
			} else {
				log.error("Could not find Port with portName: " + portName);
			}
		} else {
			log.error("Could not find Service with serviceName: " + serviceName.getLocalPart());
		}
		
		if (log.isDebugEnabled()) {
    		log.debug(new PrintUDDI<BindingTemplate>().print(bindingTemplate));
    	}
		
		return bindingTemplate;
	}
    
    /** Finds and returns ALL the tModels related to the process, so that i.e. they
     * can be removed on undeployment of the service.
     * 
     * @param serviceName
     * @return a tModel if found
     */
    public FindTModel createFindTModelForProcessName (QName serviceName) {
    	
    	FindTModel findTModel = new FindTModel();
    	Name name = new Name();
    	//name.setLang(lang);
    	name.setValue(serviceName.getLocalPart());
    	findTModel.setName(name);
    	CategoryBag categoryBag = new CategoryBag();
    	
    	String namespace = serviceName.getNamespaceURI();
    	if (namespace!=null && namespace.length()!=0) {
    		KeyedReference namespaceReference = WSDL2UDDI.newKeyedReference(
    			"uddi:uddi.org:xml:namespace", "uddi-org:xml:namespace", namespace);
    		categoryBag.getKeyedReference().add(namespaceReference);
    	}
    	KeyedReference typesReference = WSDL2UDDI.newKeyedReference(
    			"uddi:uddi.org:bpel:types", "uddi-org:bpel:types", "process");
    	categoryBag.getKeyedReference().add(typesReference);
    	findTModel.setCategoryBag(categoryBag);
    	
    	if (log.isDebugEnabled()) {
    		log.debug(new PrintUDDI<FindTModel>().print(findTModel));
    	}
    	return findTModel;
    }
    /**
     * Find all processes that use the given portType.
     * 
     * @param portTypeKey
     * @return tmodel info
     */
    public FindTModel createFindProcessesForPortTypes(String portTypeKey) {
    	FindTModel findTModel = new FindTModel();
    	CategoryBag categoryBag = new CategoryBag();
    	
    	KeyedReference typesReference = WSDL2UDDI.newKeyedReference(
    			"uddi:uddi.org:bpel:types", "uddi-org:bpel:types", "process");
    	categoryBag.getKeyedReference().add(typesReference);
    	
    	KeyedReference portTypeReference = WSDL2UDDI.newKeyedReference(
    			"uddi:uddi.org:wsdl:porttypereference", "uddi-org:wsdl:portTypeReference", portTypeKey);
    	categoryBag.getKeyedReference().add(portTypeReference);
    	
    	findTModel.setCategoryBag(categoryBag);
    	
    	return findTModel;
    }
    /**
     * Find all portTypes used in the given process. This should return the 
     * tModel registration for the process tModel. The tModelKeys for the 
     * portTypes used in the process can be obtained from the process tModels 
     * categoryBag, and passed into the second call.
     * 
     * @param processKey
     * @return GetTModelDetail
     */
    public GetTModelDetail createFindAllPortTypesForProcess_1(String processKey) {
    	GetTModelDetail getTModelDetail = new GetTModelDetail();
    	getTModelDetail.getTModelKey().add(processKey);
    	return getTModelDetail;
    }
    /**
     * Once retrieved, the second call is made to get the tModel registrations 
     * for the portTypes with the keys found in the first step.
     * 
     * @param portTypeTModelKeys - List of portType tModels found in the first step.
     * @return GetTModelDetail
     */
    public GetTModelDetail createFindAllPortTypesForProcess_2(List<String> portTypeTModelKeys) {
    	GetTModelDetail getTModelDetail = new GetTModelDetail();
    	for (String tModelKey : portTypeTModelKeys) {
    		getTModelDetail.getTModelKey().add(tModelKey);
    	}
    	return getTModelDetail;
    }
    /**
     * Find all implementations of the given process.
     * @param processKey
     * @return FindBinding
     */
    public FindBinding createFindImplementationsForProcess(String processKey) {
    	FindBinding findBinding = new FindBinding();
    	TModelBag tModelBag = new TModelBag();
    	tModelBag.getTModelKey().add(processKey);
    	return findBinding;
    }
	
}