You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by ad...@apache.org on 2008/07/08 07:19:32 UTC

svn commit: r674723 [4/4] - in /tuscany/sandbox/mobile-android: core-databinding/ core-databinding/src/ core-databinding/src/main/ core-databinding/src/main/java/ core-databinding/src/main/java/org/ core-databinding/src/main/java/org/apache/ core-datab...

Added: tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java?rev=674723&view=auto
==============================================================================
--- tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java (added)
+++ tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceIntrospectorImpl.java Mon Jul  7 22:19:28 2008
@@ -0,0 +1,225 @@
+/*
+ * 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.java.impl;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+//import java.rmi.Remote;
+//import java.rmi.RemoteException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.interfacedef.ConversationSequence;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.InvalidCallbackException;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.InvalidOperationException;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.OverloadedOperationException;
+import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
+import org.apache.tuscany.sca.interfacedef.java.introspect.JavaInterfaceVisitor;
+import org.apache.tuscany.sca.interfacedef.util.XMLType;
+import org.osoa.sca.annotations.Conversational;
+import org.osoa.sca.annotations.EndsConversation;
+import org.osoa.sca.annotations.OneWay;
+import org.osoa.sca.annotations.Remotable;
+
+/**
+ * Default implementation of a Java interface introspector.
+ * 
+ * @version $Rev: 641897 $ $Date: 2008-03-27 09:07:00 -0800 (Thu, 27 Mar 2008) $
+ */
+public class JavaInterfaceIntrospectorImpl {
+    public static final String IDL_INPUT = "idl:input";
+
+    private static final String UNKNOWN_DATABINDING = null;
+
+    private List<JavaInterfaceVisitor> visitors = new ArrayList<JavaInterfaceVisitor>();
+
+    public JavaInterfaceIntrospectorImpl(JavaInterfaceFactory javaFactory) {
+        this.visitors = javaFactory.getInterfaceVisitors();
+    }
+
+    public void introspectInterface(JavaInterface javaInterface, Class<?> clazz) throws InvalidInterfaceException {
+        javaInterface.setJavaClass(clazz);
+
+        boolean remotable = clazz.isAnnotationPresent(Remotable.class);
+        
+        // Consider @javax.ejb.Remote, java.rmi.Remote and javax.ejb.EJBObject
+        // equivalent to @Remotable
+        if (!remotable) {
+            for (Annotation annotation: clazz.getAnnotations()) {
+                if ("javax.ejb.Remote".equals(annotation.annotationType().getName())) {
+                    remotable = true;
+                    break;
+                }
+            }
+        }
+        if (!remotable) {
+            for (Class<?> superInterface: clazz.getInterfaces()) {
+                if (/*Remote.class == superInterface || */"javax.ejb.EJBObject".equals(superInterface.getName())) {
+                    remotable = true;
+                    break;
+                }
+            }
+        }
+        
+        javaInterface.setRemotable(remotable);
+
+        boolean conversational = clazz.isAnnotationPresent(Conversational.class);
+        javaInterface.setConversational(conversational);
+
+        Class<?> callbackClass = null;
+        org.osoa.sca.annotations.Callback callback = clazz.getAnnotation(org.osoa.sca.annotations.Callback.class);
+        if (callback != null && !Void.class.equals(callback.value())) {
+            callbackClass = callback.value();
+        } else if (callback != null && Void.class.equals(callback.value())) {
+            throw new InvalidCallbackException("No callback interface specified on annotation");
+        }
+        javaInterface.setCallbackClass(callbackClass);
+
+        String ns = JavaInterfaceUtil.getNamespace(clazz);
+        javaInterface.getOperations().addAll(getOperations(clazz, remotable, conversational, ns));
+
+        for (JavaInterfaceVisitor extension : visitors) {
+            extension.visitInterface(javaInterface);
+        }
+    }
+
+    private Class<?>[] getActualTypes(Type[] types, Class<?>[] rawTypes, Map<String, Type> typeBindings) {
+        Class<?>[] actualTypes = new Class<?>[types.length];
+        for (int i = 0; i < actualTypes.length; i++) {
+            actualTypes[i] = getActualType(types[i], rawTypes[i], typeBindings);
+        }
+        return actualTypes;
+    }
+
+    private Class<?> getActualType(Type type, Class<?> rawType, Map<String, Type> typeBindings) {
+        if (type instanceof TypeVariable<?>) {
+            TypeVariable<?> typeVariable = (TypeVariable<?>)type;
+            type = typeBindings.get(typeVariable.getName());
+            if (type instanceof Class<?>) {
+                return (Class<?>)type;
+            }
+        }
+        return rawType;
+    }
+
+    private <T> List<Operation> getOperations(Class<T> clazz, boolean remotable, boolean conversational, String ns)
+        throws InvalidInterfaceException {
+
+        Type[] genericInterfaces = clazz.getGenericInterfaces();
+        Map<String, Type> typeBindings = new HashMap<String, Type>();
+        for (Type genericInterface : genericInterfaces) {
+            if (genericInterface instanceof ParameterizedType) {
+                ParameterizedType parameterizedType = (ParameterizedType)genericInterface;
+                TypeVariable<?>[] typeVariables = ((Class<?>)parameterizedType.getRawType()).getTypeParameters();
+                Type[] typeArguments = parameterizedType.getActualTypeArguments();
+                for (int i = 0; i < typeArguments.length; i++) {
+                    typeBindings.put(typeVariables[i].getName(), typeArguments[i]);
+                }
+            }
+        }
+
+        Method[] methods = clazz.getMethods();
+        List<Operation> operations = new ArrayList<Operation>(methods.length);
+        Set<String> names = remotable ? new HashSet<String>() : null;
+        for (Method method : methods) {
+            if (method.getDeclaringClass() == Object.class) {
+                // Skip the methods on the Object.class
+                continue;
+            }
+            String name = method.getName();
+            if (remotable && names.contains(name)) {
+                throw new OverloadedOperationException(method);
+            }
+            if (remotable) {
+                names.add(name);
+            }
+
+            Class<?> returnType = getActualType(method.getGenericReturnType(), method.getReturnType(), typeBindings);
+            Class<?>[] parameterTypes =
+                getActualTypes(method.getGenericParameterTypes(), method.getParameterTypes(), typeBindings);
+            Class<?>[] faultTypes =
+                getActualTypes(method.getGenericExceptionTypes(), method.getExceptionTypes(), typeBindings);
+
+            boolean nonBlocking = method.isAnnotationPresent(OneWay.class);
+            ConversationSequence conversationSequence = ConversationSequence.CONVERSATION_NONE;
+            if (method.isAnnotationPresent(EndsConversation.class)) {
+                if (!conversational) {
+                    throw new InvalidOperationException(
+                                                        "Method is marked as end conversation but contract is not conversational",
+                                                        method);
+                }
+                conversationSequence = ConversationSequence.CONVERSATION_END;
+            } else if (conversational) {
+                conversationSequence = ConversationSequence.CONVERSATION_CONTINUE;
+            }
+
+            // Set outputType to null for void
+            XMLType xmlReturnType = new XMLType(new QName(ns, "return"), null);
+            DataType<XMLType> returnDataType =
+                returnType == void.class ? null : new DataTypeImpl<XMLType>(UNKNOWN_DATABINDING, returnType,
+                                                                            xmlReturnType);
+            List<DataType> paramDataTypes = new ArrayList<DataType>(parameterTypes.length);
+            for (int i = 0; i < parameterTypes.length; i++) {
+                Class paramType = parameterTypes[i];
+                XMLType xmlParamType = new XMLType(new QName(ns, "arg" + i), null);
+                paramDataTypes.add(new DataTypeImpl<XMLType>(UNKNOWN_DATABINDING, paramType, xmlParamType));
+            }
+            List<DataType> faultDataTypes = new ArrayList<DataType>(faultTypes.length);
+            for (Class<?> faultType : faultTypes) {
+                // Only add checked exceptions
+                // JAXWS Specification v2.1 section 3.7 says RemoteException should not be mapped
+                if (Exception.class.isAssignableFrom(faultType) && (!RuntimeException.class.isAssignableFrom(faultType))
+                		/*&& (!RemoteException.class.isAssignableFrom(faultType))*/) {
+                    XMLType xmlFaultType = new XMLType(new QName(ns, faultType.getSimpleName()), null);
+                    DataType<XMLType> faultDataType = new DataTypeImpl<XMLType>(faultType, xmlFaultType);
+                    faultDataTypes.add(new DataTypeImpl<DataType>(UNKNOWN_DATABINDING, faultType, faultDataType));
+                }
+            }
+
+            DataType<List<DataType>> inputType =
+                new DataTypeImpl<List<DataType>>(IDL_INPUT, Object[].class, paramDataTypes);
+            JavaOperation operation = new JavaOperationImpl();
+            operation.setName(name);
+            operation.setInputType(inputType);
+            operation.setOutputType(returnDataType);
+            operation.setFaultTypes(faultDataTypes);
+            operation.setConversationSequence(conversationSequence);
+            operation.setNonBlocking(nonBlocking);
+            operation.setJavaMethod(method);
+            operations.add(operation);
+        }
+        return operations;
+    }
+
+}

