KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > gwt > user > rebind > rpc > SerializableTypeOracleImpl


1 /*
2  * Copyright 2007 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */

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 JavaDoc;
27 import java.util.Arrays JavaDoc;
28 import java.util.Collections JavaDoc;
29 import java.util.Comparator JavaDoc;
30 import java.util.HashSet JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.Set JavaDoc;
33 import java.util.zip.CRC32 JavaDoc;
34
35 final class SerializableTypeOracleImpl implements SerializableTypeOracle {
36
37   private static final String JavaDoc DEFAULT_BUILTIN_CUSTOM_SERIALIZER_PACKAGE_NAME = "com.google.gwt.user.client.rpc.core.java.lang";
38   private static final Comparator JavaDoc FIELD_COMPARATOR = new Comparator JavaDoc() {
39     public int compare(Object JavaDoc o1, Object JavaDoc 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 JavaDoc GENERATED_FIELD_SERIALIZER_SUFFIX = "_FieldSerializer";
47   private static final String JavaDoc TYPE_SERIALIZER_SUFFIX = "_TypeSerializer";
48   private static final Set JavaDoc TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES = new HashSet JavaDoc();
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 JavaDoc /* <JType> */serializableTypesSet;
67   private final TypeOracle typeOracle;
68
69   public SerializableTypeOracleImpl(TypeOracle typeOracle,
70       JType[] serializableTypes) {
71
72     this.serializableTypes = serializableTypes;
73     serializableTypesSet = new HashSet JavaDoc();
74     serializableTypesSet.addAll(Arrays.asList(serializableTypes));
75     this.typeOracle = typeOracle;
76   }
77
78   public String JavaDoc 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 JavaDoc[] 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       // TODO(mmendez): is this branch ever needed; if not, tighten param type
99
return type.getQualifiedSourceName() + GENERATED_FIELD_SERIALIZER_SUFFIX;
100     }
101   }
102
103   /**
104    * Returns the fields which qualify for serialization.
105    */

106   public JField[] getSerializableFields(JClassType classType) {
107     List JavaDoc fields = new ArrayList JavaDoc();
108     JField[] declFields = classType.getFields();
109     for (int iField = 0; iField < declFields.length; ++iField) {
110       JField field = declFields[iField];
111       // TODO(mmendez): this is shared with the serializable type oracle
112
// builder, join with that
113
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   /**
125    *
126    */

127   public JType[] getSerializableTypes() {
128     return serializableTypes;
129   }
130
131   public String JavaDoc getSerializationSignature(JType type) {
132     CRC32 JavaDoc crc = new CRC32 JavaDoc();
133
134     generateSerializationSignature(type, crc);
135
136     return Long.toString(crc.getValue());
137   }
138
139   public String JavaDoc 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 JavaDoc getTypeSerializerQualifiedName(JClassType serviceIntf) {
173     if (serviceIntf.isInterface() == null) {
174       throw new IllegalArgumentException JavaDoc(serviceIntf.getQualifiedSourceName()
175           + " is not a service interface");
176     }
177
178     String JavaDoc[] 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 JavaDoc getTypeSerializerSimpleName(JClassType serviceIntf) {
188     if (serviceIntf.isInterface() == null) {
189       throw new IllegalArgumentException JavaDoc(serviceIntf.getQualifiedSourceName()
190           + " is not a service interface");
191     }
192
193     String JavaDoc[] 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 JavaDoc 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   /**
229    * Returns <code>true</code> if the type is serializable.
230    */

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 JavaDoc crc) {
245     JParameterizedType parameterizedType = type.isParameterized();
246     if (parameterizedType != null) {
247       generateSerializationSignature(parameterizedType.getRawType(), crc);
248
249       return;
250     }
251
252     String JavaDoc 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