Package com.alibaba.citrus.hessian.io

Source Code of com.alibaba.citrus.hessian.io.ContextSerializerFactory

/*
* Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
*
* The Apache Software License, Version 1.1
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution, if
*    any, must include the following acknowlegement:
*       "This product includes software developed by the
*        Caucho Technology (http://www.caucho.com/)."
*    Alternately, this acknowlegement may appear in the software itself,
*    if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "Burlap", "Resin", and "Caucho" must not be used to
*    endorse or promote products derived from this software without prior
*    written permission. For written permission, please contact
*    info@caucho.com.
*
* 5. Products derived from this software may not be called "Resin"
*    nor may "Resin" appear in their names without prior written
*    permission of Caucho Technology.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @author Scott Ferguson
*/

package com.alibaba.citrus.hessian.io;

import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.alibaba.citrus.hessian.HessianException;

/** The classloader-specific Factory for returning serialization */
public class ContextSerializerFactory {
    private static final Logger log
            = Logger.getLogger(ContextSerializerFactory.class.getName());

    private static Deserializer OBJECT_DESERIALIZER
            = new BasicDeserializer(BasicDeserializer.OBJECT);

    private static final WeakHashMap<ClassLoader, SoftReference<ContextSerializerFactory>>
            _contextRefMap
            = new WeakHashMap<ClassLoader, SoftReference<ContextSerializerFactory>>();

    private static final ClassLoader _systemClassLoader;

    private static HashMap<String, Serializer>   _staticSerializerMap;
    private static HashMap<String, Deserializer> _staticDeserializerMap;
    private static HashMap                       _staticClassNameMap;

    private ContextSerializerFactory _parent;
    private ClassLoader              _loader;

    private final HashSet<String> _serializerFiles   = new HashSet<String>();
    private final HashSet<String> _deserializerFiles = new HashSet<String>();

    private final HashMap<String, Serializer> _serializerClassMap
            = new HashMap<String, Serializer>();

    private final ConcurrentHashMap<String, Serializer> _customSerializerMap
            = new ConcurrentHashMap<String, Serializer>();

    private final HashMap<Class, Serializer> _serializerInterfaceMap
            = new HashMap<Class, Serializer>();

    private final HashMap<String, Deserializer> _deserializerClassMap
            = new HashMap<String, Deserializer>();

    private final HashMap<String, Deserializer> _deserializerClassNameMap
            = new HashMap<String, Deserializer>();

    private final ConcurrentHashMap<String, Deserializer> _customDeserializerMap
            = new ConcurrentHashMap<String, Deserializer>();

    private final HashMap<Class, Deserializer> _deserializerInterfaceMap
            = new HashMap<Class, Deserializer>();

    public ContextSerializerFactory(ContextSerializerFactory parent,
                                    ClassLoader loader) {
        if (loader == null) {
            loader = _systemClassLoader;
        }

        _loader = loader;

        init();
    }

    public static ContextSerializerFactory create() {
        return create(Thread.currentThread().getContextClassLoader());
    }

    public static ContextSerializerFactory create(ClassLoader loader) {
        synchronized (_contextRefMap) {
            SoftReference<ContextSerializerFactory> factoryRef
                    = _contextRefMap.get(loader);

            ContextSerializerFactory factory = null;

            if (factoryRef != null) {
                factory = factoryRef.get();
            }

            if (factory == null) {
                ContextSerializerFactory parent = null;

                if (loader != null) {
                    parent = create(loader.getParent());
                }

                factory = new ContextSerializerFactory(parent, loader);
                factoryRef = new SoftReference<ContextSerializerFactory>(factory);

                _contextRefMap.put(loader, factoryRef);
            }

            return factory;
        }
    }

    public ClassLoader getClassLoader() {
        return _loader;
    }

    /** Returns the serializer for a given class. */
    public Serializer getSerializer(String className) {
        Serializer serializer = _serializerClassMap.get(className);

        if (serializer == AbstractSerializer.NULL) {
            return null;
        } else {
            return serializer;
        }
    }

    /**
     * Returns a custom serializer the class
     *
     * @param cl the class of the object that needs to be serialized.
     * @return a serializer object for the serialization.
     */
    public Serializer getCustomSerializer(Class cl) {
        Serializer serializer = _customSerializerMap.get(cl.getName());

        if (serializer == AbstractSerializer.NULL) {
            return null;
        } else if (serializer != null) {
            return serializer;
        }

        try {
            Class serClass = Class.forName(cl.getName() + "HessianSerializer",
                                           false, cl.getClassLoader());

            Serializer ser = (Serializer) serClass.newInstance();

            _customSerializerMap.put(cl.getName(), ser);

            return ser;
        } catch (ClassNotFoundException e) {
            log.log(Level.ALL, e.toString(), e);
        } catch (Exception e) {
            throw new HessianException(e);
        }

        _customSerializerMap.put(cl.getName(), AbstractSerializer.NULL);

        return null;
    }

