1 18 package org.objectweb.speedo.mapper.lib; 19 20 import org.objectweb.util.monolog.api.Logger; 21 import org.objectweb.util.monolog.api.BasicLevel; 22 import org.objectweb.speedo.api.Debug; 23 import org.objectweb.speedo.tools.StringReplace; 24 import org.objectweb.asm.ClassWriter; 25 import org.objectweb.asm.Constants; 26 import org.objectweb.asm.CodeVisitor; 27 28 import java.io.IOException ; 29 import java.io.ObjectOutputStream ; 30 import java.io.ObjectInputStream ; 31 import java.io.ByteArrayInputStream ; 32 import java.io.File ; 33 import java.io.FileOutputStream ; 34 35 41 public abstract class Object2StringSerializer { 42 43 public final static String JDO_FILE_NAME_PROP = "jdoFileName"; 44 45 52 public static String serialize(Object o) throws IOException { 53 java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream (); 54 ObjectOutputStream oos = new ObjectOutputStream (baos); 55 oos.writeObject(o); 56 oos.close(); 57 byte[] bs = baos.toByteArray(); 58 baos.close(); 59 StringBuffer sb = new StringBuffer (bs.length); 60 for (int i = 0; i < bs.length; i++) { 61 sb.append((char) (bs[i] & 0XFF)); 62 } 63 return sb.toString(); 64 } 65 66 75 public static Object deserialize(String s) throws IOException , ClassNotFoundException { 76 byte[] bs = new byte[s.length()]; 77 for (int i = 0; i < bs.length; i++) { 78 bs[i] = (byte) s.charAt(i); 79 } 80 ObjectInputStream ois = new ObjectInputStream (new ByteArrayInputStream (bs)); 81 Object o = ois.readObject(); 82 ois.close(); 83 return o; 84 } 85 86 87 public static String serialize(String output, String jdoFileName, Object jmi, Logger logger) throws IOException { 88 String className = jdoFileName2ClassName(jdoFileName); 89 90 if (Debug.ON && logger.isLoggable(BasicLevel.DEBUG)) { 91 logger.log( 92 BasicLevel.DEBUG, 93 "Serialize the Jorm Meta Information into the class '" 94 + className 95 + "' into the directory '" 96 + output 97 + "'."); 98 } 99 100 String value = Object2StringSerializer.serialize(jmi); 102 103 ClassWriter cw = generateJavaClass(className, value); 105 107 writeJavaClass(className, cw, output); 108 109 return output + File.separatorChar + className; 110 } 111 112 private static ClassWriter generateJavaClass(final String className, final String value) { 113 114 ClassWriter cw = new ClassWriter(true); 115 116 String str = StringReplace.replaceChar(File.separatorChar, '/', className); 117 118 cw.visit(Constants.V1_1, Constants.ACC_PUBLIC, str, "org/objectweb/speedo/mapper/lib/Object2StringSerializer", new String [0], str ); 124 CodeVisitor c = cw.visitMethod(Constants.ACC_PUBLIC, "<init>", "()V", null, null); 126 c.visitVarInsn(Constants.ALOAD, 0); 127 c.visitMethodInsn( 128 Constants.INVOKESPECIAL, 129 "org/objectweb/speedo/mapper/lib/Object2StringSerializer", 130 "<init>", 131 "()V"); 132 c.visitInsn(Constants.RETURN); 133 c.visitMaxs(0, 0); 134 135 c = cw.visitMethod(Constants.ACC_PUBLIC, "getSerializedObject", "()Ljava/lang/String;", null, null); 137 c.visitTypeInsn(Constants.NEW, "java/lang/StringBuffer"); 138 c.visitInsn(Constants.DUP); 139 c.visitMethodInsn(Constants.INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "()V"); 140 final int SPLIT_SIZE = 5000; 141 int nbSplit = value.length() / SPLIT_SIZE; 142 for (int i = 0; i < nbSplit; i++) { 143 int j = i * SPLIT_SIZE; 144 String s = value.substring(j, j + SPLIT_SIZE); 145 c.visitLdcInsn(s); 146 c.visitMethodInsn( 147 Constants.INVOKEVIRTUAL, 148 "java/lang/StringBuffer", 149 "append", 150 "(Ljava/lang/String;)Ljava/lang/StringBuffer;"); 151 } 152 int last = value.length() % SPLIT_SIZE; 153 if (last > 0) { 154 c.visitLdcInsn(value.substring(SPLIT_SIZE * nbSplit)); 155 c.visitMethodInsn( 156 Constants.INVOKEVIRTUAL, 157 "java/lang/StringBuffer", 158 "append", 159 "(Ljava/lang/String;)Ljava/lang/StringBuffer;"); 160 } 161 c.visitMethodInsn(Constants.INVOKEVIRTUAL, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;"); 162 c.visitInsn(Constants.ARETURN); 163 c.visitMaxs(1, 1); 164 165 return cw; 166 } 167 168 169 public static Object deserialize(String jdoFileName, ClassLoader cl, Logger logger) 170 throws Exception { 171 String className = jdoFileName2ClassName(jdoFileName); 172 if (className == null) { 173 throw new Exception ("Impossible to load a null class"); 174 } 175 className = StringReplace.replaceChar('/', '.', className); 176 logger.log(BasicLevel.DEBUG, "Loading serialized object into the class '" + className + "'."); 177 Object2StringSerializer s = null; 178 try { 179 s = (Object2StringSerializer) cl.loadClass(className).newInstance(); 180 } catch (Throwable e) { 181 ClassNotFoundException cnfe = new ClassNotFoundException ("Impossible to load the jorm meta information: The class " 182 + className + " is not availlable through the classloader (" + cl + ") of the persistent class", e); 183 logger.log(BasicLevel.ERROR, cnfe.getMessage(), cnfe); 184 throw cnfe; 185 } 186 return deserialize(s.getSerializedObject()); 187 } 188 189 private static void writeJavaClass(final String name, 190 final ClassWriter jclass, 191 final String srcFiles) throws IOException { 192 int p = name.lastIndexOf(File.separatorChar); 193 194 String pkg; 195 String clas; 196 if (p == -1) { 197 pkg = ""; 198 clas = name; 199 } 200 else { 201 pkg = name.substring(0, p); 202 clas = name.substring(p + 1); 203 } 204 File outputDir; 205 if (srcFiles == null) { 206 outputDir = new File (pkg); 207 } 208 else { 209 outputDir = new File (srcFiles + File.separatorChar + pkg); 210 } 211 212 outputDir.mkdirs(); 213 File outputFile = new File (outputDir, clas + ".class"); 214 outputFile.createNewFile(); 215 FileOutputStream fos = new FileOutputStream (outputFile); 216 fos.write(jclass.toByteArray()); 217 fos.close(); 218 } 219 220 public static Object getObject(String jdoFileName, ClassLoader cl, Logger logger) throws Exception { 221 String className = jdoFileName2ClassName(jdoFileName); 222 223 logger.log(BasicLevel.DEBUG, "Loading serialized object into the class '" + className + "'."); 224 Object2StringSerializer s = null; 225 try { 226 s = (Object2StringSerializer) cl.loadClass(className).newInstance(); 227 } 228 catch (Throwable e) { 229 ClassNotFoundException cnfe = 230 new ClassNotFoundException ( 231 "Impossible to load the jorm meta information: The class " 232 + className 233 + " is not availlable through the classloader of the persistent class", 234 e); 235 logger.log(BasicLevel.ERROR, cnfe.getMessage(), cnfe); 236 throw cnfe; 237 } 238 return deserialize(s.getSerializedObject()); 239 } 240 241 public static String jdoFileName2ClassName(String jdoFileName) { 242 return jdoFileName.substring(0, jdoFileName.length() - 4) + "SpeedoJMI"; 243 } 244 245 246 249 public abstract String getSerializedObject(); 250 251 } 252 | Popular Tags |