Package org.apache.tuscany.sca.core.databinding.processor

Source Code of org.apache.tuscany.sca.core.databinding.processor.DataBindingJavaInterfaceProcessor

/*
* 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.core.databinding.processor;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.tuscany.sca.databinding.javabeans.JavaBeansDataBinding;
import org.apache.tuscany.sca.databinding.javabeans.SimpleJavaDataBinding;
import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
import org.apache.tuscany.sca.databinding.annotation.DataBinding;
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.JavaInterface;
import org.apache.tuscany.sca.interfacedef.java.introspect.JavaInterfaceVisitor;
import org.osoa.sca.annotations.Reference;

/**
* The databinding annotation processor for java interfaces
*
* @version $Rev: 576267 $ $Date: 2007-09-17 07:19:48 +0100 (Mon, 17 Sep 2007) $
*/
public class DataBindingJavaInterfaceProcessor implements JavaInterfaceVisitor {
    private DataBindingExtensionPoint dataBindingRegistry;

    public DataBindingJavaInterfaceProcessor(@Reference
    DataBindingExtensionPoint dataBindingRegistry) {
        super();
        this.dataBindingRegistry = dataBindingRegistry;
    }

    public void visitInterface(JavaInterface javaInterface) throws InvalidInterfaceException {
        if (!javaInterface.isRemotable()) {
            return;
        }
        List<Operation> operations = javaInterface.getOperations();
        processInterface(javaInterface, operations);
    }

    private void processInterface(JavaInterface javaInterface, List<Operation> operations) {
        Class<?> clazz = javaInterface.getJavaClass();
        DataBinding dataBinding = clazz.getAnnotation(DataBinding.class);
        String dataBindingId = null;
        boolean wrapperStyle = false;
        if (dataBinding != null) {
            dataBindingId = dataBinding.value();
            wrapperStyle = dataBinding.wrapperStyle();
        }

        Map<String, Operation> opMap = new HashMap<String, Operation>();
        for (Operation op : javaInterface.getOperations()) {
            opMap.put(op.getName(), op);
            if (dataBindingId != null) {
                op.setDataBinding(dataBindingId);
                op.setWrapperStyle(wrapperStyle);
            }
        }
        for (Method method : clazz.getMethods()) {
            Operation operation = opMap.get(method.getName());
            DataBinding methodDataBinding = clazz.getAnnotation(DataBinding.class);
            if (methodDataBinding == null) {
                methodDataBinding = dataBinding;
            }
            dataBindingId = null;
            wrapperStyle = false;
            if (dataBinding != null) {
                dataBindingId = dataBinding.value();
                wrapperStyle = dataBinding.wrapperStyle();
                operation.setDataBinding(dataBindingId);
                operation.setWrapperStyle(wrapperStyle);
            }

            // FIXME: We need a better way to identify simple java types
            int i = 0;
            for (org.apache.tuscany.sca.interfacedef.DataType<?> d : operation.getInputType().getLogical()) {
                if (d.getDataBinding() == null) {
                    d.setDataBinding(dataBindingId);
                }
                for (Annotation a : method.getParameterAnnotations()[i]) {
                    if (a.annotationType() == org.apache.tuscany.sca.databinding.annotation.DataType.class) {
                        String value = ((org.apache.tuscany.sca.databinding.annotation.DataType)a).value();
                        d.setDataBinding(value);
                    }
                }
                dataBindingRegistry.introspectType(d, method.getParameterAnnotations()[i]);
                i++;
            }
            if (operation.getOutputType() != null) {
                DataType<?> d = operation.getOutputType();
                if (d.getDataBinding() == null) {
                    d.setDataBinding(dataBindingId);
                }
                org.apache.tuscany.sca.databinding.annotation.DataType dt =
                    method.getAnnotation(org.apache.tuscany.sca.databinding.annotation.DataType.class);
                if (dt != null) {
                    d.setDataBinding(dt.value());
                }
                dataBindingRegistry.introspectType(d, method.getAnnotations());
            }
            for (org.apache.tuscany.sca.interfacedef.DataType<?> d : operation.getFaultTypes()) {
                if (d.getDataBinding() == null) {
                    d.setDataBinding(dataBindingId);
                }
                // TODO: Handle exceptions
                dataBindingRegistry.introspectType(d, method.getAnnotations(), true);
            }

            // JIRA: TUSCANY-842
            if (operation.getDataBinding() == null) {
                assignOperationDataBinding(operation);
            }

            // FIXME: Do we want to heuristically check the wrapper style?
            // introspectWrapperStyle(operation);
        }
    }

    /*
     *  Assigns an operation DB if one of the input types, output type, fault types has a non-default DB.
     *  However, if two of the input types, output type, fault types have two different non-default DBs
     *  ( e.g. SDO and JAXB), then we do nothing to the operation DB.
     * 
     *  The method logic assumes the JavaBeans DataBinding is the default
     */
    private void assignOperationDataBinding(Operation operation) {

        String nonDefaultDataBindingName = null;

        // Can't use DataType<?> since operation.getInputType() returns: DataType<List<DataType>>
        List<DataType> opDataTypes = new LinkedList<DataType>();

        opDataTypes.addAll(operation.getInputType().getLogical());
        opDataTypes.add(operation.getOutputType());
        opDataTypes.addAll(operation.getFaultTypes());

        for (DataType<?> d : opDataTypes) {
            if (d != null) {
                String dataBinding = d.getDataBinding();
                // Assumes JavaBeans DB is default
                if (dataBinding != null && !dataBinding.equals(JavaBeansDataBinding.NAME)
                    && !dataBinding.equals(SimpleJavaDataBinding.NAME)) {
                    if (nonDefaultDataBindingName != null) {
                        if (!nonDefaultDataBindingName.equals(dataBinding)) {
                            // We've seen two different non-default DBs, e.g. SDO and JAXB
                            // so unset the string and break out of the loop
                            nonDefaultDataBindingName = null;
                            break;
                        } else {
                            continue;
                        }
                    } else {
                        nonDefaultDataBindingName = dataBinding;
                    }
                }
            }
        }

        // We have a DB worthy of promoting to operation level.
        if (nonDefaultDataBindingName != null) {
            operation.setDataBinding(nonDefaultDataBindingName);
        }
    }
}
TOP

Related Classes of org.apache.tuscany.sca.core.databinding.processor.DataBindingJavaInterfaceProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.