@Override
 public MetaType[] getTypeParameters() {
   final List<MetaType> types = new ArrayList<MetaType>();
   for (final JClassType parm : parameterizedType.getTypeArgs()) {
     if (parm.isWildcard() != null) {
       types.add(new GWTWildcardType(oracle, parm.isWildcard()));
     } else if (parm.isTypeParameter() != null) {
       types.add(new GWTTypeVariable(oracle, parm.isTypeParameter()));
     } else if (parm.isClassOrInterface() != null
         || parm.isEnum() != null
         || parm.isPrimitive() != null
         || parm.isRawType() != null
         || parm.isArray() != null
         || parm.isAnnotation() != null) {
       types.add(GWTClass.newInstance(oracle, parm));
     } else {
       throw new IllegalArgumentException(
           "Unsupported kind of type parameter "
               + parm
               + " in type "
               + parameterizedType.getName());
     }
   }
   return types.toArray(new MetaType[types.size()]);
 }
Exemple #2
0
  protected void generateProxyMethods(
      SourceWriter w,
      SerializableTypeOracle serializableTypeOracle,
      TypeOracle typeOracle,
      Map<JMethod, JMethod> syncMethToAsyncMethMap) {
    JMethod[] syncMethods = serviceIntf.getOverridableMethods();
    for (JMethod syncMethod : syncMethods) {

      JMethod asyncMethod = syncMethToAsyncMethMap.get(syncMethod);
      assert (asyncMethod != null);

      JClassType enclosingType = syncMethod.getEnclosingType();
      JParameterizedType isParameterizedType = enclosingType.isParameterized();
      if (isParameterizedType != null) {
        JMethod[] methods = isParameterizedType.getMethods();
        for (int i = 0; i < methods.length; ++i) {
          if (methods[i] == syncMethod) {
            /*
             * Use the generic version of the method to ensure that the server
             * can find the method using the erasure of the generic signature.
             */
            syncMethod = isParameterizedType.getBaseType().getMethods()[i];
          }
        }
      }

      generateProxyMethod(w, serializableTypeOracle, typeOracle, syncMethod, asyncMethod);
    }
  }
