/** * Writes a method to produce a map of class name to type string for Java. * * <pre> * private static Map<String<?>, String> loadSignaturesJava() { * Map<String<?>, String> result = new HashMap<String<?>, String>(); * result.put( * com.google.gwt.user.client.rpc.core.java.lang.String_FieldSerializer.concreteType(), * "java.lang.String/2004016611"); * ... * return result; * } * </pre> */ private void writeLoadSignaturesJava() { srcWriter.println("@SuppressWarnings(\"deprecation\")"); srcWriter.println("private static Map<String, String> loadSignaturesJava() {"); srcWriter.indent(); srcWriter.println("Map<String, String> result = new HashMap<String, String>();"); for (JType type : getSerializableTypes()) { String typeString = typeStrings.get(type); if (!serializationOracle.maybeInstantiated(type) && !deserializationOracle.maybeInstantiated(type)) { continue; } String typeRef; JClassType customSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer(typeOracle, type); if (customSerializer != null && CustomFieldSerializerValidator.getConcreteTypeMethod(customSerializer) != null) { typeRef = customSerializer.getQualifiedSourceName() + ".concreteType()"; } else { typeRef = '"' + SerializationUtils.getRpcTypeName(type) + '"'; } srcWriter.println("result.put(" + typeRef + ", \"" + typeString + "\");"); } srcWriter.println("return result;"); srcWriter.outdent(); srcWriter.println("}"); srcWriter.println(); }
/** * Writes a method to produce a map of type string -> class name of {@link TypeHandler} for Java. * * <pre> * private static Map<String, String> loadMethodsJava() { * Map<String, String> result = new HashMap<String, String>(); * result.put( * "java.lang.String/2004016611", * "com.google.gwt.user.client.rpc.core.java.lang.String_FieldSerializer" * ... * return result; * } * </pre> */ private void writeLoadMethodsJava() { srcWriter.println("@SuppressWarnings(\"deprecation\")"); srcWriter.println("private static Map<String, String> loadMethodsJava() {"); srcWriter.indent(); srcWriter.println("Map<String, String> result = new HashMap<String, String>();"); List<JType> filteredTypes = new ArrayList<JType>(); JType[] types = getSerializableTypes(); int n = types.length; for (int index = 0; index < n; ++index) { JType type = types[index]; if (serializationOracle.maybeInstantiated(type) || deserializationOracle.maybeInstantiated(type)) { filteredTypes.add(type); } } for (JType type : filteredTypes) { String typeString = typeStrings.get(type); assert typeString != null : "Missing type signature for " + type.getQualifiedSourceName(); srcWriter.println( "result.put(\"" + typeString + "\", \"" + SerializationUtils.getStandardSerializerName((JClassType) type) + "\");"); } srcWriter.println("return result;"); srcWriter.outdent(); srcWriter.println("}"); srcWriter.println(); }
/** * Writes a method to produce a native map of type string -> handler funcs. * * <pre> * private static native MethodMap loadMethodsNative() /*-{ * var result = {}; * result["java.lang.String/2004016611"] = [ * @com.google.gwt.user.client.rpc.core.java.lang.String_CustomFieldSerializer::instantiate(Lcom/google/gwt/user/client/rpc/SerializationStreamReader;), * @com.google.gwt.user.client.rpc.core.java.lang.String_CustomFieldSerializer::deserialize(Lcom/google/gwt/user/client/rpc/SerializationStreamReader;Ljava/lang/String;), * @com.google.gwt.user.client.rpc.core.java.lang.String_CustomFieldSerializer::serialize(Lcom/google/gwt/user/client/rpc/SerializationStreamWriter;Ljava/lang/String;) * ]; * ... * return result; * }-*/; * </pre> */ private void writeLoadMethodsNative() { srcWriter.println("@SuppressWarnings(\"deprecation\")"); srcWriter.println("@GwtScriptOnly"); srcWriter.println("private static native MethodMap loadMethodsNative() /*-{"); srcWriter.indent(); srcWriter.println("var result = {};"); List<JType> filteredTypes = new ArrayList<JType>(); JType[] types = getSerializableTypes(); int n = types.length; for (int index = 0; index < n; ++index) { JType type = types[index]; if (serializationOracle.maybeInstantiated(type) || deserializationOracle.maybeInstantiated(type)) { filteredTypes.add(type); } } boolean shard = shardSize > 0 && filteredTypes.size() > shardSize; int shardCount = 0; if (shard) { srcWriter.println("(function() {"); } for (JType type : filteredTypes) { if (shard && ++shardCount % shardSize == 0) { srcWriter.println("})();"); srcWriter.println("(function() {"); } String typeString = typeStrings.get(type); assert typeString != null : "Missing type signature for " + type.getQualifiedSourceName(); srcWriter.println("result[\"" + typeString + "\"] = ["); srcWriter.indent(); writeTypeMethodsNative(type); srcWriter.outdent(); srcWriter.indentln("];"); srcWriter.println(); } if (shard) { srcWriter.println("})();"); } srcWriter.println("return result;"); srcWriter.outdent(); srcWriter.println("}-*/;"); srcWriter.println(); }
/** * Writes a method to produce a native map of system hash code to type string. * * <pre> * private static native JsArrayString loadSignaturesNative() /*-{ * var result = []; * result[@com.google.gwt.core.client.impl.Impl::getHashCode(Ljava/lang/Object;)(@java.lang.String::class)] = "java.lang.String/2004016611"; * ... * return result; * }-*/; * </pre> */ private void writeLoadSignaturesNative() { srcWriter.println("@SuppressWarnings(\"deprecation\")"); srcWriter.println("@GwtScriptOnly"); srcWriter.println("private static native JsArrayString loadSignaturesNative() /*-{"); srcWriter.indent(); srcWriter.println("var result = [];"); boolean shard = shardSize > 0 && getSerializableTypes().length > shardSize; int shardCount = 0; if (shard) { srcWriter.println("(function() {"); } for (JType type : getSerializableTypes()) { String typeString = typeStrings.get(type); if (!serializationOracle.maybeInstantiated(type) && !deserializationOracle.maybeInstantiated(type)) { continue; } if (shard && ++shardCount % shardSize == 0) { srcWriter.println("})();"); srcWriter.println("(function() {"); } srcWriter.println( "result[@com.google.gwt.core.client.impl.Impl::getHashCode(Ljava/lang/Object;)(@" + type.getQualifiedSourceName() + "::class)] = \"" + typeString + "\";"); } if (shard) { srcWriter.println("})();"); } srcWriter.println("return result;"); srcWriter.outdent(); srcWriter.println("}-*/;"); srcWriter.println(); }
protected String writeSerializationPolicyFile( TreeLogger logger, GeneratorContextExt ctx, SerializableTypeOracle serializationSto, SerializableTypeOracle deserializationSto) throws UnableToCompleteException { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); OutputStreamWriter osw = new OutputStreamWriter( baos, SerializationPolicyLoader.SERIALIZATION_POLICY_FILE_ENCODING); TypeOracle oracle = ctx.getTypeOracle(); PrintWriter pw = new PrintWriter(osw); JType[] serializableTypes = unionOfTypeArrays( serializationSto.getSerializableTypes(), deserializationSto.getSerializableTypes(), new JType[] {serviceIntf}); for (int i = 0; i < serializableTypes.length; ++i) { JType type = serializableTypes[i]; String binaryTypeName = SerializationUtils.getRpcTypeName(type); pw.print(binaryTypeName); pw.print(", " + Boolean.toString(deserializationSto.isSerializable(type))); pw.print(", " + Boolean.toString(deserializationSto.maybeInstantiated(type))); pw.print(", " + Boolean.toString(serializationSto.isSerializable(type))); pw.print(", " + Boolean.toString(serializationSto.maybeInstantiated(type))); pw.print(", " + typeStrings.get(type)); /* * Include the serialization signature to bump the RPC file name if * obfuscated identifiers are used. */ pw.print(", " + SerializationUtils.getSerializationSignature(oracle, type)); pw.print('\n'); /* * Emit client-side field information for classes that may be enhanced * on the server. Each line consists of a comma-separated list * containing the keyword '@ClientFields', the class name, and a list of * all potentially serializable client-visible fields. */ if ((type instanceof JClassType) && ((JClassType) type).isEnhanced()) { JField[] fields = ((JClassType) type).getFields(); JField[] rpcFields = new JField[fields.length]; int numRpcFields = 0; for (JField f : fields) { if (f.isTransient() || f.isStatic() || f.isFinal()) { continue; } rpcFields[numRpcFields++] = f; } pw.print(SerializationPolicyLoader.CLIENT_FIELDS_KEYWORD); pw.print(','); pw.print(binaryTypeName); for (int idx = 0; idx < numRpcFields; idx++) { pw.print(','); pw.print(rpcFields[idx].getName()); } pw.print('\n'); } } // Closes the wrapped streams. pw.close(); byte[] serializationPolicyFileContents = baos.toByteArray(); String serializationPolicyName = Util.computeStrongName(serializationPolicyFileContents); String serializationPolicyFileName = SerializationPolicyLoader.getSerializationPolicyFileName(serializationPolicyName); OutputStream os = ctx.tryCreateResource(logger, serializationPolicyFileName); if (os != null) { os.write(serializationPolicyFileContents); GeneratedResource resource = ctx.commitResource(logger, os); /* * Record which proxy class created the resource. A manifest will be * emitted by the RpcPolicyManifestLinker. */ emitPolicyFileArtifact(logger, ctx, resource.getPartialPath()); } else { if (logger.isLoggable(TreeLogger.TRACE)) { logger.log( TreeLogger.TRACE, "SerializationPolicy file for RemoteService '" + serviceIntf.getQualifiedSourceName() + "' already exists; no need to rewrite it.", null); } } return serializationPolicyName; } catch (UnsupportedEncodingException e) { logger.log( TreeLogger.ERROR, SerializationPolicyLoader.SERIALIZATION_POLICY_FILE_ENCODING + " is not supported", e); throw new UnableToCompleteException(); } catch (IOException e) { logger.log(TreeLogger.ERROR, null, e); throw new UnableToCompleteException(); } }
/** * Write an entry in the methodMapNative for one type. * * @param type type to generate entry for */ private void writeTypeMethodsNative(JType type) { srcWriter.indent(); String serializerName = SerializationUtils.getFieldSerializerName(typeOracle, type); JClassType customSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer(typeOracle, type); // First the initialization method if (deserializationOracle.maybeInstantiated(type)) { srcWriter.print("@"); if (customSerializer != null) { if (hasInstantiateMethod(customSerializer, type)) { srcWriter.print(serializerName); } else { srcWriter.print(SerializationUtils.getStandardSerializerName((JClassType) type)); } } else { srcWriter.print(serializerName); } srcWriter.print("::instantiate"); srcWriter.print("(L" + SerializationStreamReader.class.getName().replace('.', '/') + ";)"); } srcWriter.println(","); // Now the deserialization method if (deserializationOracle.isSerializable(type)) { // Assume param type is the concrete type of the serialized type. JType paramType = type; if (customSerializer != null) { // But a custom serializer may specify a looser type. JMethod deserializationMethod = CustomFieldSerializerValidator.getDeserializationMethod( customSerializer, (JClassType) type); paramType = deserializationMethod.getParameters()[1].getType(); } srcWriter.print("@" + serializerName); srcWriter.print( "::deserialize(L" + SerializationStreamReader.class.getName().replace('.', '/') + ";" + paramType.getJNISignature() + ")"); } srcWriter.println(","); // Now the serialization method if (serializationOracle.isSerializable(type)) { // Assume param type is the concrete type of the serialized type. JType paramType = type; if (customSerializer != null) { // But a custom serializer may specify a looser type. JMethod serializationMethod = CustomFieldSerializerValidator.getSerializationMethod( customSerializer, (JClassType) type); paramType = serializationMethod.getParameters()[1].getType(); } srcWriter.print("@" + serializerName); srcWriter.print( "::serialize(L" + SerializationStreamWriter.class.getName().replace('.', '/') + ";" + paramType.getJNISignature() + ")"); srcWriter.println(); } srcWriter.outdent(); }