1 48 49 package com.caucho.hessian.io; 50 51 import java.io.IOException ; 52 import java.io.Serializable ; 53 import java.lang.reflect.Field ; 54 import java.lang.reflect.Method ; 55 import java.lang.reflect.Modifier ; 56 import java.util.ArrayList ; 57 import java.util.logging.Level ; 58 import java.util.logging.Logger ; 59 60 63 public class JavaSerializer extends AbstractSerializer 64 { 65 private static final Logger log 66 = Logger.getLogger(JavaSerializer.class.getName()); 67 68 private Field []_fields; 69 private FieldSerializer []_fieldSerializers; 70 private Method _writeReplace; 71 72 public JavaSerializer(Class cl) 73 { 74 if (! Serializable .class.isAssignableFrom(cl)) { 75 log.fine("hessian - class " + cl.getName() + " must implement java.io.Serializable"); 76 77 throw new IllegalStateException ("Serialized class " + cl.getName() + " does not implement java.io.Serializable"); 78 } 79 80 _writeReplace = getWriteReplace(cl); 81 if (_writeReplace != null) 82 _writeReplace.setAccessible(true); 83 84 ArrayList primitiveFields = new ArrayList (); 85 ArrayList compoundFields = new ArrayList (); 86 87 for (; cl != null; cl = cl.getSuperclass()) { 88 Field []fields = cl.getDeclaredFields(); 89 for (int i = 0; i < fields.length; i++) { 90 Field field = fields[i]; 91 92 if (Modifier.isTransient(field.getModifiers()) || 93 Modifier.isStatic(field.getModifiers())) 94 continue; 95 96 field.setAccessible(true); 98 99 if (field.getType().isPrimitive() || 100 field.getType().getName().startsWith("java.lang.") && 101 ! field.getType().equals(Object .class)) 102 primitiveFields.add(field); 103 else 104 compoundFields.add(field); 105 } 106 } 107 108 ArrayList fields = new ArrayList (); 109 fields.addAll(primitiveFields); 110 fields.addAll(compoundFields); 111 112 _fields = new Field [fields.size()]; 113 fields.toArray(_fields); 114 115 _fieldSerializers = new FieldSerializer[_fields.length]; 116 117 for (int i = 0; i < _fields.length; i++) { 118 _fieldSerializers[i] = getFieldSerializer(_fields[i].getType()); 119 } 120 } 121 122 125 protected Method getWriteReplace(Class cl) 126 { 127 for (; cl != null; cl = cl.getSuperclass()) { 128 Method []methods = cl.getDeclaredMethods(); 129 130 for (int i = 0; i < methods.length; i++) { 131 Method method = methods[i]; 132 133 if (method.getName().equals("writeReplace") && 134 method.getParameterTypes().length == 0) 135 return method; 136 } 137 } 138 139 return null; 140 } 141 142 public void writeObject(Object obj, AbstractHessianOutput out) 143 throws IOException 144 { 145 if (out.addRef(obj)) { 146 return; 147 } 148 149 Class cl = obj.getClass(); 150 151 try { 152 if (_writeReplace != null) { 153 Object repl = _writeReplace.invoke(obj, new Object [0]); 154 155 out.removeRef(obj); 156 157 out.writeObject(repl); 158 159 out.replaceRef(repl, obj); 160 161 return; 162 } 163 } catch (Exception e) { 164 log.log(Level.FINE, e.toString(), e); 165 } 166 167 int ref = out.writeObjectBegin(cl.getName()); 168 169 if (ref < 0) { 170 writeObject10(obj, out); 171 } 172 else { 173 if (ref == 0) 174 writeDefinition20(out); 175 176 writeInstance(obj, out); 177 } 178 } 179 180 private void writeObject10(Object obj, AbstractHessianOutput out) 181 throws IOException 182 { 183 for (int i = 0; i < _fields.length; i++) { 184 Field field = _fields[i]; 185 186 out.writeString(field.getName()); 187 188 _fieldSerializers[i].serialize(out, obj, field); 189 } 190 191 out.writeMapEnd(); 192 } 193 194 private void writeDefinition20(AbstractHessianOutput out) 195 throws IOException 196 { 197 out.writeClassFieldLength(_fields.length); 198 199 for (int i = 0; i < _fields.length; i++) { 200 Field field = _fields[i]; 201 202 out.writeString(field.getName()); 203 } 204 } 205 206 public void writeInstance(Object obj, AbstractHessianOutput out) 207 throws IOException 208 { 209 for (int i = 0; i < _fields.length; i++) { 210 Field field = _fields[i]; 211 212 _fieldSerializers[i].serialize(out, obj, field); 213 } 214 } 215 216 private static FieldSerializer getFieldSerializer(Class type) 217 { 218 if (int.class.equals(type) || 219 byte.class.equals(type) || 220 short.class.equals(type) || 221 int.class.equals(type)) { 222 return IntFieldSerializer.SER; 223 } 224 else if (long.class.equals(type)) { 225 return LongFieldSerializer.SER; 226 } 227 else if (double.class.equals(type) || 228 float.class.equals(type)) { 229 return DoubleFieldSerializer.SER; 230 } 231 else if (boolean.class.equals(type)) { 232 return BooleanFieldSerializer.SER; 233 } 234 else if (String .class.equals(type)) { 235 return StringFieldSerializer.SER; 236 } 237 else 238 return FieldSerializer.SER; 239 } 240 241 static class FieldSerializer { 242 static final FieldSerializer SER = new FieldSerializer(); 243 244 void serialize(AbstractHessianOutput out, Object obj, Field field) 245 throws IOException 246 { 247 Object value = null; 248 249 try { 250 value = field.get(obj); 251 } catch (IllegalAccessException e) { 252 log.log(Level.FINE, e.toString(), e); 253 } 254 255 out.writeObject(value); 256 } 257 } 258 259 static class BooleanFieldSerializer extends FieldSerializer { 260 static final FieldSerializer SER = new BooleanFieldSerializer(); 261 262 void serialize(AbstractHessianOutput out, Object obj, Field field) 263 throws IOException 264 { 265 boolean value = false; 266 267 try { 268 value = field.getBoolean(obj); 269 } catch (IllegalAccessException e) { 270 log.log(Level.FINE, e.toString(), e); 271 } 272 273 out.writeBoolean(value); 274 } 275 } 276 277 static class IntFieldSerializer extends FieldSerializer { 278 static final FieldSerializer SER = new IntFieldSerializer(); 279 280 void serialize(AbstractHessianOutput out, Object obj, Field field) 281 throws IOException 282 { 283 int value = 0; 284 285 try { 286 value = field.getInt(obj); 287 } catch (IllegalAccessException e) { 288 log.log(Level.FINE, e.toString(), e); 289 } 290 291 out.writeInt(value); 292 } 293 } 294 295 static class LongFieldSerializer extends FieldSerializer { 296 static final FieldSerializer SER = new LongFieldSerializer(); 297 298 void serialize(AbstractHessianOutput out, Object obj, Field field) 299 throws IOException 300 { 301 long value = 0; 302 303 try { 304 value = field.getLong(obj); 305 } catch (IllegalAccessException e) { 306 log.log(Level.FINE, e.toString(), e); 307 } 308 309 out.writeLong(value); 310 } 311 } 312 313 static class DoubleFieldSerializer extends FieldSerializer { 314 static final FieldSerializer SER = new DoubleFieldSerializer(); 315 316 void serialize(AbstractHessianOutput out, Object obj, Field field) 317 throws IOException 318 { 319 double value = 0; 320 321 try { 322 value = field.getDouble(obj); 323 } catch (IllegalAccessException e) { 324 log.log(Level.FINE, e.toString(), e); 325 } 326 327 out.writeDouble(value); 328 } 329 } 330 331 static class StringFieldSerializer extends FieldSerializer { 332 static final FieldSerializer SER = new StringFieldSerializer(); 333 334 void serialize(AbstractHessianOutput out, Object obj, Field field) 335 throws IOException 336 { 337 String value = null; 338 339 try { 340 value = (String ) field.get(obj); 341 } catch (IllegalAccessException e) { 342 log.log(Level.FINE, e.toString(), e); 343 } 344 345 out.writeString(value); 346 } 347 } 348 } 349 | Popular Tags |