Package org.apache.tuscany.core.databinding.impl

Source Code of org.apache.tuscany.core.databinding.impl.MediatorImpl

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

import java.util.List;
import java.util.Map;

import org.apache.tuscany.spi.annotation.Autowire;
import org.apache.tuscany.spi.databinding.DataBindingRegistry;
import org.apache.tuscany.spi.databinding.DataPipe;
import org.apache.tuscany.spi.databinding.Mediator;
import org.apache.tuscany.spi.databinding.PullTransformer;
import org.apache.tuscany.spi.databinding.PushTransformer;
import org.apache.tuscany.spi.databinding.TransformationContext;
import org.apache.tuscany.spi.databinding.TransformationException;
import org.apache.tuscany.spi.databinding.Transformer;
import org.apache.tuscany.spi.databinding.TransformerRegistry;
import org.apache.tuscany.spi.model.DataType;
import org.osoa.sca.annotations.Scope;

/**
* Default Mediator implementation
*/
@Scope("MODULE")
public class MediatorImpl implements Mediator {

    private DataBindingRegistry dataBindingRegistry;

    private TransformerRegistry transformerRegistry;

    @Autowire
    public void setTransformerRegistry(TransformerRegistry transformerRegistry) {
        this.transformerRegistry = transformerRegistry;
    }

    /**
     * @param dataBindingRegistry the dataBindingRegistry to set
     */
    @Autowire
    public void setDataBindingRegistry(DataBindingRegistry dataBindingRegistry) {
        this.dataBindingRegistry = dataBindingRegistry;
    }

    /**
     * @see org.apache.tuscany.spi.databinding.Mediator#mediate(java.lang.Object,
     *      org.apache.tuscany.spi.model.DataType,
     *      org.apache.tuscany.spi.model.DataType, Map)
     */
    @SuppressWarnings("unchecked")
    public Object mediate(Object source,
                          DataType sourceDataType,
                          DataType targetDataType,
                          Map<Class<?>, Object> metadata) {
        if (source == null) {
            // Shortcut for null value
            return null;
        }
        if (sourceDataType == null) {
            sourceDataType = dataBindingRegistry.introspectType(source);
        }
        if (sourceDataType == null) {
            return source;
        } else if (sourceDataType.equals(targetDataType)) {
            return source;
        }

        List<Transformer> path = getTransformerChain(sourceDataType, targetDataType);

        Object result = source;
        int size = path.size();
        int i = 0;
        while (i < size) {
            Transformer transformer = path.get(i);
            TransformationContext context =
                createTransformationContext(sourceDataType, targetDataType, size, i, transformer, metadata);
            // the source and target type
            if (transformer instanceof PullTransformer) {
                // For intermediate node, set data type to null
                result = ((PullTransformer)transformer).transform(result, context);
            } else if (transformer instanceof PushTransformer) {
                DataPipe dataPipe = (i < size - 1) ? (DataPipe)path.get(++i) : null;
                ((PushTransformer)transformer).transform(result, dataPipe.getSink(), context);
                result = dataPipe.getResult();
            }
            i++;
        }

        return result;
    }

    private TransformationContext createTransformationContext(DataType sourceDataType,
                                                              DataType targetDataType,
                                                              int size,
                                                              int index,
                                                              Transformer transformer,
                                                              Map<Class<?>, Object> metadata) {
        DataType sourceType =
            (index == 0) ? sourceDataType : new DataType<Object>(transformer.getSourceDataBinding(),
                                                                 Object.class, null);
        DataType targetType =
            (index == size - 1) ? targetDataType : new DataType<Object>(transformer.getTargetDataBinding(),
                                                                        Object.class, null);
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        TransformationContext context =
            new TransformationContextImpl(sourceType, targetType, classLoader, metadata);
        return context;
    }

    @SuppressWarnings("unchecked")
    public void mediate(Object source,
                        Object target,
                        DataType sourceDataType,
                        DataType targetDataType,
                        Map<Class<?>, Object> metadata) {
        if (source == null) {
            // Shortcut for null value
            return;
        }
        if (sourceDataType == null) {
            sourceDataType = dataBindingRegistry.introspectType(source);
        }
        if (sourceDataType == null) {
            return;
        } else if (sourceDataType.equals(targetDataType)) {
            return;
        }

        List<Transformer> path = getTransformerChain(sourceDataType, targetDataType);
        Object result = source;
        int size = path.size();
        for (int i = 0; i < size; i++) {
            Transformer transformer = path.get(i);
            TransformationContext context =
                createTransformationContext(sourceDataType, targetDataType, size, i, transformer, metadata);

            if (transformer instanceof PullTransformer) {
                result = ((PullTransformer)transformer).transform(result, context);
            } else if (transformer instanceof PushTransformer) {
                DataPipe dataPipe = (i < size - 1) ? (DataPipe)path.get(++i) : null;
                Object sink = dataPipe != null ? dataPipe.getSink() : target;
                ((PushTransformer)transformer).transform(result, sink, context);
                result = (dataPipe != null) ? dataPipe.getResult() : null;
            }
        }
    }

    private List<Transformer> getTransformerChain(DataType sourceDataType, DataType targetDataType) {
        String sourceId = sourceDataType.getDataBinding();
        String targetId = targetDataType.getDataBinding();
        List<Transformer> path = transformerRegistry.getTransformerChain(sourceId, targetId);
        if (path == null) {
            TransformationException ex = new TransformationException("No path found for the transformation");
            ex.addContextName("Source: " + sourceId);
            ex.addContextName("Target: " + targetId);
            throw ex;
        }
        return path;
    }
}
TOP

Related Classes of org.apache.tuscany.core.databinding.impl.MediatorImpl

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.