    /** Returns the deserializer for a given class. */
    public Deserializer getDeserializer(String className) {
        Deserializer deserializer = _deserializerClassMap.get(className);

        if (deserializer == AbstractDeserializer.NULL) {
            return null;
        } else {
            return deserializer;
        }
    }

    /**
     * Returns a custom deserializer the class
     *
     * @param cl the class of the object that needs to be deserialized.
     * @return a deserializer object for the deserialization.
     */
    public Deserializer getCustomDeserializer(Class cl) {
        Deserializer deserializer = _customDeserializerMap.get(cl.getName());

        if (deserializer == AbstractDeserializer.NULL) {
            return null;
        } else if (deserializer != null) {
            return deserializer;
        }

        try {
            Class serClass = Class.forName(cl.getName() + "HessianDeserializer",
                                           false, cl.getClassLoader());

            Deserializer ser = (Deserializer) serClass.newInstance();

            _customDeserializerMap.put(cl.getName(), ser);

            return ser;
        } catch (ClassNotFoundException e) {
            log.log(Level.ALL, e.toString(), e);
        } catch (Exception e) {
            throw new HessianException(e);
        }

        _customDeserializerMap.put(cl.getName(), AbstractDeserializer.NULL);

        return null;
    }

    /** Initialize the factory */
    private void init() {
        if (_parent != null) {
            _serializerFiles.addAll(_parent._serializerFiles);
            _deserializerFiles.addAll(_parent._deserializerFiles);

            _serializerClassMap.putAll(_parent._serializerClassMap);
            _deserializerClassMap.putAll(_parent._deserializerClassMap);
        }

        if (_parent == null) {
            _serializerClassMap.putAll(_staticSerializerMap);
            _deserializerClassMap.putAll(_staticDeserializerMap);
            _deserializerClassNameMap.putAll(_staticClassNameMap);
        }

        HashMap<Class, Class> classMap;

        classMap = new HashMap<Class, Class>();
        initSerializerFiles("META-INF/citrus/hessian/serializers",
                            _serializerFiles,
                            classMap,
                            Serializer.class);

        for (Map.Entry<Class, Class> entry : classMap.entrySet()) {
            try {
                Serializer ser = (Serializer) entry.getValue().newInstance();

                if (entry.getKey().isInterface()) {
                    _serializerInterfaceMap.put(entry.getKey(), ser);
                } else {
                    _serializerClassMap.put(entry.getKey().getName(), ser);
                }
            } catch (Exception e) {
                throw new HessianException(e);
            }
        }

        classMap = new HashMap<Class, Class>();
        initSerializerFiles("META-INF/citrus/hessian/deserializers",
                            _deserializerFiles,
                            classMap,
                            Deserializer.class);

        for (Map.Entry<Class, Class> entry : classMap.entrySet()) {
            try {
                Deserializer ser = (Deserializer) entry.getValue().newInstance();

                if (entry.getKey().isInterface()) {
                    _deserializerInterfaceMap.put(entry.getKey(), ser);
                } else {
                    _deserializerClassMap.put(entry.getKey().getName(), ser);
                }
            } catch (Exception e) {
                throw new HessianException(e);
            }
        }
    }