Added: tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceUtil.java
URL: http://svn.apache.org/viewvc/tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceUtil.java?rev=674723&view=auto
==============================================================================
--- tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceUtil.java (added)
+++ tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceUtil.java Mon Jul  7 22:19:28 2008
@@ -0,0 +1,151 @@
+/*
+ * 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.java.impl;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.List;
+
+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.java.JavaOperation;
+
+/**
+ * Contains methods for mapping between an operation in a
+ * {@link org.apache.tuscany.spi.model.ServiceContract} and a method defined by
+ * a Java interface
+ * 
+ * @version $Rev: 634877 $ $Date: 2008-03-07 16:45:07 -0800 (Fri, 07 Mar 2008) $
+ */
+public final class JavaInterfaceUtil {
+
+    private JavaInterfaceUtil() {
+    }
+
+    /**
+     * Return the method on the implementation class that matches the operation.
+     * 
+     * @param implClass the implementation class or interface
+     * @param operation the operation to match
+     * @return the method described by the operation
+     * @throws NoSuchMethodException if no such method exists
+     * @Deprecated
+     */
+    public static Method findMethod(Class<?> implClass, Operation operation) throws NoSuchMethodException {
+        String name = operation.getName();
+        if (operation instanceof JavaOperation) {
+            name = ((JavaOperation)operation).getJavaMethod().getName();
+        }
+        Interface interface1 = operation.getInterface();
+        if (interface1 != null && interface1.isRemotable()) {
+            for (Method m : implClass.getMethods()) {
+                if (m.getName().equals(name)) {
+                    return m;
+                }
+            }
+            throw new NoSuchMethodException("No matching method for operation " + operation.getName()
+                + " is found on "
+                + implClass);
+        }
+        Class<?>[] paramTypes = getPhysicalTypes(operation);
+        return implClass.getMethod(name, paramTypes);
+    }
+
+    /**
+     * @Deprecated
+     */
+    private static Class<?>[] getPhysicalTypes(Operation operation) {
+        DataType<List<DataType>> inputType = operation.getInputType();
+        if (inputType == null) {
+            return new Class<?>[] {};
+        }
+        List<DataType> types = inputType.getLogical();
+        Class<?>[] javaTypes = new Class<?>[types.size()];
+        for (int i = 0; i < javaTypes.length; i++) {
+            Type physical = types.get(i).getPhysical();
+            if (physical instanceof Class<?>) {
+                javaTypes[i] = (Class<?>)physical;
+            } else {
+                throw new UnsupportedOperationException();
+            }
+        }
+        return javaTypes;
+    }
+
+    /**
+     * Searches a collection of operations for a match against the given method
+     * 
+     * @param method the method to match
+     * @param operations the operations to match against
+     * @return a matching operation or null
+     * @Deprecated
+     */
+    public static Operation findOperation(Method method, Collection<Operation> operations) {
+        for (Operation operation : operations) {
+            if (match(operation, method)) {
+                return operation;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Determines if the given operation matches the given method
+     * 
+     * @return true if the operation matches, false if does not
+     */
+    private static boolean match(Operation operation, Method method) {
+        Class<?>[] params = method.getParameterTypes();
+        DataType<List<DataType>> inputType = operation.getInputType();
+        List<DataType> types = inputType.getLogical();
+        boolean found = true;
+        if (types.size() == params.length && method.getName().equals(operation.getName())) {
+            for (int i = 0; i < params.length; i++) {
+                Class<?> clazz = params[i];
+                if (!clazz.equals(operation.getInputType().getLogical().get(i).getPhysical())) {
+                    found = false;
+                }
+            }
+        } else {
+            found = false;
+        }
+        return found;
+
+    }
+    
+    public static String getNamespace(Class<?> cls) {
+        Package pkg = cls.getPackage();
+        if (pkg == null) {
+            return "";
+        }
+        StringBuffer ns = new StringBuffer("http://");
+        String[] names = pkg.getName().split("\\.");
+        for (int i = names.length - 1; i >= 0; i--) {
+            ns.append(names[i]);
+            if (i != 0) {
+                ns.append('.');
+            }
+        }
+        ns.append('/');
+        return ns.toString();
+    }
+
+}

Added: tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaOperationImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaOperationImpl.java?rev=674723&view=auto
==============================================================================
--- tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaOperationImpl.java (added)
+++ tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaOperationImpl.java Mon Jul  7 22:19:28 2008
@@ -0,0 +1,73 @@
+/*
+ * 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.java.impl;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.sca.interfacedef.impl.OperationImpl;
+import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
+
+/**
+ * Represents a Java operation. 
+ *
+ * @version $Rev: 616060 $ $Date: 2008-01-28 13:39:55 -0800 (Mon, 28 Jan 2008) $
+ */
+public class JavaOperationImpl extends OperationImpl implements JavaOperation {
+
+    private Method method;
+
+    public Method getJavaMethod() {
+        return method;
+    }
+
+    public void setJavaMethod(Method method) {
+        this.method = method;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        result = prime * result + ((method == null) ? 0 : method.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!super.equals(obj))
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        final JavaOperationImpl other = (JavaOperationImpl)obj;
+        if (method == null) {
+            if (other.method != null)
+                return false;
+        } else if (!method.equals(other.method))
+            return false;
+        return true;
+    }
+
+    public String toString() {
+        return method == null ? "null" : method.toGenericString();
+    }
+
+}

Added: tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/PolicyJavaInterfaceVisitor.java
URL: http://svn.apache.org/viewvc/tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/PolicyJavaInterfaceVisitor.java?rev=674723&view=auto
==============================================================================
--- tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/PolicyJavaInterfaceVisitor.java (added)
+++ tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/PolicyJavaInterfaceVisitor.java Mon Jul  7 22:19:28 2008
@@ -0,0 +1,159 @@
+/*
+ * 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.java.impl;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
+import org.apache.tuscany.sca.interfacedef.java.introspect.JavaInterfaceVisitor;
+import org.apache.tuscany.sca.policy.Intent;
+import org.apache.tuscany.sca.policy.PolicyFactory;
+import org.apache.tuscany.sca.policy.PolicySet;
+import org.osoa.sca.annotations.PolicySets;
+import org.osoa.sca.annotations.Requires;
+
+/**
+ * Processes an {@link org.osoa.sca.annotations.Requires} annotation
+ * 
+ * @version $Rev:
+ */
+public class PolicyJavaInterfaceVisitor implements JavaInterfaceVisitor {
+    private PolicyFactory policyFactory;
+
+    public PolicyJavaInterfaceVisitor(PolicyFactory policyFactory) {
+        super();
+        this.policyFactory = policyFactory;
+    }
+
+    private QName getQName(String intentName) {
+        QName qname;
+        if (intentName.startsWith("{")) {
+            int i = intentName.indexOf('}');
+            if (i != -1) {
+                qname = new QName(intentName.substring(1, i), intentName.substring(i + 1));
+            } else {
+                qname = new QName("", intentName);
+            }
+        } else {
+            qname = new QName("", intentName);
+        }
+        return qname;
+    }
+
+    /**
+     * Read policy intents on the given interface or class 
+     * @param clazz
+     * @param requiredIntents
+     */
+    private void readIntentsAndPolicySets(Class<?> clazz, List<Intent> requiredIntents, List<PolicySet> policySets) {
+        Requires intentAnnotation = clazz.getAnnotation(Requires.class);
+        if (intentAnnotation != null) {
+            String[] intentNames = intentAnnotation.value();
+            if (intentNames.length != 0) {
+                for (String intentName : intentNames) {
+
+                    // Add each intent to the list
+                    Intent intent = policyFactory.createIntent();
+                    intent.setName(getQName(intentName));
+                    requiredIntents.add(intent);
+                }
+            }
+        }
+
+        PolicySets policySetAnnotation = clazz.getAnnotation(PolicySets.class);
+        if (policySetAnnotation != null) {
+            String[] policySetNames = policySetAnnotation.value();
+            if (policySetNames.length != 0) {
+                for (String policySetName : policySetNames) {
+
+                    // Add each intent to the list
+                    PolicySet policySet = policyFactory.createPolicySet();
+                    policySet.setName(getQName(policySetName));
+                    policySets.add(policySet);
+                }
+            }
+        }
+    }
+
+    private void readIntents(Requires intentAnnotation, List<Intent> requiredIntents) {
+        //Requires intentAnnotation = method.getAnnotation(Requires.class);
+        if (intentAnnotation != null) {
+            String[] intentNames = intentAnnotation.value();
+            if (intentNames.length != 0) {
+                //Operation operation = assemblyFactory.createOperation();
+                //operation.setName(method.getName());
+                //operation.setUnresolved(true);
+                for (String intentName : intentNames) {
+
+                    // Add each intent to the list, associated with the
+                    // operation corresponding to the annotated method
+                    Intent intent = policyFactory.createIntent();
+                    intent.setName(getQName(intentName));
+                    //intent.getOperations().add(operation);
+                    requiredIntents.add(intent);
+                }
+            }
+        }
+    }
+
+    private void readPolicySets(PolicySets policySetAnnotation, List<PolicySet> policySets) {
+        if (policySetAnnotation != null) {
+            String[] policySetNames = policySetAnnotation.value();
+            if (policySetNames.length != 0) {
+                //Operation operation = assemblyFactory.createOperation();
+                //operation.setName(method.getName());
+                //operation.setUnresolved(true);
+                for (String policySetName : policySetNames) {
+                    // Add each intent to the list, associated with the
+                    // operation corresponding to the annotated method
+                    PolicySet policySet = policyFactory.createPolicySet();
+                    policySet.setName(getQName(policySetName));
+                    //intent.getOperations().add(operation);
+                    policySets.add(policySet);
+                }
+            }
+        }
+    }
+
+    public void visitInterface(JavaInterface javaInterface) throws InvalidInterfaceException {
+
+        if (javaInterface.getJavaClass() != null) {
+            readIntentsAndPolicySets(javaInterface.getJavaClass(), javaInterface.getRequiredIntents(), javaInterface
+                .getPolicySets());
+
+            // Read intents on the service interface methods 
+            List<Operation> operations = javaInterface.getOperations();
+            for (Operation op : operations) {
+                JavaOperation operation = (JavaOperation)op;
+                Method method = operation.getJavaMethod();
+                if (method.getAnnotation(Requires.class) != null || method.getAnnotation(PolicySets.class) != null) {
+                    readIntents(method.getAnnotation(Requires.class), op.getRequiredIntents());
+                    readPolicySets(method.getAnnotation(PolicySets.class), op.getPolicySets());
+                }
+            }
+        }
+    }
+
+}

Added: tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/introspect/JavaInterfaceVisitor.java
URL: http://svn.apache.org/viewvc/tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/introspect/JavaInterfaceVisitor.java?rev=674723&view=auto
==============================================================================
--- tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/introspect/JavaInterfaceVisitor.java (added)
+++ tuscany/sandbox/mobile-android/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/introspect/JavaInterfaceVisitor.java Mon Jul  7 22:19:28 2008
@@ -0,0 +1,39 @@
+/*
+ * 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.java.introspect;
+
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+
+/**
+ * Implementations introspect metadata on a Java interface, populating the
+ * corresponding {@link JavaInterface}
+ * 
+ * @version $Rev: 537404 $ $Date: 2007-05-12 04:51:42 -0800 (Sat, 12 May 2007) $
+ */
+public interface JavaInterfaceVisitor {
+
+    /**
+     * Visit a java interface
+     * @param javaInterface
+     * @throws InvalidInterfaceException
+     */
+    void visitInterface(JavaInterface javaInterface) throws InvalidInterfaceException;
+
+}

Added: tuscany/sandbox/mobile-android/interface-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory
URL: http://svn.apache.org/viewvc/tuscany/sandbox/mobile-android/interface-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory?rev=674723&view=auto
==============================================================================
--- tuscany/sandbox/mobile-android/interface-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory (added)
+++ tuscany/sandbox/mobile-android/interface-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory Mon Jul  7 22:19:28 2008
@@ -0,0 +1,18 @@
+# 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. 
+
+org.apache.tuscany.sca.interfacedef.java.DefaultJavaInterfaceFactory
\ No newline at end of file

Added: tuscany/sandbox/mobile-android/interface-java/src/test/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceUtilTestCase.java
URL: http://svn.apache.org/viewvc/tuscany/sandbox/mobile-android/interface-java/src/test/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceUtilTestCase.java?rev=674723&view=auto
==============================================================================
--- tuscany/sandbox/mobile-android/interface-java/src/test/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceUtilTestCase.java (added)
+++ tuscany/sandbox/mobile-android/interface-java/src/test/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceUtilTestCase.java Mon Jul  7 22:19:28 2008
@@ -0,0 +1,121 @@
+/*
+ * 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.java.impl;
+
+import static org.apache.tuscany.sca.interfacedef.java.impl.JavaInterfaceUtil.findOperation;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
+import org.apache.tuscany.sca.interfacedef.impl.OperationImpl;
+
+/**
+ * @version $Rev: 614967 $ $Date: 2008-01-24 12:00:04 -0800 (Thu, 24 Jan 2008) $
+ */
+public class JavaInterfaceUtilTestCase extends TestCase {
+    private List<Operation> operations;
+
+    public void testNoParamsFindOperation() throws Exception {
+        Method method = Foo.class.getMethod("foo");
+        Operation ret = findOperation(method, operations);
+        assertEquals("foo", ret.getName());
+        assertEquals(0, method.getParameterTypes().length);
+    }
+
+    public void testParamsFindOperation() throws Exception {
+        Method method = Foo.class.getMethod("foo", String.class);
+        Operation ret = findOperation(method, operations);
+        assertEquals("foo", ret.getName());
+        assertEquals(String.class, method.getParameterTypes()[0]);
+    }
+
+    public void testPrimitiveParamFindOperation() throws NoSuchMethodException {
+        Method method = Foo.class.getMethod("foo", Integer.TYPE);
+        Operation operation = findOperation(method, operations);
+        assertEquals(Integer.TYPE, operation.getInputType().getLogical().get(0).getPhysical());
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        Operation operation = newOperation("foo");
+        List<DataType> types = new ArrayList<DataType>();
+        DataType<List<DataType>> inputType = new DataTypeImpl<List<DataType>>(Object[].class, types);
+        operation.setInputType(inputType);
+
+        operations = new ArrayList<Operation>();
+        operations.add(operation);
+
+        types = new ArrayList<DataType>();
+        inputType = new DataTypeImpl<List<DataType>>(Object[].class, types);
+        DataType type = new DataTypeImpl<Class>(String.class, Object.class);
+        types.add(type);
+        operation = newOperation("foo");
+        operation.setInputType(inputType);
+        operations.add(operation);
+
+        types = new ArrayList<DataType>();
+        type = new DataTypeImpl<Class>(String.class, Object.class);
+        DataType type2 = new DataTypeImpl<Class>(String.class, Object.class);
+        types.add(type);
+        types.add(type2);
+        inputType = new DataTypeImpl<List<DataType>>(Object[].class, types);
+        operation = newOperation("foo");
+        operation.setInputType(inputType);
+        operations.add(operation);
+
+        types = new ArrayList<DataType>();
+        type = new DataTypeImpl<Class>(Integer.class, Object.class);
+        types.add(type);
+        inputType = new DataTypeImpl<List<DataType>>(Object[].class, types);
+        operation = newOperation("foo");
+        operation.setInputType(inputType);
+        operations.add(operation);
+
+        types = new ArrayList<DataType>();
+        type = new DataTypeImpl<Class>(Integer.TYPE, Object.class);
+        types.add(type);
+        inputType = new DataTypeImpl<List<DataType>>(Object[].class, types);
+        operation = newOperation("foo");
+        operation.setInputType(inputType);
+        operations.add(operation);
+
+    }
+
+    private interface Foo {
+        void foo();
+
+        void foo(String foo);
+
+        void foo(int b);
+    }
+
+    private static Operation newOperation(String name) {
+        Operation operation = new OperationImpl();
+        operation.setName(name);
+        return operation;
+    }
+}

Added: tuscany/sandbox/mobile-android/interface-java/src/test/java/org/apache/tuscany/sca/interfacedef/java/introspection/impl/ConversationalIntrospectionTestCase.java
URL: http://svn.apache.org/viewvc/tuscany/sandbox/mobile-android/interface-java/src/test/java/org/apache/tuscany/sca/interfacedef/java/introspection/impl/ConversationalIntrospectionTestCase.java?rev=674723&view=auto
==============================================================================
--- tuscany/sandbox/mobile-android/interface-java/src/test/java/org/apache/tuscany/sca/interfacedef/java/introspection/impl/ConversationalIntrospectionTestCase.java (added)
+++ tuscany/sandbox/mobile-android/interface-java/src/test/java/org/apache/tuscany/sca/interfacedef/java/introspection/impl/ConversationalIntrospectionTestCase.java Mon Jul  7 22:19:28 2008
@@ -0,0 +1,98 @@
+/*
+ * 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.java.introspection.impl;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.interfacedef.ConversationSequence;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.InvalidOperationException;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.DefaultJavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.osoa.sca.annotations.Conversational;
+import org.osoa.sca.annotations.EndsConversation;
+
+/**
+ * @version $Rev: 567542 $ $Date: 2007-08-19 21:13:29 -0800 (Sun, 19 Aug 2007) $
+ */
+public class ConversationalIntrospectionTestCase extends TestCase {
+    private JavaInterfaceFactory javaFactory;
+    
+    @Override
+    protected void setUp() throws Exception {
+        javaFactory = new DefaultJavaInterfaceFactory();
+    }
+
+    private Operation getOperation(Interface i, String name) {
+        for (Operation op : i.getOperations()) {
+            if (op.getName().equals(name)) {
+                return op;
+            }
+        }
+        return null;
+    }
+
+    public void testServiceContractConversationalInformationIntrospection() throws Exception {
+        Interface i = javaFactory.createJavaInterface(Foo.class);
+        assertNotNull(i);
+        assertTrue(i.isConversational());
+        ConversationSequence seq = getOperation(i, "operation").getConversationSequence();
+        assertEquals(ConversationSequence.CONVERSATION_CONTINUE, seq);
+        seq = getOperation(i, "endOperation").getConversationSequence();
+        assertEquals(ConversationSequence.CONVERSATION_END, seq);
+    }
+
+    public void testBadServiceContract() throws Exception {
+        try {
+            javaFactory.createJavaInterface(BadFoo.class);
+            fail();
+        } catch (InvalidOperationException e) {
+            // expected
+        }
+    }
+
+    public void testNonConversationalInformationIntrospection() throws Exception {
+        Interface i = javaFactory.createJavaInterface(NonConversationalFoo.class);
+        assertFalse(i.isConversational());
+        ConversationSequence seq = getOperation(i, "operation")
+            .getConversationSequence();
+        assertEquals(ConversationSequence.CONVERSATION_NONE, seq);
+    }
+
+    @Conversational
+    private interface Foo {
+        void operation();
+
+        @EndsConversation
+        void endOperation();
+    }
+
+    private interface BadFoo {
+        void operation();
+
+        @EndsConversation
+        void endOperation();
+    }
+
+    private interface NonConversationalFoo {
+        void operation();
+    }
+
+}

Added: tuscany/sandbox/mobile-android/interface-java/src/test/java/org/apache/tuscany/sca/interfacedef/java/introspection/impl/JavaInterfaceProcessorRegistryImplTestCase.java
URL: http://svn.apache.org/viewvc/tuscany/sandbox/mobile-android/interface-java/src/test/java/org/apache/tuscany/sca/interfacedef/java/introspection/impl/JavaInterfaceProcessorRegistryImplTestCase.java?rev=674723&view=auto
==============================================================================
--- tuscany/sandbox/mobile-android/interface-java/src/test/java/org/apache/tuscany/sca/interfacedef/java/introspection/impl/JavaInterfaceProcessorRegistryImplTestCase.java (added)
+++ tuscany/sandbox/mobile-android/interface-java/src/test/java/org/apache/tuscany/sca/interfacedef/java/introspection/impl/JavaInterfaceProcessorRegistryImplTestCase.java Mon Jul  7 22:19:28 2008
@@ -0,0 +1,107 @@
+/*
+ * 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.java.introspection.impl;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.DefaultJavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.java.introspect.JavaInterfaceVisitor;
+import org.apache.tuscany.sca.interfacedef.util.XMLType;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev: 629687 $ $Date: 2008-02-20 20:11:14 -0800 (Wed, 20 Feb 2008) $
+ */
+public class JavaInterfaceProcessorRegistryImplTestCase extends TestCase {
+    private JavaInterfaceFactory factory;
+
+    @SuppressWarnings("unchecked")
+    public void testSimpleInterface() throws InvalidInterfaceException {
+        JavaInterface intf = factory.createJavaInterface(Simple.class);
+
+        assertEquals(Simple.class, intf.getJavaClass());
+        List<Operation> operations = intf.getOperations();
+        assertEquals(1, operations.size());
+        Operation baseInt = operations.get(0);
+        assertEquals("baseInt", baseInt.getName());
+
+        QName element = new QName("http://impl.introspection.java.interfacedef.sca.tuscany.apache.org/", "return");
+
+        DataType<XMLType> returnType = baseInt.getOutputType();
+        assertEquals(Integer.TYPE, returnType.getPhysical());
+        assertEquals(element, returnType.getLogical().getElementName());
+
+        List<DataType> parameterTypes = baseInt.getInputType().getLogical();
+        assertEquals(1, parameterTypes.size());
+        DataType<XMLType> arg0 = parameterTypes.get(0);
+        assertEquals(Integer.TYPE, arg0.getPhysical());
+        
+        element = new QName("http://impl.introspection.java.interfacedef.sca.tuscany.apache.org/", "arg0");
+        assertEquals(element, arg0.getLogical().getElementName());
+
+        List<DataType> faultTypes = baseInt.getFaultTypes();
+        assertEquals(1, faultTypes.size());
+        DataType<DataType<XMLType>> fault0 = faultTypes.get(0);
+        assertEquals(IOException.class, fault0.getPhysical());
+        element = new QName("http://impl.introspection.java.interfacedef.sca.tuscany.apache.org/", "IOException");
+        assertEquals(element, fault0.getLogical().getLogical().getElementName());
+    }
+
+    public void testUnregister() throws Exception {
+        JavaInterfaceVisitor extension = createMock(JavaInterfaceVisitor.class);
+        extension.visitInterface(EasyMock.isA(JavaInterface.class));
+        expectLastCall().once();
+        replay(extension);
+        factory.addInterfaceVisitor(extension);
+        factory.createJavaInterface(Base.class);
+        factory.removeInterfaceVisitor(extension);
+        factory.createJavaInterface(Base.class);
+        verify(extension);
+    }
+    
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        factory = new DefaultJavaInterfaceFactory();
+
+    }
+
+    private static interface Base {
+        int baseInt(int param) throws IllegalArgumentException, IOException;
+    }
+
+    private static interface Simple extends Base {
+
+    }
+}

Added: tuscany/sandbox/mobile-android/interface-java/src/test/java/org/apache/tuscany/sca/interfacedef/java/introspection/impl/PolicyProcessorTestCase.java
URL: http://svn.apache.org/viewvc/tuscany/sandbox/mobile-android/interface-java/src/test/java/org/apache/tuscany/sca/interfacedef/java/introspection/impl/PolicyProcessorTestCase.java?rev=674723&view=auto
==============================================================================
--- tuscany/sandbox/mobile-android/interface-java/src/test/java/org/apache/tuscany/sca/interfacedef/java/introspection/impl/PolicyProcessorTestCase.java (added)
+++ tuscany/sandbox/mobile-android/interface-java/src/test/java/org/apache/tuscany/sca/interfacedef/java/introspection/impl/PolicyProcessorTestCase.java Mon Jul  7 22:19:28 2008
@@ -0,0 +1,108 @@
+/*
+ * 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.java.introspection.impl;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.interfacedef.java.DefaultJavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.java.impl.PolicyJavaInterfaceVisitor;
+import org.apache.tuscany.sca.policy.DefaultPolicyFactory;
+import org.osoa.sca.annotations.PolicySets;
+import org.osoa.sca.annotations.Requires;
+
+/**
+ * @version $Rev: 639350 $ $Date: 2008-03-20 08:43:46 -0800 (Thu, 20 Mar 2008) $
+ */
+public class PolicyProcessorTestCase extends TestCase {
+    private JavaInterfaceFactory factory = new DefaultJavaInterfaceFactory();
+    private PolicyJavaInterfaceVisitor policyProcessor;
+
+    public void testInterfaceLevel() throws Exception {
+        JavaInterface type = factory.createJavaInterface(Interface1.class);
+        policyProcessor.visitInterface(type);
+        assertEquals(1, type.getRequiredIntents().size());
+        assertEquals(1, type.getPolicySets().size());
+    }
+
+    public void testMethodLevel() throws Exception {
+        JavaInterface type = factory.createJavaInterface(Interface2.class);
+        policyProcessor.visitInterface(type);
+        assertEquals(0, type.getRequiredIntents().size());
+        assertEquals(1, type.getOperations().get(0).getRequiredIntents().size());
+        assertEquals(1, type.getOperations().get(1).getRequiredIntents().size());
+        assertEquals(0, type.getPolicySets().size());
+        assertEquals(1, type.getOperations().get(0).getPolicySets().size());
+        assertEquals(1, type.getOperations().get(1).getPolicySets().size());
+    }
+
+    public void testInterfaceAndMethodLevel() throws Exception {
+        JavaInterface type = factory.createJavaInterface(Interface3.class);
+        policyProcessor.visitInterface(type);
+        assertEquals(1, type.getRequiredIntents().size());
+        assertEquals(1, type.getOperations().get(0).getRequiredIntents().size());
+        assertEquals(1, type.getOperations().get(1).getRequiredIntents().size());
+        assertEquals(1, type.getPolicySets().size());
+        assertEquals(1, type.getOperations().get(0).getPolicySets().size());
+        assertEquals(1, type.getOperations().get(1).getPolicySets().size());
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        policyProcessor = new PolicyJavaInterfaceVisitor(new DefaultPolicyFactory());
+    }
+
+    // @Remotable
+    @Requires( {"transaction.global"})
+    @PolicySets( {"{http://ns1}PS1"})
+    private interface Interface1 {
+        int method1();
+
+        int method2();
+
+        int method3();
+
+        int method4();
+    }
+
+    private interface Interface2 {
+        @Requires( {"transaction.global"})
+        @PolicySets( {"{http://ns1}PS1"})
+        int method1();
+
+        @Requires( {"transaction.local"})
+        @PolicySets( {"{http://ns1}PS2"})
+        int method2();
+    }
+
+    @Requires( {"transaction.global.Interface6"})
+    @PolicySets( {"{http://ns1}PS1"})
+    private interface Interface3 {
+        @Requires( {"transaction.global.Interface6.method1"})
+        @PolicySets( {"{http://ns1}PS2"})
+        int method1();
+
+        @Requires( {"transaction.local.Interface6.method2"})
+        @PolicySets( {"{http://ns1}PS3"})
+        int method2();
+    }
+
+}

Modified: tuscany/sandbox/mobile-android/tuscany-implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/JavaIntrospectionHelper.java
URL: http://svn.apache.org/viewvc/tuscany/sandbox/mobile-android/tuscany-implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/JavaIntrospectionHelper.java?rev=674723&r1=674722&r2=674723&view=diff
==============================================================================
--- tuscany/sandbox/mobile-android/tuscany-implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/JavaIntrospectionHelper.java (original)
+++ tuscany/sandbox/mobile-android/tuscany-implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/JavaIntrospectionHelper.java Mon Jul  7 22:19:28 2008
@@ -306,7 +306,18 @@
         if (!name.startsWith("set")) {
             return name;
         }
-        return Introspector.decapitalize(name.substring(3));
+        
+        if (name == null || name.length() == 0) {
+    	    return name;
+    	}
+    	if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
+    			Character.isUpperCase(name.charAt(0))){
+    	    return name;
+    	}
+    	char chars[] = name.toCharArray();
+    	chars[0] = Character.toLowerCase(chars[0]);
+    	return new String(chars);
+    	
     }
 
     public static Class<?> getErasure(Type type) {