Package org.mule.transformer.types

Source Code of org.mule.transformer.types.DataTypeFactory

/*
* $Id: DataTypeFactory.java 21939 2011-05-18 13:32:09Z aperepel $
* --------------------------------------------------------------------------------------
* Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
*
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/
package org.mule.transformer.types;

import org.mule.api.MuleMessage;
import org.mule.api.config.MuleProperties;
import org.mule.api.transformer.DataType;
import org.mule.util.generics.GenericsUtils;
import org.mule.util.generics.MethodParameter;

import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;

import javax.activation.DataHandler;
import javax.activation.DataSource;

/**
* Factory class used to create {@link DataType} objects based on the parameter types passed into
* the factory methods.
*
* @since 3.0
*/
public class DataTypeFactory
{
    public static final DataType<String> TEXT_STRING = new SimpleDataType<String>(String.class, MimeTypes.TEXT);
    public static final DataType<String> XML_STRING = new SimpleDataType<String>(String.class, MimeTypes.XML);
    public static final DataType<String> JSON_STRING = new SimpleDataType<String>(String.class, MimeTypes.JSON);
    public static final DataType<String> HTML_STRING = new SimpleDataType<String>(String.class, MimeTypes.HTML);
    public static final DataType<String> ATOM_STRING = new SimpleDataType<String>(String.class, MimeTypes.ATOM);
    public static final DataType<String> RSS_STRING = new SimpleDataType<String>(String.class, MimeTypes.RSS);

    //Common Java types
    public static final DataType<String> STRING = new SimpleDataType<String>(String.class);
    public static final DataType<String> OBJECT = new SimpleDataType<String>(Object.class);
    public static final DataType<String> BYTE_ARRAY = new SimpleDataType<String>(byte[].class);
    public static final DataType<String> INPUT_STREAM = new SimpleDataType<String>(InputStream.class);
    public static final DataType<String> MULE_MESSAGE = new SimpleDataType<String>(MuleMessage.class);

    public static <T> DataType<T> create(Class<T> type)
    {
        return create(type, MimeTypes.ANY);
    }

    public static <T> DataType<T> createImmutable(Class<T> type)
    {
        return new ImmutableDataType<T>(create(type, MimeTypes.ANY));
    }

    public static <T> DataType<T> createWithEncoding(Class<T> type, String encoding)
    {
        DataType<T> dataType = create(type);
        dataType.setEncoding(encoding);
        return dataType;
    }

    public static <T> DataType<T> create(Class<T> type, String mimeType)
    {
        if (Collection.class.isAssignableFrom(type))
        {
            Class<? extends Collection<?>> collectionType = (Class<? extends Collection<?>>)type;
            Class<?> itemType = GenericsUtils.getCollectionType(collectionType);
            if (itemType == null)
            {
                return new CollectionDataType(collectionType, mimeType);
            }
            else
            {
                return new CollectionDataType(collectionType, itemType, mimeType);
            }
        }

        // Special case where proxies are used for testing
        if (isProxyClass(type))
        {
            return new SimpleDataType<T>(type.getInterfaces()[0], mimeType);
        }

        return new SimpleDataType<T>(type, mimeType);
    }

    public static <T> DataType create(Class<? extends Collection> collClass, Class<T> itemType)
    {
        return create(collClass, itemType, null);
    }

    public static <T> DataType create(Class<? extends Collection> collClass, Class<T> itemType, String mimeType)
    {
        return new CollectionDataType(collClass, itemType, mimeType);
    }

    /**
     * Will create a {@link org.mule.api.transformer.DataType} object from an object instance. This method will check
     * if the object o is a {@link org.mule.api.MuleMessage} instance and will take the type from the message payload
     * and check if a mime type is set on the message and used that when constructing the {@link org.mule.api.transformer.DataType}
     * object.
     *
     * @param o an object instance.  This can be a {@link org.mule.api.MuleMessage}, a collection, a proxy instance or any other
     *          object
     * @return a data type that represents the object type.
     */
    public static DataType<?> createFromObject(Object o)
    {
        Class<?> type = o.getClass();
        String mime = null;
        if (o instanceof DataType)
        {
            return (DataType<?>)o;
        }
        else if (o instanceof MuleMessage)
        {
            MuleMessage mm = (MuleMessage) o;
            type = mm.getPayload().getClass();
            //TODO better mime handling, see MULE-4639
            //case insensitive
            mime = mm.getInboundProperty(MuleProperties.CONTENT_TYPE_PROPERTY);
            if (mime == null)
            {
                //case insensitive
                mime = mm.getInboundProperty("ContentType");
            }
        }
        else if (o instanceof DataHandler)
        {
            mime = ((DataHandler) o).getContentType();
        }
        else if (o instanceof DataSource)
        {
            mime = ((DataSource) o).getContentType();
        }

        if (mime != null)
        {
            int i = mime.indexOf(";");
            mime = (i > -1 ? mime.substring(0, i) : mime);
            //TODO set the charset on the DataType when the field is introduced BL-140
        }
        else
        {
            mime = MimeTypes.ANY;
        }

        return create(type, mime);
    }

