1 16 package com.google.gwt.user.server.rpc.impl; 17 18 import com.google.gwt.user.client.rpc.SerializationException; 19 import com.google.gwt.user.client.rpc.SerializationStreamReader; 20 import com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader; 21 22 import java.lang.reflect.Array ; 23 import java.lang.reflect.Field ; 24 import java.lang.reflect.InvocationTargetException ; 25 import java.lang.reflect.Method ; 26 import java.lang.reflect.Modifier ; 27 import java.util.ArrayList ; 28 29 33 public final class ServerSerializationStreamReader extends 34 AbstractSerializationStreamReader { 35 36 private ServerSerializableTypeOracle serializableTypeOracle; 37 38 private String [] stringTable; 39 40 private ArrayList tokenList = new ArrayList (); 41 42 private int tokenListIndex; 43 44 public ServerSerializationStreamReader( 45 ServerSerializableTypeOracle serializableTypeOracle) { 46 this.serializableTypeOracle = serializableTypeOracle; 47 } 48 49 public Object deserializeValue(Class type) throws SerializationException { 50 if (type == boolean.class) { 51 return Boolean.valueOf(readBoolean()); 52 } else if (type == byte.class) { 53 return new Byte (readByte()); 54 } else if (type == char.class) { 55 return new Character (readChar()); 56 } else if (type == double.class) { 57 return new Double (readDouble()); 58 } else if (type == float.class) { 59 return new Float (readFloat()); 60 } else if (type == int.class) { 61 return new Integer (readInt()); 62 } else if (type == long.class) { 63 return new Long (readLong()); 64 } else if (type == short.class) { 65 return new Short (readShort()); 66 } else if (type == String .class) { 67 return readString(); 68 } 69 70 return readObject(); 71 } 72 73 public void prepareToRead(String encodedTokens) throws SerializationException { 74 tokenList.clear(); 75 tokenListIndex = 0; 76 stringTable = null; 77 78 int idx = 0, nextIdx; 79 while (-1 != (nextIdx = encodedTokens.indexOf('\uffff', idx))) { 80 String current = encodedTokens.substring(idx, nextIdx); 81 tokenList.add(current); 82 idx = nextIdx + 1; 83 } 84 85 super.prepareToRead(encodedTokens); 86 87 deserializeStringTable(); 90 } 91 92 public boolean readBoolean() { 93 return !extract().equals("0"); 94 } 95 96 public byte readByte() { 97 return Byte.parseByte(extract()); 98 } 99 100 public char readChar() { 101 return (char) Integer.parseInt(extract()); 103 } 104 105 public double readDouble() { 106 return Double.parseDouble(extract()); 107 } 108 109 public float readFloat() { 110 return Float.parseFloat(extract()); 111 } 112 113 public int readInt() { 114 return Integer.parseInt(extract()); 115 } 116 117 public long readLong() { 118 return Long.parseLong(extract()); 119 } 120 121 public short readShort() { 122 return Short.parseShort(extract()); 123 } 124 125 public String readString() throws SerializationException { 126 return getString(readInt()); 127 } 128 129 protected Object deserialize(String typeSignature) 130 throws SerializationException { 131 Object instance = null; 132 SerializedInstanceReference serializedInstRef = serializableTypeOracle.decodeSerializedInstanceReference(typeSignature); 133 134 try { 135 Class instanceClass = Class.forName(serializedInstRef.getName(), false, 136 this.getClass().getClassLoader()); 137 138 if (!serializableTypeOracle.isSerializable(instanceClass)) { 139 throw new SerializationException("Class '" + instanceClass.getName() 140 + "' is not serializable"); 141 } 142 143 validateTypeVersions(instanceClass, serializedInstRef); 144 145 Class customSerializer = serializableTypeOracle.hasCustomFieldSerializer(instanceClass); 146 147 instance = instantiate(customSerializer, instanceClass); 148 149 rememberDecodedObject(instance); 150 151 deserializeImpl(customSerializer, instanceClass, instance); 152 153 return instance; 154 155 } catch (ClassNotFoundException e) { 156 throw new SerializationException(e); 157 158 } catch (InstantiationException e) { 159 throw new SerializationException(e); 160 161 } catch (IllegalAccessException e) { 162 throw new SerializationException(e); 163 164 } catch (IllegalArgumentException e) { 165 throw new SerializationException(e); 166 167 } catch (InvocationTargetException e) { 168 throw new SerializationException(e); 169 170 } catch (NoSuchMethodException e) { 171 throw new SerializationException(e); 172 } 173 } 174 175 protected String getString(int index) { 176 if (index == 0) { 177 return null; 178 } 179 assert (index > 0); 181 assert (index <= stringTable.length); 182 return stringTable[index - 1]; 183 } 184 185 private void deserializeImpl(Class customSerializer, Class instanceClass, 186 Object instance) throws NoSuchMethodException , IllegalArgumentException , 187 IllegalAccessException , InvocationTargetException , 188 SerializationException, ClassNotFoundException { 189 if (customSerializer != null) { 190 deserializeWithCustomFieldDeserializer(customSerializer, instanceClass, 191 instance); 192 } else { 193 deserializeWithDefaultFieldDeserializer(instanceClass, instance); 194 } 195 } 196 197 private void deserializeStringTable() { 198 int typeNameCount = readInt(); 199 stringTable = new String [typeNameCount]; 200 for (int typeNameIndex = 0; typeNameIndex < typeNameCount; ++typeNameIndex) { 201 stringTable[typeNameIndex] = extract(); 202 } 203 } 204 205 private void deserializeWithCustomFieldDeserializer(Class customSerializer, 206 Class instanceClass, Object instance) throws ClassNotFoundException , 207 NoSuchMethodException , IllegalAccessException , InvocationTargetException { 208 if (instanceClass.isArray()) { 209 Class componentType = instanceClass.getComponentType(); 210 if (!componentType.isPrimitive()) { 211 instanceClass = Class.forName("[Ljava.lang.Object;"); 212 } 213 } 214 Method deserialize = customSerializer.getMethod("deserialize", new Class [] { 215 SerializationStreamReader.class, instanceClass}); 216 deserialize.invoke(null, new Object [] {this, instance}); 217 } 218 219 private void deserializeWithDefaultFieldDeserializer(Class instanceClass, 220 Object instance) throws SerializationException, IllegalAccessException , 221 NoSuchMethodException , InvocationTargetException , ClassNotFoundException { 222 Field [] declFields = instanceClass.getDeclaredFields(); 223 Field [] serializableFields = serializableTypeOracle.applyFieldSerializationPolicy(declFields); 224 225 for (int index = 0; index < serializableFields.length; ++index) { 226 Field declField = serializableFields[index]; 227 assert (declField != null); 228 229 Object value = deserializeValue(declField.getType()); 230 231 boolean isAccessible = declField.isAccessible(); 232 boolean needsAccessOverride = !isAccessible 233 && !Modifier.isPublic(declField.getModifiers()); 234 if (needsAccessOverride) { 235 declField.setAccessible(true); 237 } 238 239 declField.set(instance, value); 240 241 if (needsAccessOverride) { 242 declField.setAccessible(isAccessible); 244 } 245 } 246 247 Class superClass = instanceClass.getSuperclass(); 248 if (superClass != null && serializableTypeOracle.isSerializable(superClass)) { 249 deserializeImpl( 250 serializableTypeOracle.hasCustomFieldSerializer(superClass), 251 superClass, instance); 252 } 253 } 254 255 private String extract() { 256 return (String ) tokenList.get(tokenListIndex++); 257 } 258 259 private Object instantiate(Class customSerializer, Class instanceClass) 260 throws InstantiationException , IllegalAccessException , 261 IllegalArgumentException , InvocationTargetException { 262 if (customSerializer != null) { 263 try { 264 Method instantiate = customSerializer.getMethod("instantiate", 265 new Class [] {SerializationStreamReader.class}); 266 return instantiate.invoke(null, new Object [] {this}); 267 } catch (NoSuchMethodException e) { 268 } 270 } 271 272 if (instanceClass.isArray()) { 273 int length = readInt(); 274 Class componentType = instanceClass.getComponentType(); 275 return Array.newInstance(componentType, length); 276 } else { 277 return instanceClass.newInstance(); 278 } 279 } 280 281 private void validateTypeVersions(Class instanceClass, 282 SerializedInstanceReference serializedInstRef) 283 throws SerializationException { 284 String clientTypeSignature = serializedInstRef.getSignature(); 285 if (clientTypeSignature.length() == 0) { 286 if (shouldEnforceTypeVersioning()) { 287 throw new SerializationException("Missing type signature for " 288 + instanceClass.getName()); 289 } 290 291 return; 292 } 293 294 String serverTypeSignature = serializableTypeOracle.getSerializationSignature(instanceClass); 295 296 if (!clientTypeSignature.equals(serverTypeSignature)) { 297 throw new SerializationException("Invalid type signature for " 298 + instanceClass.getName()); 299 } 300 } 301 } 302 | Popular Tags |