private void arrayDemarshallCode( MetaClass toMap, int dim, AnonymousClassStructureBuilder anonBuilder) { Object[] dimParms = new Object[dim]; dimParms[0] = Stmt.loadVariable("a0").invoke("size"); final MetaClass arrayType = toMap.asArrayOf(dim); MetaClass outerType = toMap.getOuterComponentType(); if (!outerType.isArray() && outerType.isPrimitive()) { outerType = outerType.asBoxed(); } Statement outerAccessorStatement = loadVariable("newArray", loadVariable("i")) .assignValue(Cast.to(outerType, loadVariable("a0").invoke("get", loadVariable("i")))); // /** // * Special case for handling char elements. // */ // if (outerType.getFullyQualifiedName().equals(Character.class.getName())) { // outerAccessorStatement = // loadVariable("newArray", loadVariable("i")) // .assignValue( // Stmt.nestedCall(Cast.to(String.class, // loadVariable("a0").invoke("get", loadVariable("i")))) // .invoke("charAt", 0)); // } final BlockBuilder<?> dmBuilder = anonBuilder .privateMethod(arrayType, "_demarshall" + dim) .parameters(List.class, MarshallingSession.class) .body(); dmBuilder.append( Stmt.declareVariable(arrayType) .named("newArray") .initializeWith(Stmt.newArray(toMap, dimParms))); dmBuilder .append( autoForLoop("i", Stmt.loadVariable("newArray").loadField("length")) .append( dim == 1 ? outerAccessorStatement : loadVariable("newArray", loadVariable("i")) .assignValue( Stmt.invokeStatic( anonBuilder.getClassDefinition(), "_demarshall" + (dim - 1), Cast.to( List.class, Stmt.loadVariable("a0") .invoke("get", Stmt.loadVariable("i"))), Stmt.loadVariable("a1")))) .finish()) .append(Stmt.loadVariable("newArray").returnValue()); dmBuilder.finish(); final BlockBuilder<?> mBuilder = anonBuilder .privateMethod(String.class, "_marshall" + dim) .parameters(arrayType, MarshallingSession.class) .body(); mBuilder .append( Stmt.declareVariable(StringBuilder.class) .named("sb") .initializeWith(Stmt.newObject(StringBuilder.class).withParameters("["))) .append( autoForLoop("i", Stmt.loadVariable("a0").loadField("length")) .append( Stmt.if_(Bool.greaterThan(Stmt.loadVariable("i"), 0)) .append(Stmt.loadVariable("sb").invoke("append", ",")) .finish()) .append( Stmt.loadVariable("sb") .invoke( "append", dim == 1 ? Stmt.loadVariable(MarshallingGenUtil.getVarName(outerType)) .invoke( "marshall", Stmt.loadVariable("a0", Stmt.loadVariable("i")), Stmt.loadVariable("a1")) : Stmt.invokeStatic( anonBuilder.getClassDefinition(), "_marshall" + (dim - 1), Stmt.loadVariable("a0", Stmt.loadVariable("i")), loadVariable("a1")))) .finish()) .append(Stmt.loadVariable("sb").invoke("append", "]").invoke("toString").returnValue()) .finish(); if (dim > 1) { arrayDemarshallCode(toMap, dim - 1, anonBuilder); } }
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(); }