1 16 package com.google.gwt.user.rebind.rpc; 17 18 import com.google.gwt.core.ext.typeinfo.JArrayType; 19 import com.google.gwt.core.ext.typeinfo.JClassType; 20 import com.google.gwt.core.ext.typeinfo.JField; 21 import com.google.gwt.core.ext.typeinfo.JParameterizedType; 22 import com.google.gwt.core.ext.typeinfo.JPrimitiveType; 23 import com.google.gwt.core.ext.typeinfo.JType; 24 import com.google.gwt.core.ext.typeinfo.TypeOracle; 25 26 import java.util.ArrayList ; 27 import java.util.Arrays ; 28 import java.util.Collections ; 29 import java.util.Comparator ; 30 import java.util.HashSet ; 31 import java.util.List ; 32 import java.util.Set ; 33 import java.util.zip.CRC32 ; 34 35 final class SerializableTypeOracleImpl implements SerializableTypeOracle { 36 37 private static final String DEFAULT_BUILTIN_CUSTOM_SERIALIZER_PACKAGE_NAME = "com.google.gwt.user.client.rpc.core.java.lang"; 38 private static final Comparator FIELD_COMPARATOR = new Comparator () { 39 public int compare(Object o1, Object o2) { 40 JField f1 = (JField) o1; 41 JField f2 = (JField) o2; 42 43 return f1.getName().compareTo(f2.getName()); 44 } 45 }; 46 private static final String GENERATED_FIELD_SERIALIZER_SUFFIX = "_FieldSerializer"; 47 private static final String TYPE_SERIALIZER_SUFFIX = "_TypeSerializer"; 48 private static final Set TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES = new HashSet (); 49 50 static { 51 TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES.add("java.lang.Boolean"); 52 TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES.add("java.lang.Byte"); 53 TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES.add("java.lang.Character"); 54 TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES.add("java.lang.Double"); 55 TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES.add("java.lang.Exception"); 56 TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES.add("java.lang.Float"); 57 TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES.add("java.lang.Integer"); 58 TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES.add("java.lang.Long"); 59 TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES.add("java.lang.Object"); 60 TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES.add("java.lang.Short"); 61 TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES.add("java.lang.String"); 62 TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES.add("java.lang.Throwable"); 63 } 64 65 private final JType[] serializableTypes; 66 private final Set serializableTypesSet; 67 private final TypeOracle typeOracle; 68 69 public SerializableTypeOracleImpl(TypeOracle typeOracle, 70 JType[] serializableTypes) { 71 72 this.serializableTypes = serializableTypes; 73 serializableTypesSet = new HashSet (); 74 serializableTypesSet.addAll(Arrays.asList(serializableTypes)); 75 this.typeOracle = typeOracle; 76 } 77 78 public String getFieldSerializerName(JType type) { 79 if (!isSerializable(type)) { 80 return null; 81 } 82 83 JClassType customSerializer = hasCustomFieldSerializer(type); 84 if (customSerializer != null) { 85 return customSerializer.getQualifiedSourceName(); 86 } 87 88 JClassType classType = type.isClassOrInterface(); 89 if (classType != null) { 90 String [] name = Shared.synthesizeTopLevelClassName(classType, 91 GENERATED_FIELD_SERIALIZER_SUFFIX); 92 if (name[0].length() > 0) { 93 return name[0] + "." + name[1]; 94 } else { 95 return name[1]; 96 } 97 } else { 98 return type.getQualifiedSourceName() + GENERATED_FIELD_SERIALIZER_SUFFIX; 100 } 101 } 102 103 106 public JField[] getSerializableFields(JClassType classType) { 107 List fields = new ArrayList (); 108 JField[] declFields = classType.getFields(); 109 for (int iField = 0; iField < declFields.length; ++iField) { 110 JField field = declFields[iField]; 111 if (field.isStatic() || field.isTransient() || field.isFinal()) { 114 continue; 115 } 116 117 fields.add(field); 118 } 119 120 Collections.sort(fields, FIELD_COMPARATOR); 121 return (JField[]) fields.toArray(new JField[fields.size()]); 122 } 123 124 127 public JType[] getSerializableTypes() { 128 return serializableTypes; 129 } 130 131 public String getSerializationSignature(JType type) { 132 CRC32 crc = new CRC32 (); 133 134 generateSerializationSignature(type, crc); 135 136 return Long.toString(crc.getValue()); 137 } 138 139 public String getSerializedTypeName(JType type) { 140 JPrimitiveType primitiveType = type.isPrimitive(); 141 if (primitiveType != null) { 142 return primitiveType.getJNISignature(); 143 } 144 145 JArrayType arrayType = type.isArray(); 146 if (arrayType != null) { 147 JType component = arrayType.getComponentType(); 148 if (component.isClassOrInterface() != null) { 149 return "[L" + getSerializedTypeName(arrayType.getComponentType()) + ";"; 150 } else { 151 return "[" + getSerializedTypeName(arrayType.getComponentType()); 152 } 153 } 154 155 JParameterizedType parameterizedType = type.isParameterized(); 156 if (parameterizedType != null) { 157 return getSerializedTypeName(parameterizedType.getRawType()); 158 } 159 160 JClassType classType = type.isClassOrInterface(); 161 assert (classType != null); 162 163 JClassType enclosingType = classType.getEnclosingType(); 164 if (enclosingType != null) { 165 return getSerializedTypeName(enclosingType) + "$" 166 + classType.getSimpleSourceName(); 167 } 168 169 return classType.getQualifiedSourceName(); 170 } 171 172 public String getTypeSerializerQualifiedName(JClassType serviceIntf) { 173 if (serviceIntf.isInterface() == null) { 174 throw new IllegalArgumentException (serviceIntf.getQualifiedSourceName() 175 + " is not a service interface"); 176 } 177 178 String [] name = Shared.synthesizeTopLevelClassName(serviceIntf, 179 TYPE_SERIALIZER_SUFFIX); 180 if (name[0].length() > 0) { 181 return name[0] + "." + name[1]; 182 } else { 183 return name[1]; 184 } 185 } 186 187 public String getTypeSerializerSimpleName(JClassType serviceIntf) { 188 if (serviceIntf.isInterface() == null) { 189 throw new IllegalArgumentException (serviceIntf.getQualifiedSourceName() 190 + " is not a service interface"); 191 } 192 193 String [] name = Shared.synthesizeTopLevelClassName(serviceIntf, 194 TYPE_SERIALIZER_SUFFIX); 195 return name[1]; 196 } 197 198 public JClassType hasCustomFieldSerializer(JType type) { 199 JClassType customSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer( 200 typeOracle, type); 201 if (customSerializer != null) { 202 return customSerializer; 203 } 204 205 if (!isSerializable(type)) { 206 return null; 207 } 208 209 JArrayType arrayType = type.isArray(); 210 if (arrayType == null) { 211 return null; 212 } 213 214 JType componentType = arrayType.getComponentType(); 215 JPrimitiveType primitiveType = componentType.isPrimitive(); 216 String qualifiedSerializerName = DEFAULT_BUILTIN_CUSTOM_SERIALIZER_PACKAGE_NAME 217 + "."; 218 if (primitiveType != null) { 219 qualifiedSerializerName += primitiveType.getSimpleSourceName(); 220 } else { 221 qualifiedSerializerName += typeOracle.getJavaLangObject().getSimpleSourceName(); 222 } 223 qualifiedSerializerName += "_Array_CustomFieldSerializer"; 224 225 return typeOracle.findType(qualifiedSerializerName); 226 } 227 228 231 public boolean isSerializable(JType type) { 232 return serializableTypesSet.contains(type); 233 } 234 235 private boolean excludeImplementationFromSerializationSignature( 236 JType instanceType) { 237 if (TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES.contains(instanceType.getQualifiedSourceName())) { 238 return true; 239 } 240 241 return false; 242 } 243 244 private void generateSerializationSignature(JType type, CRC32 crc) { 245 JParameterizedType parameterizedType = type.isParameterized(); 246 if (parameterizedType != null) { 247 generateSerializationSignature(parameterizedType.getRawType(), crc); 248 249 return; 250 } 251 252 String serializedTypeName = getSerializedTypeName(type); 253 crc.update(serializedTypeName.getBytes()); 254 255 if (excludeImplementationFromSerializationSignature(type)) { 256 return; 257 } 258 259 JClassType customSerializer = hasCustomFieldSerializer(type); 260 if (customSerializer != null) { 261 generateSerializationSignature(customSerializer, crc); 262 } else if (type.isArray() != null) { 263 JArrayType isArray = type.isArray(); 264 generateSerializationSignature(isArray.getComponentType(), crc); 265 } else if (type.isClassOrInterface() != null) { 266 JClassType isClassOrInterface = type.isClassOrInterface(); 267 JField[] fields = getSerializableFields(isClassOrInterface); 268 for (int i = 0; i < fields.length; ++i) { 269 JField field = fields[i]; 270 assert (field != null); 271 272 crc.update(field.getName().getBytes()); 273 crc.update(getSerializedTypeName(field.getType()).getBytes()); 274 } 275 276 JClassType superClass = isClassOrInterface.getSuperclass(); 277 if (superClass != null) { 278 generateSerializationSignature(superClass, crc); 279 } 280 } 281 } 282 } 283 | Popular Tags |