/* * Copyright (C) 2011 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jboss.errai.enterprise.rebind; import java.util.Date; import java.util.Map; import org.jboss.errai.codegen.Parameter; import org.jboss.errai.codegen.Statement; import org.jboss.errai.codegen.TernaryStatement; import org.jboss.errai.codegen.Variable; import org.jboss.errai.codegen.builder.ContextualStatementBuilder; import org.jboss.errai.codegen.meta.MetaClass; import org.jboss.errai.codegen.meta.MetaClassFactory; import org.jboss.errai.codegen.util.Bool; import org.jboss.errai.codegen.util.Stmt; import org.jboss.errai.enterprise.client.jaxrs.MarshallingWrapper; import org.jboss.errai.marshalling.rebind.util.MarshallingGenUtil; /** * Generates the required {@link Statement}s for type marshalling. * * @author Christian Sadilek <csadilek@redhat.com> */ public class TypeMarshaller { public static Statement marshal(final Statement statement) { return marshal(statement, "text/plain"); } public static Statement marshal(final MetaClass type, final Statement statement) { return marshal(type, statement, "text/plain"); } public static Statement marshal(final Statement statement, final String contentType) { if (statement instanceof Parameter) { final Parameter param = (Parameter) statement; return marshal(param.getType(), Variable.get(param.getName()), contentType); } return marshal(statement.getType(), statement, contentType); } public static Statement marshal(final MetaClass type, final Statement statement, final String contentType) { Statement marshallingStatement = null; if (PrimitiveTypeMarshaller.canHandle(type, contentType)) { marshallingStatement = PrimitiveTypeMarshaller.marshal(type, statement); } else { marshallingStatement = Stmt.invokeStatic(MarshallingWrapper.class, "toJSON", statement); } return marshallingStatement; } public static Statement demarshal(final MetaClass type, final Statement statement, final String accepts) { Statement demarshallingStatement = null; if (PrimitiveTypeMarshaller.canHandle(type, accepts)) { demarshallingStatement = PrimitiveTypeMarshaller.demarshal(type, statement); } else { if (!type.equals(MetaClassFactory.get(void.class))) { if (type.isAssignableTo(Map.class)) { demarshallingStatement = Stmt.invokeStatic(MarshallingWrapper.class, "fromJSON", statement, type.asBoxed().asClass(), MarshallingGenUtil.getConcreteMapKeyType(type.asBoxed()), MarshallingGenUtil.getConcreteMapValueType(type.asBoxed())); } else { demarshallingStatement = Stmt.invokeStatic(MarshallingWrapper.class, "fromJSON", statement, type.asBoxed().asClass(), MarshallingGenUtil.getConcreteElementType(type.asBoxed())); } } else { demarshallingStatement = Stmt.invokeStatic(MarshallingWrapper.class, "fromJSON", statement); } } return demarshallingStatement; } /** * Works for all types that have a 'copy constructor', a toString() representation and a valueOf() method (all * primitive wrapper types and java.lang.String). Will only be used in case text/plain was specified as mime type. */ public static class PrimitiveTypeMarshaller { public static boolean canHandle(final MetaClass type, final String mimeType) { boolean canHandle = false; if (("text/plain".equals(mimeType) && type.asUnboxed().isPrimitive()) || type.equals(MetaClassFactory.get(String.class)) || type.equals(MetaClassFactory.get(Date.class)) || type.isEnum()) { canHandle = true; } return canHandle; } private static Statement marshal(final MetaClass type, final Statement statement) { ContextualStatementBuilder s = null; if (type.isPrimitive()) { s = Stmt.nestedCall(Stmt.newObject(type.asBoxed()).withParameters(statement)).invoke("toString"); } else if (type.getFullyQualifiedName().equals(Date.class.getName())) { s = Stmt.nestedCall(new TernaryStatement(Bool.isNull(statement), Stmt.load(""), Stmt.nestedCall(statement).invoke("toGMTString"))); } else { s = Stmt.nestedCall(new TernaryStatement(Bool.isNull(statement), Stmt.load(""), Stmt.nestedCall(statement))); if (!type.equals(MetaClassFactory.get(String.class))) { s = s.invoke("toString"); } } return s; } private static Statement demarshal(final MetaClass type, final Statement statement) { if (type.equals(statement.getType())) { return statement; } if (MetaClassFactory.get(void.class).equals(type)) { return Stmt.load(null); } if (MetaClassFactory.get(Date.class).equals(type)) { return Stmt.newObject(Date.class, statement); } return Stmt.invokeStatic(type.asBoxed(), "valueOf", statement); } } }