From 13a67aabaa547bd4813a891ef563d4f07af9ff4d Mon Sep 17 00:00:00 2001 From: kelvingoodson Date: Fri, 28 May 2010 14:53:20 +0000 Subject: Tag for 2.0-Mr-RC1 git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@949195 13f79535-47bb-0310-9956-ffa450edef68 --- .../sca/interfacedef/impl/DataTypeImpl.java | 220 ++++++++++++ .../interfacedef/impl/InterfaceContractImpl.java | 129 +++++++ .../impl/InterfaceContractMapperImpl.java | 392 +++++++++++++++++++++ .../sca/interfacedef/impl/InterfaceImpl.java | 329 +++++++++++++++++ .../sca/interfacedef/impl/OperationImpl.java | 274 ++++++++++++++ 5 files changed, 1344 insertions(+) create mode 100644 sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java create mode 100644 sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractImpl.java create mode 100644 sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractMapperImpl.java create mode 100644 sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceImpl.java create mode 100644 sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java (limited to 'sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl') diff --git a/sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java b/sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java new file mode 100644 index 0000000000..12ea22938c --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java @@ -0,0 +1,220 @@ +/* + * 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.interfacedef.impl; + +import java.lang.reflect.Type; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.tuscany.sca.interfacedef.DataType; + +/** + * Representation of the type of data associated with an operation. Data is + * represented in two forms: the physical form used by the runtime and a logical + * form used by the assembly. The physical form is a Java Type because the + * runtime is written in Java. This may be the same form used by the application + * but it may not; for example, an application that is performing stream + * processing may want a physical form such as an + * {@link java.io.InputStream InputStream} to semantically operate on application + * data such as a purchase order. The logical description is that used by the + * assembly model and is an identifier into some well-known type space; examples + * may be a Java type represented by its Class or an XML type represented by its + * QName. Every data type may also contain metadata describing the expected + * data; for example, it could specify a preferred data binding technology or + * the size of a typical instance. + * + * @version $Rev$ $Date$ + * @tuscany.spi.extension.asclient + */ +public class DataTypeImpl implements DataType { + private String dataBinding; + private Class physical; + private Type genericType; + private L logical; + private Map, Object> metaDataMap; + + /** + * Construct a data type specifying the physical and logical types. + * + * @param physical the physical class used by the runtime + * @param logical the logical type + * @see #getLogical() + */ + public DataTypeImpl(Class physical, L logical) { + this(null, physical, physical, logical); + } + + /** + * @param dataBinding + * @param physical + * @param logical + */ + public DataTypeImpl(String dataBinding, Class physical, L logical) { + this(dataBinding, physical, physical, logical); + } + + /** + * @param dataBinding + * @param physical + * @param genericType + * @param logical + */ + public DataTypeImpl(String dataBinding, Class physical, Type genericType, L logical) { + super(); + this.dataBinding = dataBinding; + this.physical = physical; + this.genericType = genericType; + this.logical = logical; + } + + /** + * Returns the physical type used by the runtime. + * + * @return the physical type used by the runtime + */ + public Class getPhysical() { + return physical; + } + + /** + * @param physical the physical to set + */ + public void setPhysical(Class physical) { + this.physical = physical; + } + + /** + * Get the java generic type + * @return The java generic type + */ + public Type getGenericType() { + return genericType; + } + + /** + * Set the java generic type + * @param genericType + */ + public void setGenericType(Type genericType) { + this.genericType = genericType; + } + + /** + * Returns the logical identifier used by the assembly. The type of this + * value identifies the logical type system in use. Known values are: + *
    + *
  • a java.lang.reflect.Type identifies a Java type by name and + * ClassLoader; this includes Java Classes as they are specializations of + * Type
  • + *
  • a javax.xml.namespace.QName identifies an XML type by local name and + * namespace
  • + *
+ * + * @return the logical type name + */ + public L getLogical() { + return logical; + } + + /** + * @param logical the logical to set + */ + public void setLogical(L logical) { + this.logical = logical; + } + + public String getDataBinding() { + return dataBinding; + } + + /** + * @param dataBinding the dataBinding to set + */ + public void setDataBinding(String dataBinding) { + this.dataBinding = dataBinding; + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(physical).append(" ").append(dataBinding).append(" ").append(logical); + return sb.toString(); + } + + @SuppressWarnings("unchecked") + @Override + public Object clone() throws CloneNotSupportedException { + DataTypeImpl copy = (DataTypeImpl)super.clone(); + return copy; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((dataBinding == null) ? 0 : dataBinding.hashCode()); + result = prime * result + ((genericType == null) ? 0 : genericType.hashCode()); + result = prime * result + ((logical == null) ? 0 : logical.hashCode()); + result = prime * result + ((physical == null) ? 0 : physical.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final DataTypeImpl other = (DataTypeImpl)obj; + if (dataBinding == null) { + if (other.dataBinding != null) + return false; + } else if (!dataBinding.equals(other.dataBinding)) + return false; + if (genericType == null) { + if (other.genericType != null) + return false; + } else if (!genericType.equals(other.genericType)) + return false; + if (logical == null) { + if (other.logical != null) + return false; + } else if (!logical.equals(other.logical)) + return false; + if (physical == null) { + if (other.physical != null) + return false; + } else if (!physical.equals(other.physical)) + return false; + return true; + } + + public T getMetaData(Class type) { + return metaDataMap == null ? null : type.cast(metaDataMap.get(type)); + } + + public void setMetaData(Class type, T metaData) { + if (metaDataMap == null) { + metaDataMap = new ConcurrentHashMap, Object>(); + } + metaDataMap.put(type, metaData); + } +} diff --git a/sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractImpl.java b/sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractImpl.java new file mode 100644 index 0000000000..a62813edd4 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractImpl.java @@ -0,0 +1,129 @@ +/* + * 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.interfacedef.impl; + +import org.apache.tuscany.sca.interfacedef.Interface; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; + +/** + * Represents an interface contract. InterfaceContractImpl + * + * @version $Rev$ $Date$ + * @tuscany.spi.extension.inheritfrom + */ +public abstract class InterfaceContractImpl implements InterfaceContract { + private Interface callInterface; + private Interface callbackInterface; + + public Interface getCallbackInterface() { + return callbackInterface; + } + + public Interface getInterface() { + return callInterface; + } + + public void setCallbackInterface(Interface callbackInterface) { + this.callbackInterface = callbackInterface; + } + + public void setInterface(Interface callInterface) { + this.callInterface = callInterface; + } + + public InterfaceContract makeUnidirectional(boolean isCallback) { + if (!isCallback && callbackInterface == null) + return this; // already a unidirectional forward interface contract + + if (isCallback && callInterface == null) + return this; // already a unidirectional callback interface contract + + // contract is bidirectional, so create a new unidirectional contract + try { + InterfaceContract newContract = clone(); + if (!isCallback) { + newContract.setCallbackInterface(null); // create unidirectional forward interface contract + } else { + newContract.setInterface(null); // create unidirectional callback interface contract + } + return newContract; + } catch (CloneNotSupportedException e) { + // will not happen + return null; + } + } + + @Override + public InterfaceContractImpl clone() throws CloneNotSupportedException { + InterfaceContractImpl copy = (InterfaceContractImpl)super.clone(); + if (this.callbackInterface != null) { + copy.callbackInterface = (Interface)this.callbackInterface.clone(); + } + if (this.callInterface != null) { + copy.callInterface = (Interface)this.callInterface.clone(); + } + return copy; + } + + /** + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((callInterface == null) ? 0 : callInterface.hashCode()); + result = prime * result + ((callbackInterface == null) ? 0 : callbackInterface.hashCode()); + return result; + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final InterfaceContractImpl other = (InterfaceContractImpl)obj; + if (callInterface == null) { + if (other.callInterface != null) { + return false; + } + } else if (!callInterface.equals(other.callInterface)) { + return false; + } + if (callbackInterface == null) { + if (other.callbackInterface != null) { + return false; + } + } else if (!callbackInterface.equals(other.callbackInterface)) { + return false; + } + return true; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractMapperImpl.java b/sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractMapperImpl.java new file mode 100644 index 0000000000..468083c839 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceContractMapperImpl.java @@ -0,0 +1,392 @@ +/* + * 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.interfacedef.impl; + +import java.util.List; + +import org.apache.tuscany.sca.interfacedef.Compatibility; +import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.IncompatibleInterfaceContractException; +import org.apache.tuscany.sca.interfacedef.Interface; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; +import org.apache.tuscany.sca.interfacedef.Operation; + +/** + * @version $Rev$ $Date$ + */ +public class InterfaceContractMapperImpl implements InterfaceContractMapper { + + public boolean isCompatible(DataType source, DataType target, boolean passByValue) { + if (source == target) { + return true; + } + if (!passByValue) { + if (source == null || target == null) { + return false; + } + // For local case + return target.getPhysical().isAssignableFrom(source.getPhysical()); + } else { + // FIXME: [rfeng] How to test if two remotable data type is compatible? + // We will need to understand the different typing system used by the databindings + // We should probably delegate to some extensions here + return true; + } + + } + + /** + * Check that two interface contracts are equal. The contracts are equal if the two contracts have the + * same set of operations, with each operation having the same signature, both for forward and callback + * interfaces + * @param source + * @param target + * @return + */ + public boolean isMutuallyCompatible(InterfaceContract source, InterfaceContract target) { + // Are the forward interfaces equal? + if (isMutuallyCompatible(source.getInterface(), target.getInterface())) { + // Is there a Callback interface? + if (source.getCallbackInterface() == null && target.getCallbackInterface() == null) { + return true; + } else { + if (isMutuallyCompatible(source.getCallbackInterface(), target.getCallbackInterface())) { + return true; + } // end if + } // end if + } // end if + return false; + } // end method isEqual + + /** + * Check that two interfaces are equal. The interfaces are equal if the two interfaces have the + * same set of operations, with each operation having the same signature. + * @param source + * @param target + * @return + */ + public boolean isMutuallyCompatible(Interface source, Interface target) { + if (source == target) { + // Shortcut for performance + return true; + } // end if + if (source == null || target == null) { + return false; + } // end if + + if (source.isDynamic() || target.isDynamic()) { + return true; + } + + if (source.isRemotable() != target.isRemotable()) { + return false; + } + if (source.getOperations().size() != target.getOperations().size()) { + return false; + } + + for (Operation operation : source.getOperations()) { + Operation targetOperation = getOperation(target.getOperations(), operation.getName()); + if (targetOperation == null) { + return false; + } + if (!isCompatible(operation, targetOperation, Compatibility.SUBSET)) { + return false; + } + } + return true; + } // end method isEqual + + public boolean isCompatible(Operation source, Operation target, Compatibility compatibilityType) { + return isCompatible(source, target, compatibilityType, true); + } + + public boolean isCompatible(Operation source, Operation target, Compatibility compatibilityType, boolean byValue) { + if (source == target) { + return true; + } + + if (source.isDynamic() || target.isDynamic()) { + return true; + } + + // Check name + if (!source.getName().equals(target.getName())) { + return false; + } + + if (source.getInterface().isRemotable() != target.getInterface().isRemotable()) { + return false; + } + + boolean passByValue = (source.getInterface().isRemotable()) && byValue; + + // if (source.getInterface().isRemotable()) { + // return true; + // } + + // FIXME: We need to deal with wrapped<-->unwrapped conversion + + // Check output type + DataType sourceOutputType = source.getOutputType(); + DataType targetOutputType = target.getOutputType(); + + boolean checkSourceWrapper = true; + List sourceInputType = source.getInputType().getLogical(); + if (source.isWrapperStyle() && source.getWrapper() != null) { + sourceInputType = source.getWrapper().getUnwrappedInputType().getLogical(); + sourceOutputType = source.getWrapper().getUnwrappedOutputType(); + checkSourceWrapper = false; + } + boolean checkTargetWrapper = true; + List targetInputType = target.getInputType().getLogical(); + if (target.isWrapperStyle() && target.getWrapper() != null) { + targetInputType = target.getWrapper().getUnwrappedInputType().getLogical(); + targetOutputType = target.getWrapper().getUnwrappedOutputType(); + checkTargetWrapper = false; + } + + if (checkSourceWrapper != checkTargetWrapper) { + return true; + } + + if (!isCompatible(targetOutputType, sourceOutputType, passByValue)) { + return false; + } + + if (sourceInputType.size() != targetInputType.size()) { + return false; + } + + int size = sourceInputType.size(); + for (int i = 0; i < size; i++) { + if (!isCompatible(sourceInputType.get(i), targetInputType.get(i), passByValue)) { + return false; + } + } + + // Check fault types + for (DataType targetFaultType : target.getFaultTypes()) { + // Source fault types must be the same or superset of target fault + // types + boolean found = true; + for (DataType sourceFaultType : source.getFaultTypes()) { + found = false; + if (isCompatible(targetFaultType, sourceFaultType, passByValue)) { + // Target fault type can be covered by the source fault type + found = true; + break; + } + } + if (!found) { + return false; + } + } + + return true; + } + public boolean isCompatibleByReference(Operation source, Operation target, Compatibility compatibilityType) { + return isCompatible(source, target, compatibilityType, false); + } + + public boolean isCompatibleByValue(Operation source, Operation target, Compatibility compatibilityType) { + return isCompatible(source, target, compatibilityType, true); + } + + // FIXME: How to improve the performance for the lookup + private Operation getOperation(List operations, String name) { + for (Operation op : operations) { + if (op.getName().equals(name)) { + return op; + } + } + return null; + } + + public boolean checkCompatibility(InterfaceContract source, + InterfaceContract target, + Compatibility compatibility, + boolean ignoreCallback, + boolean silent) throws IncompatibleInterfaceContractException { + if (source == target) { + // Shortcut for performance + return true; + } + + if (source == null || target == null) { + return false; + } + + if (source.getInterface() == target.getInterface()) { + return ignoreCallback || isCallbackCompatible(source, target, silent); + } + + if (source.getInterface() == null || target.getInterface() == null) { + return false; + } + + if (source.getInterface().isDynamic() || target.getInterface().isDynamic()) { + return ignoreCallback || isCallbackCompatible(source, target, silent); + } + + if (source.getInterface().isRemotable() != target.getInterface().isRemotable()) { + if (!silent) { + throw new IncompatibleInterfaceContractException("Remotable settings do not match", source, target); + } else { + return false; + } + } + + for (Operation operation : source.getInterface().getOperations()) { + Operation targetOperation = map(target.getInterface(), operation); + if (targetOperation == null) { + if (!silent) { + throw new IncompatibleInterfaceContractException("Operation " + + operation.getName() + + " not found on target", + source, + target); + } else { + return false; + } + } + if (!source.getInterface().isRemotable()) { + // FIXME: for remotable operation, only compare name for now + if (!isCompatible(operation, targetOperation, Compatibility.SUBSET)) { + if (!silent) { + throw new IncompatibleInterfaceContractException("Target operations called " + + operation.getName() + + " are not compatible", + source, + target); + } else { + return false; + } + } + } + } + + return ignoreCallback || isCallbackCompatible(source, target, silent); + } + + protected boolean isCallbackCompatible(InterfaceContract source, InterfaceContract target, boolean silent) + throws IncompatibleInterfaceContractException { + if (source.getCallbackInterface() == null && target.getCallbackInterface() == null) { + return true; + } + if (source.getCallbackInterface() == null || target.getCallbackInterface() == null) { + if (!silent) { + throw new IncompatibleInterfaceContractException("Callback interface doesn't match", source, target); + } else { + return false; + } + } + + for (Operation operation : source.getCallbackInterface().getOperations()) { + Operation targetOperation = + getOperation(target.getCallbackInterface().getOperations(), operation.getName()); + if (targetOperation == null) { + if (!silent) { + throw new IncompatibleInterfaceContractException("Callback operation not found on target", source, + target, null, targetOperation); + } else { + return false; + } + } + if (!source.getCallbackInterface().isRemotable()) { + // FIXME: for remotable operation, only compare name for now + if (!operation.equals(targetOperation)) { + if (!silent) { + throw new IncompatibleInterfaceContractException("Target callback operation is not compatible", + source, target, operation, targetOperation); + } else { + return false; + } + } + } + } + return true; + } + + public boolean isCompatibleSubset(Interface source, Interface target) { + if (source == target) { + // Shortcut for performance + return true; + } + if (source == null || target == null) { + return false; + } + + if (source.isDynamic() || target.isDynamic()) { + return true; + } + + if (source.isRemotable() != target.isRemotable()) { + return false; + } + + for (Operation operation : source.getOperations()) { + Operation targetOperation = getOperation(target.getOperations(), operation.getName()); + if (targetOperation == null) { + return false; + } + if (!isCompatible(operation, targetOperation, Compatibility.SUBSET)) { + return false; + } + } + return true; + } + + public boolean isCompatibleSubset(InterfaceContract source, InterfaceContract target) { + try { + return checkCompatibility(source, target, Compatibility.SUBSET, false, false); + } catch (IncompatibleInterfaceContractException e) { + return false; + } + } + + /** + * @see org.apache.tuscany.sca.interfacedef.InterfaceContractMapper#map(org.apache.tuscany.sca.interfacedef.Interface, + * org.apache.tuscany.sca.interfacedef.Operation) + */ + public Operation map(Interface target, Operation source) { + // TODO: How to handle the case that source operation is dynamic? + if (target == null || target.isDynamic()) { + return source; + } else if (target.isRemotable()) { + for (Operation op : target.getOperations()) { + if (op.getName().equals(source.getName())) { + return op; + } + } + return null; + } else { + for (Operation op : target.getOperations()) { + if (isCompatible(source, op, Compatibility.SUBSET)) { + return op; + } + } + return null; + } + + } + +} diff --git a/sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceImpl.java b/sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceImpl.java new file mode 100644 index 0000000000..c56b5545ce --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/InterfaceImpl.java @@ -0,0 +1,329 @@ +/* + * 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.interfacedef.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.Interface; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.util.WrapperInfo; +import org.apache.tuscany.sca.policy.ExtensionType; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.PolicySet; + +/** + * Represents a service interface. + * + * @version $Rev$ $Date$ + * @tuscany.spi.extension.inheritfrom + */ +public class InterfaceImpl implements Interface { + + private Boolean remotable; + private boolean conversational; + private OperationList operations = new OperationList(); + private boolean unresolved; + + private ExtensionType type; + private List policySets = new ArrayList(); + private List requiredIntents = new ArrayList(); + private Map attributes = new ConcurrentHashMap(); + + public boolean isRemotable() { + boolean value = false; + if (remotable != null && remotable.booleanValue()) { + value = true; + } + return value; + } + + public void setRemotable(boolean remotable) { + this.remotable = Boolean.valueOf(remotable); + } + + public boolean isRemotableSet() { + return remotable == null ? false : true; + } + + public List getOperations() { + return operations; + } + + public boolean isUnresolved() { + return unresolved; + } + + public void setUnresolved(boolean undefined) { + this.unresolved = undefined; + } + + /** + * @return the conversational + */ + public boolean isConversational() { + return conversational; + } + + /** + * @param conversational the conversational to set + */ + public void setConversational(boolean conversational) { + this.conversational = conversational; + } + + private class OperationList extends ArrayList { + private static final long serialVersionUID = -903469106307606099L; + + @Override + public Operation set(int index, Operation element) { + element.setInterface(InterfaceImpl.this); + return super.set(index, element); + } + + @Override + public void add(int index, Operation element) { + element.setInterface(InterfaceImpl.this); + super.add(index, element); + } + + @Override + public boolean add(Operation o) { + o.setInterface(InterfaceImpl.this); + return super.add(o); + } + + @Override + public boolean addAll(Collection c) { + for (Operation op : c) { + op.setInterface(InterfaceImpl.this); + } + return super.addAll(c); + } + + @Override + public boolean addAll(int index, Collection c) { + for (Operation op : c) { + op.setInterface(InterfaceImpl.this); + } + return super.addAll(index, c); + } + + } + + @Deprecated + public void setDefaultDataBinding(String dataBinding) { + for (Operation op : getOperations()) { + if (op.getDataBinding() == null) { + op.setDataBinding(dataBinding); + DataType> inputType = op.getInputType(); + if (inputType != null) { + for (DataType d : inputType.getLogical()) { + if (d.getDataBinding() == null) { + d.setDataBinding(dataBinding); + } + } + } + DataType outputType = op.getOutputType(); + if (outputType != null && outputType.getDataBinding() == null) { + outputType.setDataBinding(dataBinding); + } + List faultTypes = op.getFaultTypes(); + if (faultTypes != null) { + for (DataType d : faultTypes) { + if (d.getDataBinding() == null) { + d.setDataBinding(dataBinding); + } + DataType ft = (DataType) d.getLogical(); + if (ft.getDataBinding() == null) { + ft.setDataBinding(dataBinding); + } + + } + } + if (op.isWrapperStyle()) { + WrapperInfo wrapper = op.getWrapper(); + if (wrapper != null) { + DataType> unwrappedInputType = wrapper.getUnwrappedInputType(); + if (unwrappedInputType != null) { + for (DataType d : unwrappedInputType.getLogical()) { + if (d.getDataBinding() == null) { + d.setDataBinding(dataBinding); + } + } + } + DataType unwrappedOutputType = wrapper.getUnwrappedOutputType(); + if (unwrappedOutputType != null && unwrappedOutputType.getDataBinding() == null) { + unwrappedOutputType.setDataBinding(dataBinding); + } + } + } + } + } + } + + private void setDataBinding(DataType dataType, String dataBinding) { + if ("java:array".equals(dataType.getDataBinding())) { + setDataBinding((DataType)dataType.getLogical(), dataBinding); + } else { + dataType.setDataBinding(dataBinding); + } + } + + public void resetDataBinding(String dataBinding) { + for (Operation op : getOperations()) { + op.setDataBinding(dataBinding); + DataType> inputType = op.getInputType(); + if (inputType != null) { + for (DataType d : inputType.getLogical()) { + setDataBinding(d, dataBinding); + } + } + DataType outputType = op.getOutputType(); + if (outputType != null) { + setDataBinding(outputType, dataBinding); + } + List faultTypes = op.getFaultTypes(); + if (faultTypes != null) { + for (DataType d : faultTypes) { + setDataBinding(d, dataBinding); + setDataBinding((DataType) d.getLogical(), dataBinding); + } + } + if (op.isWrapperStyle()) { + WrapperInfo wrapper = op.getWrapper(); + if (wrapper != null) { + DataType> unwrappedInputType = wrapper.getUnwrappedInputType(); + if (unwrappedInputType != null) { + for (DataType d : unwrappedInputType.getLogical()) { + setDataBinding(d, dataBinding); + } + } + DataType unwrappedOutputType = wrapper.getUnwrappedOutputType(); + if (unwrappedOutputType != null) { + setDataBinding(unwrappedOutputType, dataBinding); + } + } + } + } + } + + public void resetInterfaceInputTypes(Interface newInterface){ + for (int i = 0; i < getOperations().size(); i++) { + // only remote interfaces only have a data type model defined + // and in this case operations cannot be overloaded so match + // operations by name + Operation oldOperation = getOperations().get(i); + Operation newOperation = null; + + for (Operation tmpOperation : newInterface.getOperations()){ + if (tmpOperation.getName().equals(oldOperation.getName())){ + newOperation = tmpOperation; + } + } + + if (newOperation == null){ + break; + } + + // set input types + oldOperation.setInputType(newOperation.getInputType()); + + // set wrapper + if (newOperation.isWrapperStyle()) { + oldOperation.setWrapperStyle(true); + oldOperation.setWrapper(newOperation.getWrapper()); + } + } + } + + public void resetInterfaceOutputTypes(Interface newInterface){ + for (int i = 0; i < getOperations().size(); i++) { + // only remote interfaces only have a data type model defined + // and in this case operations cannot be overloaded so match + // operations by name + Operation oldOperation = getOperations().get(i); + Operation newOperation = null; + + for (Operation tmpOperation : newInterface.getOperations()){ + if (tmpOperation.getName().equals(oldOperation.getName())){ + newOperation = tmpOperation; + } + } + + if (newOperation == null){ + break; + } + + // set output types + oldOperation.setOutputType(newOperation.getOutputType()); + + // set fault types + oldOperation.setFaultTypes(newOperation.getFaultTypes()); + + // set wrapper + if (newOperation.isWrapperStyle()) { + oldOperation.setWrapperStyle(true); + oldOperation.setWrapper(newOperation.getWrapper()); + } + } + } + + public boolean isDynamic() { + return false; + } + + public List getPolicySets() { + return policySets; + } + + public List getRequiredIntents() { + return requiredIntents; + } + + public ExtensionType getExtensionType() { + return type; + } + + public void setExtensionType(ExtensionType type) { + this.type = type; + } + + @Override + public Object clone() throws CloneNotSupportedException { + InterfaceImpl copy = (InterfaceImpl)super.clone(); + copy.operations = new OperationList(); + for (Operation operation : this.operations) { + Operation clonedOperation = (Operation)operation.clone(); + copy.operations.add(clonedOperation); + } + copy.attributes = new ConcurrentHashMap(); + copy.attributes.putAll(attributes); + return copy; + } + + public Map getAttributes() { + return attributes; + } + +} diff --git a/sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java b/sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java new file mode 100644 index 0000000000..0acb326a47 --- /dev/null +++ b/sca-java-2.x/tags/2.0-M5-RC1/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java @@ -0,0 +1,274 @@ +/* + * 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.interfacedef.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.Interface; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.util.WrapperInfo; +import org.apache.tuscany.sca.interfacedef.util.XMLType; +import org.apache.tuscany.sca.policy.ExtensionType; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.PolicySet; + +/** + * Represents an operation on a service interface. + * + * @version $Rev$ $Date$ + * @tuscany.spi.extension.inheritfrom + */ +public class OperationImpl implements Operation { + + private String name; + private boolean unresolved; + private DataType outputType; + private DataType> inputType; + private List faultTypes; + private Interface interfaze; + private boolean nonBlocking; + private boolean wrapperStyle; + private WrapperInfo wrapper; + private boolean dynamic; + + private Map attributes = new ConcurrentHashMap(); + + private Map>> faultBeans; + + private List applicablePolicySets = new ArrayList(); + private List policySets = new ArrayList(); + private List requiredIntents = new ArrayList(); + private ExtensionType type; + + /** + * @param name + */ + public OperationImpl() { + inputType = new DataTypeImpl>("idl:input", Object[].class, new ArrayList()); + faultTypes = new ArrayList(); + faultBeans = new HashMap>>(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isUnresolved() { + return unresolved; + } + + public void setUnresolved(boolean undefined) { + this.unresolved = undefined; + } + + /** + * @return the faultTypes + */ + public List getFaultTypes() { + return faultTypes; + } + + /** + * @param faultTypes the faultTypes to set + */ + public void setFaultTypes(List faultTypes) { + this.faultTypes = faultTypes; + } + + /** + * @return the inputType + */ + public DataType> getInputType() { + return inputType; + } + + /** + * @param inputType the inputType to set + */ + public void setInputType(DataType> inputType) { + this.inputType = inputType; + } + + /** + * @return the outputType + */ + public DataType getOutputType() { + return outputType; + } + + /** + * @param outputType the outputType to set + */ + public void setOutputType(DataType outputType) { + this.outputType = outputType; + } + + /** + * @return the interface + */ + public Interface getInterface() { + return interfaze; + } + + /** + * @param interfaze the interface to set + */ + public void setInterface(Interface interfaze) { + this.interfaze = interfaze; + } + + /** + * @return the nonBlocking + */ + public boolean isNonBlocking() { + return nonBlocking; + } + + /** + * @param nonBlocking the nonBlocking to set + */ + public void setNonBlocking(boolean nonBlocking) { + this.nonBlocking = nonBlocking; + } + + /** + * @return the wrapperInfo + */ + public WrapperInfo getWrapper() { + return wrapper; + } + + /** + * @param wrapperInfo the wrapperInfo to set + */ + public void setWrapper(WrapperInfo wrapperInfo) { + this.wrapper = wrapperInfo; + } + + /** + * @return the wrapperStyle + */ + public boolean isWrapperStyle() { + return wrapperStyle; + } + + /** + * @param wrapperStyle the wrapperStyle to set + */ + public void setWrapperStyle(boolean wrapperStyle) { + this.wrapperStyle = wrapperStyle; + } + + public String getDataBinding() { + return wrapper != null ? wrapper.getDataBinding() : null; + } + + public void setDataBinding(String dataBinding) { + if (wrapper != null) { + wrapper.setDataBinding(dataBinding); + } + } + + public boolean isDynamic() { + return dynamic; + } + + public void setDynamic(boolean b) { + this.dynamic = b; + } + + public Map>> getFaultBeans() { + return faultBeans; + } + + public void setFaultBeans(Map>> faultBeans) { + this.faultBeans = faultBeans; + } + + @Override + public OperationImpl clone() throws CloneNotSupportedException { + OperationImpl copy = (OperationImpl) super.clone(); + + final List clonedFaultTypes = new ArrayList(this.faultTypes.size()); + for (DataType t : this.faultTypes) { + clonedFaultTypes.add((DataType) t.clone()); + } + copy.faultTypes = clonedFaultTypes; + + List clonedLogicalTypes = new ArrayList(); + for (DataType t : inputType.getLogical()) { + DataType type = (DataType) t.clone(); + clonedLogicalTypes.add(type); + } + DataType> clonedInputType = + new DataTypeImpl>(inputType.getPhysical(), clonedLogicalTypes); + clonedInputType.setDataBinding(inputType.getDataBinding()); + copy.inputType = clonedInputType; + + if (this.outputType != null) { + copy.outputType = (DataType) this.outputType.clone(); + } + + copy.attributes = new ConcurrentHashMap(); + copy.attributes.putAll(attributes); + + // [rfeng] We need to clone the wrapper as it holds the databinding information + if (wrapper != null) { + copy.wrapper = (WrapperInfo)wrapper.clone(); + } + + return copy; + } + + public List getApplicablePolicySets() { + return applicablePolicySets; + } + + public List getPolicySets() { + return policySets; + } + + public List getRequiredIntents() { + return requiredIntents; + } + + public ExtensionType getExtensionType() { + return type; + } + + public void setExtensionType(ExtensionType type) { + this.type = type; + } + + public Map getAttributes() { + return attributes; + } + +} -- cgit v1.2.3