Package org.pentaho.reporting.libraries.serializer

Source Code of org.pentaho.reporting.libraries.serializer.SerializerHelper

/**
* ===================================================
* JCommon-Serializer : a free serialization framework
* ===================================================
*
* Project Info:  http://reporting.pentaho.org/jcommon-serializer/
*
* (C) Copyright 2006-2008, by Object Refinery Limited, Pentaho Corporation and Contributors.
*
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ------------
* SerializerHelper
* ------------
*/

package org.pentaho.reporting.libraries.serializer;

import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;

import org.pentaho.reporting.libraries.base.config.Configuration;
import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
* The SerializeHelper is used to make implementing custom serialization
* handlers easier. Handlers for certain object types need to be added to this
* helper before this implementation is usable.
*
* @author Thomas Morgner
*/
public class SerializerHelper
{
  private static Log logger = LogFactory.getLog(SerializerHelper.class);
  /**
   * The singleton instance of the serialize helper.
   */
  private static SerializerHelper singleton;

  /**
   * Returns or creates a new SerializerHelper. When a new instance is created
   * by this method, all known SerializeMethods are registered.
   *
   * @return the SerializerHelper singleton instance.
   */
  public static synchronized SerializerHelper getInstance()
  {
    if (singleton == null)
    {
      singleton = new SerializerHelper();
      singleton.registerMethods();
    }
    return singleton;
  }


  /**
   * This method can be used to replace the singleton instance of this helper.
   *
   * @param helper the new instance of the serialize helper.
   */
  protected static void setInstance(final SerializerHelper helper)
  {
    singleton = helper;
  }

  /**
   * A collection of the serializer methods.
   */
  private final HashMap methods;

  /**
   * A class comparator for searching the super class of an certain class.
   */
  private final ClassComparator comparator;

  /**
   * Creates a new SerializerHelper.
   */
  protected SerializerHelper()
  {
    this.comparator = new ClassComparator();
    this.methods = new HashMap();
  }

  /**
   * Registers a new SerializeMethod with this SerializerHelper.
   *
   * @param method the method that should be registered.
   */
  public synchronized void registerMethod(final SerializeMethod method)
  {
    this.methods.put(method.getObjectClass(), method);
  }

  /**
   * Traverses the configuration and registers all serialization handlers in this factory.
   */
  protected void registerMethods()
  {
    final Configuration config = LibSerializerBoot.getInstance().getGlobalConfig();
    final Iterator sit = config.findPropertyKeys("org.pentaho.reporting.libraries.serializer.handler.");

    while (sit.hasNext())
    {
      final String configkey = (String) sit.next();
      final String c = config.getConfigProperty(configkey);
      final Object maybeModule = ObjectUtilities.loadAndInstantiate
          (c, SerializerHelper.class, SerializeMethod.class);
      if (maybeModule != null)
      {
        final SerializeMethod module = (SerializeMethod) maybeModule;
        registerMethod(module);
      }
      else
      {
        logger.warn("Invalid SerializeMethod implementation: " + c);
      }
    }
  }

  /**
   * Deregisters a new SerializeMethod with this SerializerHelper.
   *
   * @param method the method that should be deregistered.
   */
  public synchronized void unregisterMethod(final SerializeMethod method)
  {
    this.methods.remove(method.getObjectClass());
  }

  /**
   * Returns the collection of all registered serialize methods.
   *
   * @return a collection of the registered serialize methods.
   */
  protected HashMap getMethods()
  {
    return methods;
  }

  /**
   * Returns the class comparator instance used to find correct super classes.
   *
   * @return the class comparator.
   */
  protected ClassComparator getComparator()
  {
    return comparator;
  }

  /**
   * Looks up the SerializeMethod for the given class or null if there is no
   * SerializeMethod for the given class.
   *
   * @param c the class for which we want to lookup a serialize method.
   * @return the method or null, if there is no registered method for the
   *         class.
   */
  protected SerializeMethod getSerializer(final Class c)
  {
    final SerializeMethod sm = (SerializeMethod) methods.get(c);
    if (sm != null)
    {
      return sm;
    }
    return getSuperClassObjectDescription(c);
  }

  /**
   * Looks up the SerializeMethod for the given class or null if there is no
   * SerializeMethod for the given class. This method searches all
   * superclasses.
   *
   * @param d               the class for which we want to lookup a serialize
   *                        method.
   * @return the method or null, if there is no registered method for the
   *         class.
   */
  protected SerializeMethod getSuperClassObjectDescription
      (final Class d)
  {
    SerializeMethod knownSuperClass = null;
    final Iterator keys = methods.keySet().iterator();
    while (keys.hasNext())
    {
      final Class keyClass = (Class) keys.next();
      if (keyClass.isAssignableFrom(d))
      {
        final SerializeMethod od = (SerializeMethod) methods.get(keyClass);
        if (knownSuperClass == null)
        {
          knownSuperClass = od;
        }
        else
        {
          if (comparator.isComparable
              (knownSuperClass.getObjectClass(), od.getObjectClass()))
          {
            if (comparator.compare
                (knownSuperClass.getObjectClass(), od.getObjectClass()) < 0)
            {
              knownSuperClass = od;
            }
          }
        }
      }
    }
    return knownSuperClass;
  }


  /**
   * Writes a serializable object description to the given object output stream.
   * This method selects the best serialize helper method for the given object.
   *
   * @param o   the to be serialized object.
   * @param out the outputstream that should receive the object.
   * @throws IOException if an I/O error occured.
   */
  public synchronized void writeObject(final Object o,
                                       final ObjectOutputStream out)
      throws IOException
  {
    if (o == null)
    {
      out.writeByte(0);
      return;
    }
    if (o instanceof Serializable)
    {
      out.writeByte(1);
      out.writeObject(o);
      return;
    }

    final SerializeMethod m = getSerializer(o.getClass());
    if (m == null)
    {
      throw new NotSerializableException(o.getClass().getName());
    }
    out.writeByte(2);
    out.writeObject(m.getObjectClass());
    m.writeObject(o, out);
  }

  /**
   * Reads the object from the object input stream. This object selects the best
   * serializer to read the object.
   * <p/>
   * Make sure, that you use the same configuration (library and class versions,
   * registered methods in the SerializerHelper) for reading as you used for
   * writing.
   *
   * @param in the object input stream from where to read the serialized data.
   * @return the generated object.
   * @throws IOException            if reading the stream failed.
   * @throws ClassNotFoundException if serialized object class cannot be found.
   */
  public synchronized Object readObject(final ObjectInputStream in)
      throws IOException, ClassNotFoundException
  {
    final int type = in.readByte();
    if (type == 0)
    {
      return null;
    }
    if (type == 1)
    {
      return in.readObject();
    }
    final Class c = (Class) in.readObject();
    final SerializeMethod m = getSerializer(c);
    if (m == null)
    {
      throw new NotSerializableException(c.getName());
    }
    return m.readObject(in);
  }
}
TOP

Related Classes of org.pentaho.reporting.libraries.serializer.SerializerHelper

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.