Package org.objectweb.speedo.mapper.lib

Source Code of org.objectweb.speedo.mapper.lib.Object2StringSerializer

/**
* Copyright (C) 2001-2004 France Telecom R&D
*
* 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 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
*/
package org.objectweb.speedo.mapper.lib;

import org.objectweb.util.monolog.api.Logger;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.speedo.api.Debug;
import org.objectweb.speedo.tools.StringReplace;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Constants;
import org.objectweb.asm.CodeVisitor;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;

/**
* This class contains primitive to serialize and deserialize an Object into a
* java Stirng.
*
* @author S.Chassande-Barrioz
*/
public abstract class Object2StringSerializer {

  public final static String DESC_FILE_NAME_PROP = "descFileName";

  /**
   * Serializes an object into a String
   *
   * @param o is the java object to serialize
   * @return the java object serialized into a String
   * @throws java.io.IOException occurs if the java serialization fails
   */
  public static String serialize(Object o) throws IOException {
    java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(o);
    oos.close();
    byte[] bs = baos.toByteArray();
    baos.close();
    StringBuffer sb = new StringBuffer(bs.length);
    for (int i = 0; i < bs.length; i++) {
      sb.append((char) (bs[i] & 0XFF));
    }
    return sb.toString();
  }

  /**
   * Deserializes a String into a java object.
   *
   * @param s is the string containing a serialized java object
   * @return the deserialized java object
   * @throws IOException occurs if the deserialization fails
   * @throws ClassNotFoundException occurs a class of a deserialized java
   *             object is not present.
   */
  public static Object deserialize(String s) throws IOException, ClassNotFoundException {
    byte[] bs = new byte[s.length()];
    for (int i = 0; i < bs.length; i++) {
      bs[i] = (byte) s.charAt(i);
    }
    ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bs));
    Object o = ois.readObject();
    ois.close();
    return o;
  }


  public static String serialize(String output, String descFileName, Object jmi, Logger logger) throws IOException {
    String className = descFileName2ClassName(descFileName);

    if (Debug.ON && logger.isLoggable(BasicLevel.DEBUG)) {
      logger.log(
        BasicLevel.DEBUG,
        "Serialize the Jorm Meta Information into the class '"
          + className
          + "' into the directory '"
          + output
          + "'.");
    }
 
    //Serialize the object into a String
    String value = Object2StringSerializer.serialize(jmi);
   
    // Generate class 
    ClassWriter cw = generateJavaClass(className, value);
    // Write class file on disk
   
    writeJavaClass(className, cw, output);
   
    return output + File.separatorChar + className;
  }

  private static ClassWriter generateJavaClass(final String className, final String value) {
   
    ClassWriter cw = new ClassWriter(true);

    String str = StringReplace.replaceChar(File.separatorChar, '/', className);
   
    cw.visit(Constants.V1_1, Constants.ACC_PUBLIC, //access
    str, //name
    "org/objectweb/speedo/mapper/lib/Object2StringSerializer", //superName
    new String[0], //interfaces
    str // sourcefile
    );
    //implement an empty public constructor
    CodeVisitor c = cw.visitMethod(Constants.ACC_PUBLIC, "<init>", "()V", null, null);
    c.visitVarInsn(Constants.ALOAD, 0);
    c.visitMethodInsn(
      Constants.INVOKESPECIAL,
      "org/objectweb/speedo/mapper/lib/Object2StringSerializer",
      "<init>",
      "()V");
    c.visitInsn(Constants.RETURN);
    c.visitMaxs(0, 0);

    //implement the getSerializedObject method
    c = cw.visitMethod(Constants.ACC_PUBLIC, "getSerializedObject", "()Ljava/lang/String;", null, null);
    c.visitTypeInsn(Constants.NEW, "java/lang/StringBuffer");
    c.visitInsn(Constants.DUP);
    c.visitMethodInsn(Constants.INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "()V");
    final int SPLIT_SIZE = 5000;
    int nbSplit = value.length() / SPLIT_SIZE;
    for (int i = 0; i < nbSplit; i++) {
      int j = i * SPLIT_SIZE;
      String s = value.substring(j, j + SPLIT_SIZE);
      c.visitLdcInsn(s);
      c.visitMethodInsn(
        Constants.INVOKEVIRTUAL,
        "java/lang/StringBuffer",
        "append",
        "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
    }
    int last = value.length() % SPLIT_SIZE;
    if (last > 0) {
      c.visitLdcInsn(value.substring(SPLIT_SIZE * nbSplit));
      c.visitMethodInsn(
        Constants.INVOKEVIRTUAL,
        "java/lang/StringBuffer",
        "append",
        "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
    }
    c.visitMethodInsn(Constants.INVOKEVIRTUAL, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;");
    c.visitInsn(Constants.ARETURN);
    c.visitMaxs(1, 1);
   
    return cw;
  }
 
   
  public static Object deserialize(String descFileName, ClassLoader cl, Logger logger)
      throws Exception {
    String className = descFileName2ClassName(descFileName);
    if (className == null) {
        throw new Exception("Impossible to load a null class");
    }
        Object2StringSerializer s = null;
        className = StringReplace.replaceChar('/', '.', className);
        if (logger != null) {
          logger.log(BasicLevel.DEBUG, "Loading serialized object into the class '" + className + "'.");
        }
    try {
            Class c = cl.loadClass(className);
      s = (Object2StringSerializer) c.newInstance();
    } catch (Throwable e) {
      if (logger != null) {
        logger.log(BasicLevel.ERROR, e.getMessage(), e);
      }
      ClassNotFoundException cnfe = new ClassNotFoundException("Impossible to load the jorm meta information: The class "
          + className + " is not availlable through the classloader (" + cl + ") of the persistent class", e);
      throw cnfe;
    }
    return deserialize(s.getSerializedObject());
  }

  private static void writeJavaClass(final String name,
                     final ClassWriter jclass,
                     final String srcFiles) throws IOException {
    int p = name.lastIndexOf(File.separatorChar);

    String pkg;
    String clas;
    if (p == -1) {
      pkg = "";
      clas = name;
    }
    else {
      pkg = name.substring(0, p);
      clas = name.substring(p + 1);
    }
    File outputDir;
    if (srcFiles == null) {
      outputDir = new File(pkg);
    }
    else {
      outputDir = new File(srcFiles + File.separatorChar + pkg);
    }

    outputDir.mkdirs();
    File outputFile = new File(outputDir, clas + ".class");
    outputFile.createNewFile();
    FileOutputStream fos = new FileOutputStream(outputFile);
    fos.write(jclass.toByteArray());
    fos.close();
  }

  public static Object getObject(String descFileName, ClassLoader cl, Logger logger) throws Exception {
    String className = descFileName2ClassName(descFileName);

    logger.log(BasicLevel.DEBUG, "Loading serialized object into the class '" + className + "'.");
    Object2StringSerializer s = null;
    try
      s = (Object2StringSerializer) cl.loadClass(className).newInstance();
    }
    catch (Throwable e) {
      ClassNotFoundException cnfe =
        new ClassNotFoundException(
          "Impossible to load the jorm meta information: The class "
            + className
            + " is not availlable through the classloader of the persistent class",
          e);
      logger.log(BasicLevel.ERROR, cnfe.getMessage(), cnfe);
      throw cnfe;
    }
    return deserialize(s.getSerializedObject());
  }

  public static String descFileName2ClassName(String descFileName) {
    return descFileName.substring(0, descFileName.length() - 4) + "SpeedoJMI";
  }

 
  /**
   * @return the String containing a serialized java object
   */
  public abstract String getSerializedObject();

}
TOP

Related Classes of org.objectweb.speedo.mapper.lib.Object2StringSerializer

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.