Exemple #3
0
  private void addSerializeSupport(TreeLogger logger, JType type) throws UnableToCompleteException {
    hasSerializeSupport.add(type);

    JParameterizedType parametrized = type.isParameterized();
    if (parametrized != null) {
      for (JClassType parameterType : parametrized.getTypeArgs()) {
        setNeedsSerialize(parameterType);
      }
    }

    if (serializationHandledByFramework(type)) {
      return;
    }

    JClassType customSerializer = customSerializers.get(type);
    JClassType typeAsClass = type.isClass();
    JEnumType enumType = type.isEnum();
    JArrayType arrayType = type.isArray();

    if (customSerializer != null) {
      logger.log(Type.INFO, "Will serialize " + type + " using " + customSerializer.getName());
      setSerializer(type, new CustomSerializer(customSerializer));
    } else if (arrayType != null) {
      logger.log(Type.INFO, "Will serialize " + type + " as an array");
      setSerializer(type, new ArraySerializer(arrayType));
      setNeedsSerialize(arrayType.getComponentType());
    } else if (enumType != null) {
      logger.log(Type.INFO, "Will serialize " + type + " as an enum");
      setSerializer(type, new EnumSerializer(enumType));
    } else if (typeAsClass != null) {
      // Bean
      checkSerializable(logger, typeAsClass);

      logger.log(Type.INFO, "Will serialize " + type + " as a bean");

      JClassType needsSuperClass = typeAsClass;
      while (needsSuperClass != null) {
        if (needsSuperClass.isPublic()) {
          setNeedsSuperclass(needsSuperClass);
        }
        needsSuperClass = needsSuperClass.getSuperclass();
      }

      setNeedsGwtConstructor(typeAsClass);

      for (Property property : getProperties(typeAsClass)) {
        setNeedsProperty(property);

        JType propertyType = property.getPropertyType();
        setNeedsSerialize(propertyType);
      }
    }
  }
  private JType resolveType(final JType type) {
    JType ret = type;
    JParameterizedType pt = type.isParameterized();

    if (pt != null) {
      ret = pt.getRawType();
    }

    JTypeParameter tp = ret.isTypeParameter();

    if (tp != null) {
      ret = tp.getBaseType();
    }

    return ret;
  }
  @Override
  public void generate() throws UnableToCompleteException {
    locator = new JsonEncoderDecoderInstanceLocator(context, getLogger());
    generateSingleton(shortName);

    JParameterizedType parameterizedType = source.isParameterized();

    if (parameterizedType == null
        || parameterizedType.getTypeArgs() == null
        || parameterizedType.getTypeArgs().length != 2) {
      getLogger().log(ERROR, "Either types must have exactly two type parameters");
      throw new UnableToCompleteException();
    }

    leftType = parameterizedType.getTypeArgs()[0];
    rightType = parameterizedType.getTypeArgs()[1];

    generateEncodeMethod();
    generateDecodeMethod();
  }
  public String init(
      TypeOracle oracle,
      JField targetWidgetField,
      JType targetType,
      JField targetEntityMember,
      JField targetEntityField,
      String variable,
      List<JField> fields) {
    JClassType widgetCollectionType = targetWidgetField.getType().isClassOrInterface();
    JClassType entityCollectionType = targetEntityMember.getType().isClassOrInterface();

    JParameterizedType paramaterizedType = widgetCollectionType.isParameterized();

    if (paramaterizedType == null) {
      throw new RuntimeException(
          "cannot generateGetField mappers for collection of widgets (the collection is not properly parameterized: eg. List<Widget>)");
    }

    JClassType widgetType = paramaterizedType.getTypeArgs()[0];
    varName =
        targetEntityField.getType().isClassOrInterface().getName()
            + targetWidgetField.getName()
            + "Mapper";

    if (compiledTemplate == null) {
      InputStream istream = this.getClass().getResourceAsStream("CollectionFMGenerator.mv");
      compiledTemplate = TemplateCompiler.compileTemplate(istream, null);
    }

    Map vars = new HashMap();
    vars.put("typeOracle", oracle);
    vars.put("targetWidgetField", targetWidgetField);
    vars.put("targetEntityField", targetEntityField);
    vars.put("targetEntityMember", targetEntityMember);
    vars.put("widgetType", widgetType);
    vars.put("entityCollectionType", entityCollectionType);
    vars.put("widgetCollectionType", widgetCollectionType);
    vars.put("varName", varName);

    return String.valueOf(TemplateRuntime.execute(compiledTemplate, vars));
  }
  /*
   * Create a field serializer for a type if it does not have a custom
   * serializer.
   */
  private void createFieldSerializer(TreeLogger logger, GeneratorContextExt ctx, JType type) {
    Event event = SpeedTracerLogger.start(CompilerEventType.GENERATOR_RPC_FIELD_SERIALIZER);
    try {
      assert (type != null);
      assert (serializationOracle.isSerializable(type)
          || deserializationOracle.isSerializable(type));

      JParameterizedType parameterizedType = type.isParameterized();
      if (parameterizedType != null) {
        createFieldSerializer(logger, ctx, parameterizedType.getRawType());
        return;
      }

      /*
       * Only a JClassType can reach this point in the code. JPrimitives have been
       * removed because their serialization is built in, interfaces have been
       * removed because they are not an instantiable type and parameterized types
       * have been broken down into their raw types.
       */
      assert (type.isClass() != null || type.isArray() != null);

      if (findCacheableFieldSerializerAndMarkForReuseIfAvailable(ctx, type)) {
        // skip generation of field serializer
        return;
      }

      JClassType customFieldSerializer =
          SerializableTypeOracleBuilder.findCustomFieldSerializer(typeOracle, type);
      FieldSerializerCreator creator =
          new FieldSerializerCreator(
              context,
              serializationOracle,
              deserializationOracle,
              (JClassType) type,
              customFieldSerializer);
      creator.realize(logger, ctx);
    } finally {
      event.end();
    }
  }
 @Override
 public String getName() {
   return parameterizedType.getParameterizedQualifiedSourceName();
 }
 @Override
 public MetaType getRawType() {
   return GWTClass.newInstance(oracle, parameterizedType.getRawType());
 }
 @Override
 public MetaType getOwnerType() {
   return GWTClass.newInstance(oracle, parameterizedType.getEnclosingType());
 }
  /** Examines a type to see if it can be transported. */
  private boolean validateTransportableType(
      RequestMethod.Builder methodBuilder, JType type, boolean requireObject)
      throws UnableToCompleteException {
    JClassType transportedClass = type.isClassOrInterface();
    if (transportedClass == null) {
      if (requireObject) {
        poison(
            "The type %s cannot be transported by RequestFactory as" + " a return type",
            type.getQualifiedSourceName());
        return false;
      } else {
        // Primitives always ok
        return true;
      }
    }

    if (ModelUtils.isValueType(oracle, transportedClass)
        || splittableType.equals(transportedClass)) {
      // Simple values, like Integer and String
      methodBuilder.setValueType(true);
    } else if (entityProxyInterface.isAssignableFrom(transportedClass)
        || valueProxyInterface.isAssignableFrom(transportedClass)) {
      // EntityProxy and ValueProxy return types
      methodBuilder.setEntityType(getEntityProxyType(transportedClass));
    } else if (collectionInterface.isAssignableFrom(transportedClass)) {
      // Only allow certain collections for now
      JParameterizedType parameterized = transportedClass.isParameterized();
      if (parameterized == null) {
        poison("Requests that return collections of List or Set must be parameterized");
        return false;
      }
      if (listInterface.equals(parameterized.getBaseType())) {
        methodBuilder.setCollectionType(CollectionType.LIST);
      } else if (setInterface.equals(parameterized.getBaseType())) {
        methodBuilder.setCollectionType(CollectionType.SET);
      } else {
        poison(
            "Requests that return collections may be declared with" + " %s or %s only",
            listInterface.getQualifiedSourceName(), setInterface.getQualifiedSourceName());
        return false;
      }
      // Also record the element type in the method builder
      JClassType elementType =
          ModelUtils.findParameterizationOf(collectionInterface, transportedClass)[0];
      methodBuilder.setCollectionElementType(elementType);
      validateTransportableType(methodBuilder, elementType, requireObject);
    } else if (mapInterface.isAssignableFrom(transportedClass)) {
      JParameterizedType parameterized = transportedClass.isParameterized();
      if (parameterized == null) {
        poison("Requests that return Maps must be parameterized");
        return false;
      }
      if (mapInterface.equals(parameterized.getBaseType())) {
        methodBuilder.setCollectionType(CollectionType.MAP);
      } else {
        poison(
            "Requests that return maps may be declared with" + " %s only",
            mapInterface.getQualifiedSourceName());
        return false;
      }
      // Also record the element type in the method builder
      JClassType[] params = ModelUtils.findParameterizationOf(mapInterface, transportedClass);
      JClassType keyType = params[0];
      JClassType valueType = params[1];
      methodBuilder.setMapKeyType(keyType);
      methodBuilder.setMapValueType(valueType);
      validateTransportableType(methodBuilder, keyType, requireObject);
      validateTransportableType(methodBuilder, valueType, requireObject);
    } else {
      // Unknown type, fail
      poison("Invalid Request parameterization %s", transportedClass.getQualifiedSourceName());
      return false;
    }
    methodBuilder.setDataType(transportedClass);
    return true;
  }
  private String encodeDecodeExpression(
      JType type,
      String expression,
      Style style,
      String encoderMethod,
      String mapMethod,
      String setMethod,
      String listMethod)
      throws UnableToCompleteException {

    if (null != type.isEnum()) {
      if (encoderMethod.equals("encode")) {
        return encodeDecodeExpression(
            STRING_TYPE,
            expression + ".name()",
            style,
            encoderMethod,
            mapMethod,
            setMethod,
            listMethod);
      } else {
        return type.getQualifiedSourceName()
            + ".valueOf("
            + encodeDecodeExpression(
                STRING_TYPE, expression, style, encoderMethod, mapMethod, setMethod, listMethod)
            + ")";
      }
    }

    String encoderDecoder = getEncoderDecoder(type, logger);
    if (encoderDecoder != null) {
      return encoderDecoder + "." + encoderMethod + "(" + expression + ")";
    }

    JClassType clazz = type.isClassOrInterface();

    if (isCollectionType(clazz)) {
      JParameterizedType parameterizedType = type.isParameterized();
      if (parameterizedType == null || parameterizedType.getTypeArgs() == null) {
        error("Collection types must be parameterized.");
      }
      JClassType[] types = parameterizedType.getTypeArgs();

      if (clazz.isAssignableTo(MAP_TYPE)) {
        if (types.length != 2) {
          error("Map must define two and only two type parameters");
        }
        if (types[0] != STRING_TYPE) {
          error("Map's first type parameter must be of type String");
        }
        encoderDecoder = getEncoderDecoder(types[1], logger);
        if (encoderDecoder != null) {
          return mapMethod
              + "("
              + expression
              + ", "
              + encoderDecoder
              + ", "
              + JSON_CLASS
              + ".Style."
              + style.name()
              + ")";
        }
      } else if (clazz.isAssignableTo(SET_TYPE)) {
        if (types.length != 1) {
          error("Set must define one and only one type parameter");
        }
        encoderDecoder = getEncoderDecoder(types[0], logger);
        if (encoderDecoder != null) {
          return setMethod + "(" + expression + ", " + encoderDecoder + ")";
        }
      } else if (clazz.isAssignableTo(LIST_TYPE)) {
        if (types.length != 1) {
          error("List must define one and only one type parameter");
        }
        encoderDecoder = getEncoderDecoder(types[0], logger);
        info("type encoder for: " + types[0] + " is " + encoderDecoder);
        if (encoderDecoder != null) {
          return listMethod + "(" + expression + ", " + encoderDecoder + ")";
        }
      }
    }

    error("Do not know how to encode/decode " + type);
    return null;
  }