1 16 package com.google.gwt.user.rebind.rpc; 17 18 import com.google.gwt.core.ext.GeneratorContext; 19 import com.google.gwt.core.ext.TreeLogger; 20 import com.google.gwt.core.ext.typeinfo.JArrayType; 21 import com.google.gwt.core.ext.typeinfo.JClassType; 22 import com.google.gwt.core.ext.typeinfo.JField; 23 import com.google.gwt.core.ext.typeinfo.JType; 24 import com.google.gwt.user.client.rpc.SerializationException; 25 import com.google.gwt.user.client.rpc.SerializationStreamReader; 26 import com.google.gwt.user.client.rpc.SerializationStreamWriter; 27 import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; 28 import com.google.gwt.user.rebind.SourceWriter; 29 30 import java.io.PrintWriter ; 31 32 52 public class FieldSerializerCreator { 53 54 private final JClassType serializableClass; 55 56 private final JField[] serializableFields; 57 58 private final SerializableTypeOracle serializationOracle; 59 60 private SourceWriter sourceWriter; 61 62 68 public FieldSerializerCreator(SerializableTypeOracle serializationOracle, 69 JClassType requestedClass) { 70 assert (requestedClass != null); 71 assert (requestedClass.isClass() != null); 72 73 this.serializationOracle = serializationOracle; 74 serializableClass = requestedClass; 75 serializableFields = serializationOracle.getSerializableFields(requestedClass); 76 } 77 78 public String realize(TreeLogger logger, GeneratorContext ctx) { 79 assert (ctx != null); 80 assert (serializationOracle.isSerializable(serializableClass)); 81 82 logger = logger.branch(TreeLogger.DEBUG, 83 "Generating a field serializer for type '" 84 + serializableClass.getQualifiedSourceName() + "'", null); 85 String fieldSerializerName = serializationOracle.getFieldSerializerName(serializableClass); 86 87 sourceWriter = getSourceWriter(logger, ctx); 88 if (sourceWriter == null) { 89 return fieldSerializerName; 90 } 91 assert sourceWriter != null; 92 93 writeFieldAccessors(); 94 95 writeSerializeMethod(); 96 97 writeDeserializeMethod(); 98 99 sourceWriter.commit(logger); 100 101 return fieldSerializerName; 102 } 103 104 109 private String getFieldSerializerClassName() { 110 String sourceName = serializationOracle.getFieldSerializerName(serializableClass); 111 112 int qualifiedSourceNameStart = sourceName.lastIndexOf('.'); 113 if (qualifiedSourceNameStart >= 0) { 114 sourceName = sourceName.substring(qualifiedSourceNameStart + 1); 115 } 116 117 return sourceName; 118 } 119 120 private SourceWriter getSourceWriter(TreeLogger logger, GeneratorContext ctx) { 121 String packageName = serializableClass.getPackage().getName(); 122 String className = getFieldSerializerClassName(); 123 124 PrintWriter printWriter = ctx.tryCreate(logger, packageName, className); 125 if (printWriter == null) { 126 return null; 127 } 128 129 ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory( 130 packageName, className); 131 132 return composerFactory.createSourceWriter(ctx, printWriter); 133 } 134 135 140 private boolean needsAccessorMethods(JField field) { 141 149 return field.isPrivate(); 150 } 151 152 private void writeDeserializeMethod() { 153 sourceWriter.print("public static void deserialize("); 154 sourceWriter.print(SerializationStreamReader.class.getName()); 155 sourceWriter.print(" streamReader, "); 156 sourceWriter.print(serializableClass.getQualifiedSourceName()); 157 sourceWriter.println(" instance) throws " 158 + SerializationException.class.getName() + "{"); 159 sourceWriter.indent(); 160 161 writeFieldDeserializationStatements(); 162 163 JClassType superClass = serializableClass.getSuperclass(); 164 if (superClass != null && serializationOracle.isSerializable(superClass)) { 165 String fieldSerializerName = serializationOracle.getFieldSerializerName(superClass); 166 sourceWriter.print(fieldSerializerName); 167 sourceWriter.println(".deserialize(streamReader, instance);"); 168 } 169 170 sourceWriter.outdent(); 171 sourceWriter.println("}"); 172 sourceWriter.println(); 173 } 174 175 180 private void writeFieldAccessors() { 181 JField[] jFields = serializableFields; 182 int fieldCount = jFields.length; 183 184 for (int fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex) { 185 JField serializableField = jFields[fieldIndex]; 186 187 if (!needsAccessorMethods(serializableField)) { 188 continue; 189 } 190 191 writeFieldGet(serializableField); 192 writeFieldSet(serializableField); 193 } 194 } 195 196 private void writeFieldDeserializationStatements() { 197 JType type = serializableClass; 198 JArrayType isArray = type.isArray(); 199 if (isArray != null) { 200 sourceWriter.println("for (int itemIndex = 0; itemIndex < instance.length; ++itemIndex) {"); 201 sourceWriter.indent(); 202 203 JType componentType = isArray.getComponentType(); 204 205 sourceWriter.print("instance[itemIndex] = "); 206 if (Shared.typeNeedsCast(componentType)) { 207 sourceWriter.print("(" + componentType.getQualifiedSourceName() + ") "); 208 } 209 String readMethodName = "streamReader.read" 210 + Shared.getCallSuffix(componentType); 211 sourceWriter.println(readMethodName + "();"); 212 sourceWriter.outdent(); 213 sourceWriter.println("}"); 214 } else { 215 JField[] jFields = serializableFields; 216 int fieldCount = jFields.length; 217 218 for (int fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex) { 219 JField serializableField = jFields[fieldIndex]; 220 JType fieldType = serializableField.getType(); 221 boolean needsAccessor = needsAccessorMethods(serializableField); 222 223 String readMethodName = "read" + Shared.getCallSuffix(fieldType); 224 String streamReadExpression = "streamReader." + readMethodName + "()"; 225 if (Shared.typeNeedsCast(fieldType)) { 226 streamReadExpression = "(" + fieldType.getQualifiedSourceName() 227 + ") " + streamReadExpression; 228 } 229 230 if (needsAccessor) { 231 sourceWriter.print("set"); 232 sourceWriter.print(Shared.capitalize(serializableField.getName())); 233 sourceWriter.print("(instance, "); 234 sourceWriter.print(streamReadExpression); 235 sourceWriter.println(");"); 236 } else { 237 sourceWriter.print("instance."); 238 sourceWriter.print(serializableField.getName()); 239 sourceWriter.print(" = "); 240 sourceWriter.print(streamReadExpression); 241 sourceWriter.println(";"); 242 } 243 } 244 } 245 246 sourceWriter.println(); 247 } 248 249 252 private void writeFieldGet(JField serializableField) { 253 JType fieldType = serializableField.getType(); 254 String fieldTypeQualifiedSourceName = fieldType.getQualifiedSourceName(); 255 String fieldName = serializableField.getName(); 256 257 sourceWriter.print("private static native "); 258 sourceWriter.print(fieldTypeQualifiedSourceName); 259 sourceWriter.print(" get"); 260 sourceWriter.print(Shared.capitalize(fieldName)); 261 sourceWriter.print("("); 262 sourceWriter.print(serializableClass.getQualifiedSourceName()); 263 sourceWriter.println(" instance) /*-{"); 264 sourceWriter.indent(); 265 266 sourceWriter.print("return instance.@"); 267 sourceWriter.print(serializationOracle.getSerializedTypeName(serializableClass)); 268 sourceWriter.print("::"); 269 sourceWriter.print(fieldName); 270 sourceWriter.println(";"); 271 272 sourceWriter.outdent(); 273 sourceWriter.println("}-*/;"); 274 sourceWriter.println(); 275 } 276 277 private void writeFieldSerializationStatements() { 278 JType type = serializableClass; 279 JArrayType isArray = type.isArray(); 280 if (isArray != null) { 281 sourceWriter.println("int itemCount = instance.length;"); 282 sourceWriter.println(); 283 sourceWriter.println("streamWriter.writeInt(itemCount);"); 284 sourceWriter.println(); 285 sourceWriter.println("for (int itemIndex = 0; itemIndex < itemCount; ++itemIndex) {"); 286 sourceWriter.indent(); 287 String writeMethodName = "write" 288 + Shared.getCallSuffix(isArray.getComponentType()); 289 sourceWriter.print("streamWriter."); 290 sourceWriter.print(writeMethodName); 291 sourceWriter.println("(instance[itemIndex]);"); 292 sourceWriter.outdent(); 293 sourceWriter.println("}"); 294 } else { 295 JField[] jFields = serializableFields; 296 int fieldCount = jFields.length; 297 298 for (int fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex) { 299 JField serializableField = jFields[fieldIndex]; 300 JType fieldType = serializableField.getType(); 301 302 String writeMethodName = "write" + Shared.getCallSuffix(fieldType); 303 sourceWriter.print("streamWriter."); 304 sourceWriter.print(writeMethodName); 305 sourceWriter.print("("); 306 307 if (needsAccessorMethods(serializableField)) { 308 sourceWriter.print("get"); 309 sourceWriter.print(Shared.capitalize(serializableField.getName())); 310 sourceWriter.println("(instance));"); 311 } else { 312 sourceWriter.print("instance."); 313 sourceWriter.print(serializableField.getName()); 314 sourceWriter.println(");"); 315 } 316 } 317 } 318 319 sourceWriter.println(); 320 } 321 322 325 private void writeFieldSet(JField serializableField) { 326 JType fieldType = serializableField.getType(); 327 String fieldTypeQualifiedSourceName = fieldType.getQualifiedSourceName(); 328 String serializableClassQualifedName = serializableClass.getQualifiedSourceName(); 329 String fieldName = serializableField.getName(); 330 331 sourceWriter.print("private static native void "); 332 sourceWriter.print(" set"); 333 sourceWriter.print(Shared.capitalize(fieldName)); 334 sourceWriter.print("("); 335 sourceWriter.print(serializableClassQualifedName); 336 sourceWriter.print(" instance, "); 337 sourceWriter.print(fieldTypeQualifiedSourceName); 338 sourceWriter.println(" value) /*-{"); 339 sourceWriter.indent(); 340 341 sourceWriter.print("instance.@"); 342 sourceWriter.print(serializationOracle.getSerializedTypeName(serializableClass)); 343 sourceWriter.print("::"); 344 sourceWriter.print(fieldName); 345 sourceWriter.println(" = value;"); 346 347 sourceWriter.outdent(); 348 sourceWriter.println("}-*/;"); 349 sourceWriter.println(); 350 } 351 352 private void writeSerializeMethod() { 353 sourceWriter.print("public static void serialize("); 354 sourceWriter.print(SerializationStreamWriter.class.getName()); 355 sourceWriter.print(" streamWriter, "); 356 sourceWriter.print(serializableClass.getQualifiedSourceName()); 357 sourceWriter.println(" instance) throws " 358 + SerializationException.class.getName() + " {"); 359 sourceWriter.indent(); 360 361 writeFieldSerializationStatements(); 362 363 JClassType superClass = serializableClass.getSuperclass(); 364 if (superClass != null && serializationOracle.isSerializable(superClass)) { 365 String fieldSerializerName = serializationOracle.getFieldSerializerName(superClass); 366 sourceWriter.print(fieldSerializerName); 367 sourceWriter.println(".serialize(streamWriter, instance);"); 368 } 369 370 sourceWriter.outdent(); 371 sourceWriter.println("}"); 372 sourceWriter.println(); 373 } 374 375 } 376 | Popular Tags |