private void loadMarshallers() { Set<Class<?>> marshallers = ScannerSingleton.getOrCreateInstance().getTypesAnnotatedWith(ClientMarshaller.class); for (Class<?> cls : marshallers) { if (Marshaller.class.isAssignableFrom(cls)) { try { Class<?> type = (Class<?>) Marshaller.class.getMethod("getTypeHandled").invoke(cls.newInstance()); mappingContext.registerMarshaller(type.getName(), cls.asSubclass(Marshaller.class)); if (cls.isAnnotationPresent(ImplementationAliases.class)) { for (Class<?> c : cls.getAnnotation(ImplementationAliases.class).value()) { mappingContext.registerMappingAlias(c, type); } } } catch (Throwable t) { throw new RuntimeException("could not instantiate marshaller class: " + cls.getName(), t); } } else { throw new RuntimeException( "class annotated with " + ClientMarshaller.class.getCanonicalName() + " does not implement " + Marshaller.class.getName()); } } }
private String _generate(String packageName, String clazzName) { startTime = System.currentTimeMillis(); classStructureBuilder = implement(MarshallerFactory.class, packageName, clazzName); classContext = ((BuildMetaClass) classStructureBuilder.getClassDefinition()).getContext(); mappingContext = new MappingContext( classContext, classStructureBuilder.getClassDefinition(), classStructureBuilder, new ArrayMarshallerCallback() { @Override public Statement marshal(MetaClass type, Statement value) { createDemarshallerIfNeeded(type); return value; } @Override public Statement demarshall(MetaClass type, Statement value) { String variable = createDemarshallerIfNeeded(type); value = Stmt.loadVariable(getVarName(List.class)) .invoke("demarshall", value, Stmt.loadVariable("a1")); return Stmt.loadVariable(variable) .invoke("demarshall", value, Stmt.loadVariable("a1")); } private String createDemarshallerIfNeeded(MetaClass type) { return addArrayMarshaller(type); } }); loadMarshallers(); MetaClass javaUtilMap = MetaClassFactory.get(new TypeLiteral<Map<String, Marshaller>>() {}); autoInitializedField(classStructureBuilder, javaUtilMap, MARSHALLERS_VAR, HashMap.class); constructor = classStructureBuilder.publicConstructor(); for (Map.Entry<String, Class<? extends Marshaller>> entry : mappingContext.getAllMarshallers().entrySet()) { String varName = getVarName(entry.getKey()); String arrayVarName = getArrayVarName(entry.getKey()); classStructureBuilder.privateField(varName, entry.getValue()).finish(); classStructureBuilder.privateField(arrayVarName, entry.getValue()).finish(); constructor.append( Stmt.create(classContext) .loadVariable(varName) .assignValue(Stmt.newObject(entry.getValue()))); constructor.append( Stmt.create(classContext) .loadVariable(MARSHALLERS_VAR) .invoke("put", entry.getKey(), loadVariable(varName))); for (String s : mappingContext.getReverseMappingAliasFor(entry.getKey())) { constructor.append( Stmt.create(classContext) .loadVariable(MARSHALLERS_VAR) .invoke("put", s, loadVariable(varName))); } } generateMarshallers(); classStructureBuilder .publicMethod(Marshaller.class, "getMarshaller") .parameters(String.class, String.class) .body() .append(loadVariable(MARSHALLERS_VAR).invoke("get", loadVariable("a1")).returnValue()) .finish(); // special support for Object[] addArrayMarshaller(MetaClassFactory.get(Object[].class)); return classStructureBuilder.toJavaString(); // System.out.println("[Generation Finished in: " + (System.currentTimeMillis() - startTime) + // "ms]"); // System.out.println(generatedClass); // return generatedClass; }
private Statement generateArrayMarshaller(MetaClass arrayType) { MetaClass toMap = arrayType; while (toMap.isArray()) { toMap = toMap.getComponentType(); } int dimensions = GenUtil.getArrayDimensions(arrayType); AnonymousClassStructureBuilder classStructureBuilder = Stmt.create(mappingContext.getCodegenContext()) .newObject(parameterizedAs(Marshaller.class, typeParametersOf(List.class, arrayType))) .extend(); MetaClass anonClass = classStructureBuilder.getClassDefinition(); classStructureBuilder .publicOverridesMethod("getTypeHandled") .append(Stmt.load(toMap).returnValue()) .finish(); classStructureBuilder .publicOverridesMethod("getEncodingType") .append(Stmt.load("json").returnValue()) .finish(); BlockBuilder<?> bBuilder = classStructureBuilder.publicOverridesMethod( "demarshall", Parameter.of(Object.class, "a0"), Parameter.of(MarshallingSession.class, "a1")); bBuilder.append( Stmt.if_(Bool.isNull(loadVariable("a0"))) .append(Stmt.load(null).returnValue()) .finish() .else_() .append( Stmt.invokeStatic( anonClass, "_demarshall" + dimensions, loadVariable("a0"), loadVariable("a1")) .returnValue()) .finish()); bBuilder.finish(); arrayDemarshallCode(toMap, dimensions, classStructureBuilder); BlockBuilder<?> marshallMethodBlock = classStructureBuilder.publicOverridesMethod( "marshall", Parameter.of(Object.class, "a0"), Parameter.of(MarshallingSession.class, "a1")); marshallMethodBlock.append( Stmt.if_(Bool.isNull(loadVariable("a0"))) .append(Stmt.load(null).returnValue()) .finish() .else_() .append( Stmt.invokeStatic( anonClass, "_marshall" + dimensions, loadVariable("a0"), loadVariable("a1")) .returnValue()) .finish()); classStructureBuilder .publicOverridesMethod("handles", Parameter.of(JSONValue.class, "a0")) .append(Stmt.load(true).returnValue()) .finish(); marshallMethodBlock.finish(); return classStructureBuilder.finish(); }
private void generateMarshallers() { MetaDataScanner scanner = ScannerSingleton.getOrCreateInstance(); Set<Class<?>> exposed = new HashSet<Class<?>>(scanner.getTypesAnnotatedWith(Portable.class)); exposed.addAll(scanner.getTypesAnnotatedWith(ExposeEntity.class)); // add all GWT JRE classes exposed.add(Throwable.class); exposed.add(NullPointerException.class); exposed.add(RuntimeException.class); exposed.add(Exception.class); exposed.add(ArithmeticException.class); exposed.add(ArrayStoreException.class); exposed.add(AssertionError.class); exposed.add(ClassCastException.class); exposed.add(IllegalArgumentException.class); exposed.add(IndexOutOfBoundsException.class); exposed.add(NegativeArraySizeException.class); exposed.add(NumberFormatException.class); exposed.add(StringIndexOutOfBoundsException.class); exposed.add(UnsupportedOperationException.class); exposed.add(StackTraceElement.class); exposed.add(IOException.class); exposed.add(UnsupportedEncodingException.class); exposed.add(ConcurrentModificationException.class); exposed.add(EmptyStackException.class); // exposed.add(MissingResourceException.class); // exposed.add(NoSuchMethodException.class); for (Class<?> clazz : exposed) { mappingContext.registerGeneratedMarshaller(clazz.getName()); } for (Class<?> clazz : exposed) { if (clazz.isEnum()) continue; MetaClass metaClazz = MetaClassFactory.get(clazz); Statement marshaller = marshal(metaClazz); MetaClass type = marshaller.getType(); String varName = getVarName(clazz); classStructureBuilder.privateField(varName, type).finish(); constructor.append(loadVariable(varName).assignValue(marshaller)); constructor.append( Stmt.create(classContext) .loadVariable(MARSHALLERS_VAR) .invoke("put", clazz.getName(), loadVariable(varName))); for (String s : mappingContext.getReverseMappingAliasFor(clazz.getName())) { constructor.append( Stmt.create(classContext) .loadVariable(MARSHALLERS_VAR) .invoke("put", s, loadVariable(varName))); } } constructor.finish(); }