/** * * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. * * 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.tuscany.model.assembly.impl; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.tuscany.model.assembly.AssemblyContext; import org.apache.tuscany.model.assembly.AssemblyFactory; import org.apache.tuscany.model.assembly.AssemblyVisitor; import org.apache.tuscany.model.assembly.Component; import org.apache.tuscany.model.assembly.ComponentType; import org.apache.tuscany.model.assembly.Composite; import org.apache.tuscany.model.assembly.ConfiguredProperty; import org.apache.tuscany.model.assembly.ConfiguredReference; import org.apache.tuscany.model.assembly.ConfiguredService; import org.apache.tuscany.model.assembly.EntryPoint; import org.apache.tuscany.model.assembly.ExternalService; import org.apache.tuscany.model.assembly.Implementation; import org.apache.tuscany.model.assembly.ImportWSDL; import org.apache.tuscany.model.assembly.Multiplicity; import org.apache.tuscany.model.assembly.OverrideOption; import org.apache.tuscany.model.assembly.Part; import org.apache.tuscany.model.assembly.Reference; import org.apache.tuscany.model.assembly.Service; import org.apache.tuscany.model.assembly.ServiceContract; import org.apache.tuscany.model.assembly.ServiceURI; import org.apache.tuscany.model.assembly.Wire; import org.apache.tuscany.model.util.NotifyingList; /** * An implementation of Composite. */ public abstract class CompositeImpl extends ExtensibleImpl implements Composite { private String name; private ComponentType componentType; private Class implementationClass; /** * A list of parts synchronized with a map */ private class PartList extends NotifyingList { protected void added(E element) { partsMap.put(element.getName(), element); element.setComposite(CompositeImpl.this); } protected void removed(E element) { partsMap.remove(element.getName()); element.setComposite(null); } } private Map partsMap = new HashMap(); private List components = new PartList(); private List entryPoints = new PartList(); private List externalServices = new PartList(); private List wires = new ArrayList(); /** * A list of WSDL imports synchronized with a map */ private class ImportWSDLList extends NotifyingList { protected void added(ImportWSDL element) { List importList = wsdlImportsMap.get(element.getNamespace()); if (importList == null) { importList = new ArrayList(); wsdlImportsMap.put(element.getNamespace(), importList); } importList.add(element); } protected void removed(ImportWSDL element) { List importList = wsdlImportsMap.get(element.getNamespace()); if (importList != null) { importList.remove(element); if (importList.isEmpty()) wsdlImportsMap.remove(element.getNamespace()); } } } private Map> wsdlImportsMap = new HashMap>(); private List wsdlImports = new ImportWSDLList(); protected CompositeImpl() { } public String getName() { return name; } public void setName(String newName) { checkNotFrozen(); name = newName; } public List getComponents() { return components; } public List getEntryPoints() { return entryPoints; } public List getExternalServices() { return externalServices; } public Part getPart(String name) { return partsMap.get(name); } public List getWires() { return wires; } public List getWSDLImports() { return wsdlImports; } public List getWSDLImports(String namespace) { return wsdlImportsMap.get(namespace); } public ComponentType getComponentType() { return componentType; } public void setComponentType(ComponentType componentType) { checkNotFrozen(); this.componentType = componentType; } public ConfiguredService getConfiguredService(ServiceURI address) { String partName = address.getPartName(); String serviceName = address.getServiceName(); Part part = getPart(partName); if (part instanceof Component) { Component component = (Component) part; if (serviceName != null) { return component.getConfiguredService(serviceName); } else { if (!component.getConfiguredServices().isEmpty()) { return component.getConfiguredServices().get(0); } else { return null; } } } if (part instanceof ExternalService) { ExternalService externalService = (ExternalService) part; return externalService.getConfiguredService(); } else return null; } public void initialize(AssemblyContext modelContext) { if (isInitialized()) return; super.initialize(modelContext); // Initialize WSDL imports for (ImportWSDL importWSDL : wsdlImports) { importWSDL.initialize(modelContext); } // Initialize parts for (Part part : externalServices) { part.initialize(modelContext); } for (Part part : components) { part.initialize(modelContext); } for (Part part : entryPoints) { part.initialize(modelContext); } // Derive the component type from the entry points and external services in the composite // Also derive properties from the overridable properties of the components in the composite if (componentType == null) { AssemblyFactory factory = modelContext.getAssemblyFactory(); componentType = factory.createComponentType(); for (EntryPoint entryPoint : getEntryPoints()) { Service service = factory.createService(); service.setName(entryPoint.getName()); ServiceContract serviceContract = entryPoint.getConfiguredService().getPort().getServiceContract(); if (serviceContract != null) service.setServiceContract(serviceContract); componentType.getServices().add(service); ConfiguredReference configuredReference = entryPoint.getConfiguredReference(); ServiceURI sourceURI = factory.createServiceURI(null, entryPoint, configuredReference); for (String target : configuredReference.getTargets()) { ServiceURI targetURI = factory.createServiceURI(null, target); Wire wire = factory.createWire(); wire.setSource(sourceURI); wire.setTarget(targetURI); getWires().add(wire); } } for (ExternalService externalService : getExternalServices()) { if (externalService.getOverrideOption() == null || externalService.getOverrideOption() == OverrideOption.NO) continue; Reference reference = factory.createReference(); reference.setName(externalService.getName()); ServiceContract serviceContract = externalService.getConfiguredService().getPort().getServiceContract(); if (serviceContract != null) reference.setServiceContract(serviceContract); componentType.getReferences().add(reference); } for (Component component : getComponents()) { for (ConfiguredProperty configuredProperty : component.getConfiguredProperties()) { if (configuredProperty.getOverrideOption() == null || configuredProperty.getOverrideOption() == OverrideOption.NO) continue; componentType.getProperties().add(configuredProperty.getProperty()); } for (ConfiguredReference configuredReference : component.getConfiguredReferences()) { // Create a wire ServiceURI sourceURI = factory.createServiceURI(null, component, configuredReference); for (String target : configuredReference.getTargets()) { ServiceURI targetURI = factory.createServiceURI(null, target); Wire wire = factory.createWire(); wire.setSource(sourceURI); wire.setTarget(targetURI); getWires().add(wire); } } } } componentType.initialize(modelContext); // Wire the parts in this composite wire(modelContext); } /** * Wire the parts in this composite. * @param modelContext */ protected void wire(AssemblyContext modelContext) { for (Wire wire : getWires()) { // Get the source reference ServiceURI sourceURI = wire.getSource(); ConfiguredReference configuredReference = null; String partName = sourceURI.getPartName(); String referenceName = sourceURI.getServiceName(); if (referenceName != null) { //Component component = (Component)getPart(partName); // if (component != null) { Part part = getPart(partName); if (part instanceof Component) { configuredReference = ((Component) part).getConfiguredReference(referenceName); } else if (part instanceof EntryPoint) { configuredReference = ((EntryPoint) part).getConfiguredReference(); } } else { EntryPoint entryPoint = (EntryPoint) getPart(partName); if (entryPoint != null) { configuredReference = entryPoint.getConfiguredReference(); } } if (configuredReference == null) { throw new IllegalArgumentException("Cannot find wire source " + sourceURI.getPath()); } else { // Resolve the target service endpoint ServiceURI targetURI = wire.getTarget(); ConfiguredService configuredService = getConfiguredService(targetURI); if (configuredService != null) { // Wire the reference to the target Multiplicity multiplicity = configuredReference.getPort().getMultiplicity(); if (multiplicity == Multiplicity.ZERO_N || multiplicity == Multiplicity.ONE_N) { configuredReference.getTargetConfiguredServices().add(configuredService); } else { configuredReference.getTargetConfiguredServices().clear(); configuredReference.getTargetConfiguredServices().add(configuredService); } } else { throw new IllegalArgumentException("Cannot find service '" + targetURI.getPath() +"'."); } } } } public Class getImplementationClass() { return implementationClass; } public void setImplementationClass(Class clazz) { checkNotFrozen(); this.implementationClass = clazz; } public void freeze() { if (isFrozen()) return; super.freeze(); // Freeze component type if (componentType != null) componentType.freeze(); // Freeze lists wsdlImports = freeze(wsdlImports); components = freeze(components); entryPoints = freeze(entryPoints); externalServices = freeze(externalServices); wires = freeze(wires); } public boolean accept(AssemblyVisitor visitor) { if (!super.accept(visitor)) return false; if (!accept(wsdlImports, visitor)) return false; if (!accept(partsMap.values(), visitor)) return false; if (!accept(wires, visitor)) return false; if (componentType != null) { if (!componentType.accept(visitor)) return false; } return true; } }