| /* |
| * 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.builder.impl; |
| |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.logging.Logger; |
| |
| import javax.xml.namespace.QName; |
| |
| 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.ComponentReference; |
| import org.apache.tuscany.sca.assembly.ComponentService; |
| import org.apache.tuscany.sca.assembly.ComponentType; |
| import org.apache.tuscany.sca.assembly.Composite; |
| import org.apache.tuscany.sca.assembly.CompositeReference; |
| import org.apache.tuscany.sca.assembly.CompositeService; |
| import org.apache.tuscany.sca.assembly.Contract; |
| import org.apache.tuscany.sca.assembly.Multiplicity; |
| import org.apache.tuscany.sca.assembly.Reference; |
| import org.apache.tuscany.sca.assembly.SCABinding; |
| import org.apache.tuscany.sca.assembly.SCABindingFactory; |
| import org.apache.tuscany.sca.assembly.Service; |
| import org.apache.tuscany.sca.assembly.builder.BuilderContext; |
| import org.apache.tuscany.sca.assembly.builder.BuilderExtensionPoint; |
| import org.apache.tuscany.sca.assembly.builder.ContractBuilder; |
| import org.apache.tuscany.sca.assembly.builder.Messages; |
| import org.apache.tuscany.sca.core.ExtensionPointRegistry; |
| import org.apache.tuscany.sca.core.FactoryExtensionPoint; |
| import org.apache.tuscany.sca.core.UtilityExtensionPoint; |
| import org.apache.tuscany.sca.definitions.Definitions; |
| import org.apache.tuscany.sca.interfacedef.Compatibility; |
| import org.apache.tuscany.sca.interfacedef.IncompatibleInterfaceContractException; |
| import org.apache.tuscany.sca.interfacedef.InterfaceContract; |
| import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; |
| import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract; |
| import org.apache.tuscany.sca.monitor.Monitor; |
| import org.apache.tuscany.sca.policy.ExtensionType; |
| import org.apache.tuscany.sca.policy.PolicySubject; |
| |
| /** |
| * @version $Rev$ $Date$ |
| */ |
| |
| // TODO - really implementation.composite component type builder - CompositeComponentTypeBuilder? |
| |
| public class CompositeComponentTypeBuilderImpl { |
| private static final Logger logger = Logger.getLogger(CompositeComponentTypeBuilderImpl.class.getName()); |
| |
| protected static final String SCA11_NS = "http://docs.oasis-open.org/ns/opencsa/sca/200912"; |
| protected static final String BINDING_SCA = "binding.sca"; |
| protected static final QName BINDING_SCA_QNAME = new QName(SCA11_NS, BINDING_SCA); |
| |
| private ComponentBuilderImpl componentBuilder; |
| private AssemblyFactory assemblyFactory; |
| private SCABindingFactory scaBindingFactory; |
| private InterfaceContractMapper interfaceContractMapper; |
| private BuilderExtensionPoint builders; |
| private ContractBuilder contractBuilder; |
| |
| public CompositeComponentTypeBuilderImpl(ExtensionPointRegistry registry) { |
| UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class); |
| |
| FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class); |
| assemblyFactory = modelFactories.getFactory(AssemblyFactory.class); |
| scaBindingFactory = modelFactories.getFactory(SCABindingFactory.class); |
| |
| interfaceContractMapper = utilities.getUtility(InterfaceContractMapper.class); |
| builders = registry.getExtensionPoint(BuilderExtensionPoint.class); |
| contractBuilder = builders.getContractBuilder(); |
| } |
| |
| public void setComponentBuilder(ComponentBuilderImpl componentBuilder) { |
| this.componentBuilder = componentBuilder; |
| } |
| |
| /** |
| * Calculate the component type for the provided implementation |
| * |
| * @param implementation |
| * @return component type |
| */ |
| public void createComponentType(Component outerComponent, Composite composite, BuilderContext context) { |
| |
| Monitor monitor = context.getMonitor(); |
| monitor.pushContext("Composite: " + composite.getName().toString()); |
| |
| try { |
| // first make sure that each child component has been properly configured based |
| // on its own component type |
| for (Component component : composite.getComponents()) { |
| |
| // Check for duplicate component names |
| if (component != composite.getComponent(component.getName())) { |
| Monitor.error(monitor, |
| this, |
| Messages.ASSEMBLY_VALIDATION, |
| "DuplicateComponentName", |
| composite.getName().toString(), |
| component.getName()); |
| } |
| |
| // do any work we need to do before we configure the component |
| // Anything that needs to be pushed down the promotion |
| // hierarchy must be done before we configure the component |
| |
| // Push down the autowire flag from the composite to components |
| if (component.getAutowire() == null) { |
| component.setAutowire(composite.getAutowire()); |
| } |
| |
| // configure the component from its component type |
| componentBuilder.configureComponentFromComponentType(outerComponent, composite, component, context); |
| } |
| |
| // create the composite component type based on the promoted artifacts |
| // from the components that it contains |
| |
| // index all the components, services and references in the |
| // component type so that they are easy to find |
| Map<String, Component> components = new HashMap<String, Component>(); |
| Map<String, ComponentService> componentServices = new HashMap<String, ComponentService>(); |
| Map<String, ComponentReference> componentReferences = new HashMap<String, ComponentReference>(); |
| indexComponentsServicesAndReferences(composite, components, componentServices, componentReferences); |
| |
| // services |
| calculateServices(composite, components, componentServices, context); |
| |
| // references |
| calculateReferences(composite, components, componentReferences, context); |
| |
| // properties |
| // Properties on the composite component are unaffected by properties |
| // on child components. Instead child component properties might take their |
| // values from composite properties. Hence there is nothing to do here. |
| //calculateProperties(composite, components); |
| |
| } finally { |
| monitor.popContext(); |
| } |
| } |
| |
| /** |
| * Index components, services and references inside a composite. |
| * |
| * @param composite |
| * @param components |
| * @param componentServices |
| * @param componentReferences |
| */ |
| private void indexComponentsServicesAndReferences(Composite composite, |
| Map<String, Component> components, |
| Map<String, ComponentService> componentServices, |
| Map<String, ComponentReference> componentReferences) { |
| |
| for (Component component : composite.getComponents()) { |
| |
| // Index components by name |
| components.put(component.getName(), component); |
| |
| ComponentService nonCallbackService = null; |
| int nonCallbackServices = 0; |
| for (ComponentService componentService : component.getServices()) { |
| |
| // Index component services by component name / service name |
| String uri = component.getName() + '/' + componentService.getName(); |
| componentServices.put(uri, componentService); |
| |
| // count how many non-callback services there are |
| // if there is only one the component name also acts as the service name |
| if (!componentService.isForCallback()) { |
| |
| // Check how many non callback non-promoted services we have |
| if (nonCallbackServices == 0) { |
| nonCallbackService = componentService; |
| } |
| nonCallbackServices++; |
| } |
| } |
| |
| if (nonCallbackServices == 1) { |
| // If we have a single non callback service, index it by |
| // component name as well |
| componentServices.put(component.getName(), nonCallbackService); |
| } |
| |
| // Index references by component name / reference name |
| for (ComponentReference componentReference : component.getReferences()) { |
| String uri = component.getName() + '/' + componentReference.getName(); |
| componentReferences.put(uri, componentReference); |
| } |
| } |
| } |
| |
| /** |
| * Connect the services in the component type to the component services that |
| * they promote |
| * |
| * @param componentType |
| * @param component |
| */ |
| private void calculateServices(ComponentType componentType, |
| Map<String, Component> components, |
| Map<String, ComponentService> componentServices, |
| BuilderContext context) { |
| |
| Monitor monitor = context.getMonitor(); |
| |
| // Connect this component type's services to the |
| // services from child components which it promotes |
| connectPromotedServices(componentType, components, componentServices, monitor); |
| |
| // look at each component type service in turn and |
| // calculate its configuration based on OASIS rules |
| for (Service service : componentType.getServices()) { |
| CompositeService compositeService = (CompositeService)service; |
| ComponentService promotedComponentService = compositeService.getPromotedService(); |
| |
| // promote interface contracts |
| calculatePromotedServiceInterfaceContract(compositeService, promotedComponentService, monitor); |
| |
| // promote bindings |
| calculatePromotedBindings(compositeService, promotedComponentService); |
| |
| componentBuilder.policyBuilder.configure(compositeService, context); |
| } |
| } |
| |
| /** |
| * Connect the references in the component type to the component references that |
| * they promote |
| * |
| * @param componentType |
| * @param component |
| */ |
| private void calculateReferences(ComponentType componentType, |
| Map<String, Component> components, |
| Map<String, ComponentReference> componentReferences, |
| BuilderContext context) { |
| Monitor monitor = context.getMonitor(); |
| // Connect this component type's references to the |
| // references from child components which it promotes |
| connectPromotedReferences(componentType, components, componentReferences, monitor); |
| |
| // look at each component type reference in turn and |
| // calculate its configuration based on OASIS rules |
| for (Reference reference : componentType.getReferences()) { |
| CompositeReference compositeReference = (CompositeReference)reference; |
| List<ComponentReference> promotedReferences = compositeReference.getPromotedReferences(); |
| |
| for (ComponentReference promotedComponentReference : promotedReferences) { |
| |
| // promote multiplicity |
| reconcileReferenceMultiplicity(componentType, compositeReference, promotedComponentReference, monitor); |
| |
| // check nonOverridable |
| validateNonOverridable(componentType, compositeReference, promotedComponentReference, monitor); |
| |
| // promote interface contracts |
| calculatePromotedReferenceInterfaceContract(compositeReference, promotedComponentReference, monitor); |
| |
| // promote bindings |
| // Don't need to promote reference bindings as any lower level binding will |
| // already be targeting the correct service without need for promotion |
| //calculatePromotedBindings(compositeReference, promotedComponentReference); |
| } |
| |
| componentBuilder.policyBuilder.configure(compositeReference, context); |
| } |
| } |
| |
| /** |
| * Connect the services in the component type to the component services that |
| * they promote |
| * |
| * @param componentType |
| * @param component |
| */ |
| private void connectPromotedServices(ComponentType componentType, |
| Map<String, Component> components, |
| Map<String, ComponentService> componentServices, |
| Monitor monitor) { |
| |
| for (Service service : componentType.getServices()) { |
| // Connect composite (component type) services to the component services |
| // that they promote |
| CompositeService compositeService = (CompositeService)service; |
| ComponentService componentService = compositeService.getPromotedService(); |
| if (componentService != null && componentService.isUnresolved()) { |
| // get the name of the promoted component/service |
| String promotedComponentName = compositeService.getPromotedComponent().getName(); |
| String promotedServiceName; |
| if (componentService.getName() != null) { |
| if (compositeService.isForCallback()) { |
| // For callbacks the name already has the form "componentName/servicename" |
| promotedServiceName = componentService.getName(); |
| } else { |
| promotedServiceName = promotedComponentName + '/' + componentService.getName(); |
| } |
| } else { |
| promotedServiceName = promotedComponentName; |
| } |
| |
| // find the promoted service |
| ComponentService promotedService = componentServices.get(promotedServiceName); |
| |
| if (promotedService != null) { |
| |
| // Point to the resolved component |
| Component promotedComponent = components.get(promotedComponentName); |
| compositeService.setPromotedComponent(promotedComponent); |
| |
| // Point to the resolved component service |
| compositeService.setPromotedService(promotedService); |
| } else { |
| Monitor.error(monitor, |
| this, |
| Messages.ASSEMBLY_VALIDATION, |
| "PromotedServiceNotFound", |
| ((Composite)componentType).getName().toString(), |
| promotedServiceName); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Connect the references in the component type to the component references that |
| * they promote |
| * |
| * @param componentType |
| * @param component |
| */ |
| private void connectPromotedReferences(ComponentType componentType, |
| Map<String, Component> components, |
| Map<String, ComponentReference> componentReferences, |
| Monitor monitor) { |
| |
| // Connect composite (component type) references to the component references that they promote |
| for (Reference reference : componentType.getReferences()) { |
| CompositeReference compositeReference = (CompositeReference)reference; |
| List<ComponentReference> promotedReferences = compositeReference.getPromotedReferences(); |
| for (int i = 0, n = promotedReferences.size(); i < n; i++) { |
| ComponentReference componentReference = promotedReferences.get(i); |
| if (componentReference.isUnresolved()) { |
| String componentReferenceName = componentReference.getName(); |
| componentReference = componentReferences.get(componentReferenceName); |
| if (componentReference != null) { |
| // Set the promoted component |
| Component promotedComponent = compositeReference.getPromotedComponents().get(i); |
| promotedComponent = components.get(promotedComponent.getName()); |
| compositeReference.getPromotedComponents().set(i, promotedComponent); |
| |
| componentReference.setPromoted(true); |
| |
| // Point to the resolved component reference |
| promotedReferences.set(i, componentReference); |
| } else { |
| Monitor.error(monitor, |
| this, |
| Messages.ASSEMBLY_VALIDATION, |
| "PromotedReferenceNotFound", |
| ((Composite)componentType).getName().toString(), |
| componentReferenceName); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Create a default SCA binding in the case that no binding |
| * is specified by the user |
| * |
| * @param contract |
| * @param definitions |
| */ |
| protected void createSCABinding(Contract contract, Definitions definitions) { |
| |
| SCABinding scaBinding = scaBindingFactory.createSCABinding(); |
| scaBinding.setName(contract.getName()); |
| |
| if (definitions != null) { |
| for (ExtensionType attachPointType : definitions.getBindingTypes()) { |
| if (attachPointType.getType().equals(BINDING_SCA_QNAME)) { |
| ((PolicySubject)scaBinding).setExtensionType(attachPointType); |
| } |
| } |
| } |
| |
| contract.getBindings().add(scaBinding); |
| contract.setOverridingBindings(false); |
| } |
| |
| /** |
| * The following methods implement rules that the OASIS specification defined explicitly |
| * to control how configuration from a component type is inherited by a component |
| */ |
| |
| /** |
| * Interface contract from higher in the implementation hierarchy takes precedence. |
| * When it comes to checking compatibility the top level service interface is a |
| * subset of the promoted service interface so treat the top level interface as |
| * the source |
| * |
| * @param topContract the top contract |
| * @param bottomContract the bottom contract |
| */ |
| private void calculatePromotedServiceInterfaceContract(Service topContract, Service bottomContract, Monitor monitor) { |
| // Use the interface contract from the bottom level contract if |
| // none is specified on the top level contract |
| InterfaceContract topInterfaceContract = topContract.getInterfaceContract(); |
| InterfaceContract bottomInterfaceContract = bottomContract.getInterfaceContract(); |
| |
| if (topInterfaceContract == null) { |
| topContract.setInterfaceContract(bottomInterfaceContract); |
| } else if (bottomInterfaceContract != null) { |
| // Check that the top and bottom interface contracts are compatible |
| boolean isCompatible = true; |
| String incompatibilityReason = ""; |
| try{ |
| isCompatible = checkSubsetCompatibility(topInterfaceContract, bottomInterfaceContract); |
| } catch (IncompatibleInterfaceContractException ex){ |
| isCompatible = false; |
| incompatibilityReason = ex.getMessage(); |
| } |
| if (!isCompatible) { |
| Monitor.error(monitor, |
| this, |
| Messages.ASSEMBLY_VALIDATION, |
| "ServiceInterfaceNotSubSet", |
| topContract.getName(), |
| incompatibilityReason); |
| } |
| |
| // TODO - there is an issue with the following code if the |
| // contracts of of different types. Need to use the |
| // normalized form |
| |
| // fix up the forward interface based on the promoted component |
| // Someone might have manually specified a callback interface but |
| // left out the forward interface |
| if (topInterfaceContract.getInterface() == null){ |
| topInterfaceContract.setInterface(bottomInterfaceContract.getInterface()); |
| } |
| |
| // fix up the callback interface based on the promoted component |
| // Someone might have manually specified a forward interface but |
| // left out the callback interface |
| if (topInterfaceContract.getCallbackInterface() == null){ |
| topInterfaceContract.setCallbackInterface(bottomInterfaceContract.getCallbackInterface()); |
| } |
| } |
| } |
| |
| /** |
| * Interface contract from higher in the implementation hierarchy takes precedence. |
| * When it comes to checking compatibility the top level reference interface is a |
| * superset of the promoted reference interface so treat the promoted |
| * (bottom) interface as the source |
| * |
| * @param topContract the top contract |
| * @param bottomContract the bottom contract |
| */ |
| private void calculatePromotedReferenceInterfaceContract(Reference topContract, Reference bottomContract, Monitor monitor) { |
| // Use the interface contract from the bottom level contract if |
| // none is specified on the top level contract |
| InterfaceContract topInterfaceContract = topContract.getInterfaceContract(); |
| InterfaceContract bottomInterfaceContract = bottomContract.getInterfaceContract(); |
| |
| if (topInterfaceContract == null) { |
| topContract.setInterfaceContract(bottomInterfaceContract); |
| } else if (bottomInterfaceContract != null) { |
| // Check that the top and bottom interface contracts are compatible |
| boolean isCompatible = true; |
| String incompatibilityReason = ""; |
| try{ |
| isCompatible = checkSubsetCompatibility(bottomInterfaceContract, topInterfaceContract); |
| } catch (IncompatibleInterfaceContractException ex){ |
| isCompatible = false; |
| incompatibilityReason = ex.getMessage(); |
| } |
| if (!isCompatible) { |
| Monitor.error(monitor, |
| this, |
| Messages.ASSEMBLY_VALIDATION, |
| "ReferenceInterfaceNotSubSet", |
| topContract.getName(), |
| incompatibilityReason); |
| } |
| |
| // TODO - there is an issue with the following code if the |
| // contracts of of different types. Need to use the |
| // normalized form |
| |
| // fix up the forward interface based on the promoted component |
| // Someone might have manually specified a callback interface but |
| // left out the forward interface |
| if (topInterfaceContract.getInterface() == null){ |
| topInterfaceContract.setInterface(bottomInterfaceContract.getInterface()); |
| } |
| |
| // fix up the callback interface based on the promoted component |
| // Someone might have manually specified a forward interface but |
| // left out the callback interface |
| if (topInterfaceContract.getCallbackInterface() == null){ |
| topInterfaceContract.setCallbackInterface(bottomInterfaceContract.getCallbackInterface()); |
| } |
| } |
| } |
| |
| /** |
| * Bindings from higher in the implementation hierarchy take precedence |
| * |
| * @param compositeService |
| * @param promotedComponentService |
| */ |
| private void calculatePromotedBindings(CompositeService compositeService, ComponentService promotedComponentService) { |
| // forward bindings |
| if (compositeService.getBindings().isEmpty()) { |
| for (Binding binding : promotedComponentService.getBindings()) { |
| try { |
| compositeService.getBindings().add((Binding)binding.clone()); |
| } catch (CloneNotSupportedException ex) { |
| // this binding can't be used in the promoted service |
| } |
| } |
| } |
| |
| if (compositeService.getBindings().isEmpty()) { |
| createSCABinding(compositeService, null); |
| } |
| |
| // callback bindings |
| if (promotedComponentService.getCallback() != null) { |
| if (compositeService.getCallback() != null) { |
| compositeService.getCallback().getBindings().clear(); |
| } else { |
| compositeService.setCallback(assemblyFactory.createCallback()); |
| } |
| |
| for (Binding binding : promotedComponentService.getCallback().getBindings()) { |
| try { |
| compositeService.getCallback().getBindings().add((Binding)binding.clone()); |
| } catch (CloneNotSupportedException ex) { |
| // this binding can't be used in the promoted service |
| } |
| } |
| } |
| } |
| |
| private void reconcileReferenceMultiplicity(ComponentType componentType, |
| Reference compositeReference, |
| Reference promotedComponentReference, |
| Monitor monitor) { |
| if (compositeReference.getMultiplicity() != null) { |
| if (!isValidMultiplicityOverride(promotedComponentReference.getTargets().size() > 0, |
| promotedComponentReference.getMultiplicity(), |
| compositeReference.getMultiplicity())) { |
| Monitor.error(monitor, |
| this, |
| Messages.ASSEMBLY_VALIDATION, |
| "CompositeReferenceIncompatibleMultiplicity", |
| componentType.getURI(), |
| compositeReference.getName(), |
| promotedComponentReference.getName()); |
| } |
| } else { |
| compositeReference.setMultiplicity(promotedComponentReference.getMultiplicity()); |
| } |
| } |
| |
| private boolean isValidMultiplicityOverride(boolean componentRefHasTarget, |
| Multiplicity componentRefMul, |
| Multiplicity compositeRefMul) { |
| if ((componentRefMul != null) && |
| (compositeRefMul != null) && |
| componentRefMul != compositeRefMul) { |
| if (componentRefHasTarget){ |
| switch (componentRefMul) { |
| case ZERO_ONE: |
| return compositeRefMul == Multiplicity.ZERO_ONE || |
| compositeRefMul == Multiplicity.ONE_ONE; |
| case ONE_ONE: |
| return compositeRefMul == Multiplicity.ZERO_ONE || |
| compositeRefMul == Multiplicity.ONE_ONE; |
| case ZERO_N: |
| return true; |
| case ONE_N: |
| return true; |
| default: |
| return false; |
| } |
| } else { |
| switch (componentRefMul) { |
| case ZERO_ONE: |
| return compositeRefMul == Multiplicity.ONE_ONE; |
| case ONE_ONE: |
| return compositeRefMul == Multiplicity.ONE_ONE; |
| case ZERO_N: |
| return true; |
| case ONE_N: |
| return compositeRefMul == Multiplicity.ONE_ONE || |
| compositeRefMul == Multiplicity.ONE_N; |
| |
| default: |
| return false; |
| } |
| } |
| } else { |
| return true; |
| } |
| } |
| |
| /** |
| * ASM50042 - Checks that if a component reference with multiplicity="1..1" is marked |
| * as nonOveridable then there are no composite references that promote it |
| * |
| * @param componentType |
| * @param compositeReference |
| * @param promotedComponentReference |
| * @param monitor |
| */ |
| private void validateNonOverridable(ComponentType componentType, |
| Reference compositeReference, |
| Reference promotedComponentReference, |
| Monitor monitor){ |
| if ((promotedComponentReference.getMultiplicity() == Multiplicity.ONE_ONE) && |
| (((ComponentReference)promotedComponentReference)).isNonOverridable() == true) { |
| Monitor.error(monitor, |
| this, |
| Messages.ASSEMBLY_VALIDATION, |
| "CompositeReferencePromotesNonOverridableReference", |
| componentType.getURI(), |
| compositeReference.getName(), |
| promotedComponentReference.getName()); |
| } |
| } |
| |
| /** |
| * A local wrapper for the interace contract mapper as we need to normalize the |
| * interface contracts if appropriate and the mapper doesn't have the right |
| * dependencies to be able to do it. |
| * |
| * Sometimes the two interfaces can be presented using different IDLs, for example |
| * Java and WSDL. In this case interfaces are converted so that they are both WSDL1.1 interfaces |
| * and they are then compared. The generated WSDL is cached on the interface object for |
| * any subsequent matching |
| * |
| * @param contractA |
| * @param contractB |
| * @return true if the interface contracts match |
| */ |
| private boolean checkSubsetCompatibility(InterfaceContract contractA, InterfaceContract contractB) |
| throws IncompatibleInterfaceContractException { |
| |
| if (contractA.getClass() != contractB.getClass()) { |
| |
| if (contractA instanceof JavaInterfaceContract){ |
| contractBuilder.build(contractA, null); |
| contractA = ((JavaInterfaceContract)contractA).getNormalizedWSDLContract(); |
| } |
| |
| if (contractB instanceof JavaInterfaceContract){ |
| contractBuilder.build(contractB, null); |
| contractB = ((JavaInterfaceContract)contractB).getNormalizedWSDLContract(); |
| } |
| } |
| |
| return interfaceContractMapper.checkCompatibility(contractA, |
| contractB, |
| Compatibility.SUBSET, |
| false, |
| false); |
| } |
| |
| } //end class |