    private void initSerializerFiles(String fileName,
                                     HashSet<String> fileList,
                                     HashMap<Class, Class> classMap,
                                     Class type) {
        try {
            ClassLoader classLoader = getClassLoader();

            // on systems with the security manager enabled, the system classloader
            // is null
            if (classLoader == null) {
                return;
            }

            Enumeration iter;

            iter = classLoader.getResources(fileName);
            while (iter.hasMoreElements()) {
                URL url = (URL) iter.nextElement();

                if (fileList.contains(url.toString())) {
                    continue;
                }

                fileList.add(url.toString());

                InputStream is = null;
                try {
                    is = url.openStream();

                    Properties props = new Properties();
                    props.load(is);

                    for (Map.Entry entry : props.entrySet()) {
                        String apiName = (String) entry.getKey();
                        String serializerName = (String) entry.getValue();

                        Class apiClass = null;
                        Class serializerClass = null;

                        try {
                            apiClass = Class.forName(apiName, false, classLoader);
                        } catch (ClassNotFoundException e) {
                            log.fine(url + ": " + apiName + " is not available in this context: " + getClassLoader());
                            continue;
                        }

                        try {
                            serializerClass = Class.forName(serializerName, false, classLoader);
                        } catch (ClassNotFoundException e) {
                            log.fine(url + ": " + serializerName + " is not available in this context: " + getClassLoader());
                            continue;
                        }

                        if (!type.isAssignableFrom(serializerClass)) {
                            throw new HessianException(url + ": " + serializerClass.getName() + " is invalid because it does not implement " + type.getName());
                        }

                        classMap.put(apiClass, serializerClass);
                    }
                } finally {
                    if (is != null) {
                        is.close();
                    }
                }
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new HessianException(e);
        }
    }

    private static void addBasic(Class cl, String typeName, int type) {
        _staticSerializerMap.put(cl.getName(), new BasicSerializer(type));

        Deserializer deserializer = new BasicDeserializer(type);
        _staticDeserializerMap.put(cl.getName(), deserializer);
        _staticClassNameMap.put(typeName, deserializer);
    }

    static {
        _staticSerializerMap = new HashMap();
        _staticDeserializerMap = new HashMap();
        _staticClassNameMap = new HashMap();

        addBasic(void.class, "void", BasicSerializer.NULL);

        addBasic(Boolean.class, "boolean", BasicSerializer.BOOLEAN);
        addBasic(Byte.class, "byte", BasicSerializer.BYTE);
        addBasic(Short.class, "short", BasicSerializer.SHORT);
        addBasic(Integer.class, "int", BasicSerializer.INTEGER);
        addBasic(Long.class, "long", BasicSerializer.LONG);
        addBasic(Float.class, "float", BasicSerializer.FLOAT);
        addBasic(Double.class, "double", BasicSerializer.DOUBLE);
        addBasic(Character.class, "char", BasicSerializer.CHARACTER_OBJECT);
        addBasic(String.class, "string", BasicSerializer.STRING);
        addBasic(Object.class, "object", BasicSerializer.OBJECT);
        addBasic(java.util.Date.class, "date", BasicSerializer.DATE);

        addBasic(boolean.class, "boolean", BasicSerializer.BOOLEAN);
        addBasic(byte.class, "byte", BasicSerializer.BYTE);
        addBasic(short.class, "short", BasicSerializer.SHORT);
        addBasic(int.class, "int", BasicSerializer.INTEGER);
        addBasic(long.class, "long", BasicSerializer.LONG);
        addBasic(float.class, "float", BasicSerializer.FLOAT);
        addBasic(double.class, "double", BasicSerializer.DOUBLE);
        addBasic(char.class, "char", BasicSerializer.CHARACTER);

        addBasic(boolean[].class, "[boolean", BasicSerializer.BOOLEAN_ARRAY);
        addBasic(byte[].class, "[byte", BasicSerializer.BYTE_ARRAY);
        addBasic(short[].class, "[short", BasicSerializer.SHORT_ARRAY);
        addBasic(int[].class, "[int", BasicSerializer.INTEGER_ARRAY);
        addBasic(long[].class, "[long", BasicSerializer.LONG_ARRAY);
        addBasic(float[].class, "[float", BasicSerializer.FLOAT_ARRAY);
        addBasic(double[].class, "[double", BasicSerializer.DOUBLE_ARRAY);
        addBasic(char[].class, "[char", BasicSerializer.CHARACTER_ARRAY);
        addBasic(String[].class, "[string", BasicSerializer.STRING_ARRAY);
        addBasic(Object[].class, "[object", BasicSerializer.OBJECT_ARRAY);

        Deserializer objectDeserializer = new JavaDeserializer(Object.class);
        _staticDeserializerMap.put("object", objectDeserializer);
        _staticClassNameMap.put("object", objectDeserializer);

        _staticSerializerMap.put(Class.class.getName(), new ClassSerializer());

        _staticDeserializerMap.put(Number.class.getName(), new BasicDeserializer(BasicSerializer.NUMBER));

        /*
        for (Class cl : new Class[] { BigDecimal.class, File.class, ObjectName.class }) {
          _staticSerializerMap.put(cl, StringValueSerializer.SER);
          _staticDeserializerMap.put(cl, new StringValueDeserializer(cl));
        }

        _staticSerializerMap.put(ObjectName.class, StringValueSerializer.SER);
        try {
          _staticDeserializerMap.put(ObjectName.class,
                               new StringValueDeserializer(ObjectName.class));
        } catch (Throwable e) {
        }
        */

        _staticSerializerMap.put(java.sql.Date.class.getName(),
                                 new SqlDateSerializer());
        _staticSerializerMap.put(java.sql.Time.class.getName(),
                                 new SqlDateSerializer());
        _staticSerializerMap.put(java.sql.Timestamp.class.getName(),
                                 new SqlDateSerializer());

        _staticDeserializerMap.put(java.sql.Date.class.getName(),
                                   new SqlDateDeserializer(java.sql.Date.class));
        _staticDeserializerMap.put(java.sql.Time.class.getName(),
                                   new SqlDateDeserializer(java.sql.Time.class));
        _staticDeserializerMap.put(java.sql.Timestamp.class.getName(),
                                   new SqlDateDeserializer(java.sql.Timestamp.class));

        // hessian/3bb5
        _staticDeserializerMap.put(StackTraceElement.class.getName(),
                                   new StackTraceElementDeserializer());

        ClassLoader systemClassLoader = null;
        try {
            systemClassLoader = ClassLoader.getSystemClassLoader();
        } catch (Exception e) {
        }

        _systemClassLoader = systemClassLoader;
    }
}

TOP

Related Classes of com.alibaba.citrus.hessian.io.ContextSerializerFactory

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.