    public static DataType<?> createFromReturnType(Method m)
    {
        return createFromReturnType(m, null);
    }

    public static DataType<?> createFromReturnType(Method m, String mimeType)
    {
        if (Collection.class.isAssignableFrom(m.getReturnType()))
        {
            Class<? extends Collection> cType = (Class<? extends Collection>) m.getReturnType();
            Class itemType = GenericsUtils.getCollectionReturnType(m);

            if (itemType != null)
            {
                return new CollectionDataType(cType, itemType, mimeType);
            }
            else
            {
                return new CollectionDataType(cType, mimeType);
            }
        }
        else
        {
            return new SimpleDataType(m.getReturnType(), mimeType);
        }
    }

    public static DataType createFromParameterType(Method m, int paramIndex)
    {
        return createFromParameterType(m, paramIndex, null);
    }

    public static DataType createFromParameterType(Method m, int paramIndex, String mimeType)
    {
        if (Collection.class.isAssignableFrom(m.getParameterTypes()[paramIndex]))
        {
            Class<? extends Collection> cType = (Class<? extends Collection>) m.getParameterTypes()[paramIndex];
            Class itemType = GenericsUtils.getCollectionParameterType(new MethodParameter(m, paramIndex));

            if (itemType != null)
            {
                return new CollectionDataType(cType, itemType, mimeType);
            }
            else
            {
                return new CollectionDataType(cType, mimeType);
            }
        }
        else
        {
            return new SimpleDataType(m.getParameterTypes()[paramIndex], mimeType);
        }
    }

    public static DataType<?> createFromField(Field f)
    {
        return createFromField(f, null);
    }

    public static DataType<?> createFromField(Field f, String mimeType)
    {
        if (Collection.class.isAssignableFrom(f.getType()))
        {
            Class<? extends Collection> cType = (Class<? extends Collection>) f.getType();
            Class itemType = GenericsUtils.getCollectionFieldType(f);

            if (itemType != null)
            {
                return new CollectionDataType(cType, itemType, mimeType);
            }
            else
            {
                return new CollectionDataType(cType, mimeType);
            }
        }
        else
        {
            return new SimpleDataType(f.getType(), mimeType);
        }
    }


    private static ConcurrentHashMap proxyClassCache = new ConcurrentHashMap();
    /**
     * Cache which classes are proxies.  Very experimental
     */
    protected static<T> boolean isProxyClass(Class<T> type)
    {
        /**
         * map value
         */
        class ProxyIndicator
        {
            private final WeakReference<Class> targetClassRef;
            private final boolean isProxy;

            ProxyIndicator(Class targetClass, boolean proxy)
            {
                this.targetClassRef = new WeakReference<Class>(targetClass);
                isProxy = proxy;
            }

            public Class getTargetClass()
            {
                return targetClassRef.get();
            }

            public boolean isProxy()
            {
                return isProxy;
            }
        }

        String typeName = type.getName();
        ProxyIndicator indicator = (ProxyIndicator) proxyClassCache.get(typeName);
        if (indicator != null)
        {
            Class classInMap = indicator.getTargetClass();
            if (classInMap == type)
            {
                return indicator.isProxy();
            }
            else if (classInMap != null)
            {
                // We have duplicate class names from different active classloaders.  Skip the optimization for this one
                return Proxy.isProxyClass(type);
            }
        }
        // Either there's no indicator in the map or there's one that is due to be replaced
        boolean isProxy = Proxy.isProxyClass(type);
        proxyClassCache.put(typeName, new ProxyIndicator(type, isProxy));
        return isProxy;
    }
}
TOP

Related Classes of org.mule.transformer.types.DataTypeFactory

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.