Ejemplo n.º 1
0
  public static boolean ensureProviderClass(
      TreeLogger logger,
      String packageName,
      String simpleName0,
      String canonical,
      String qualifiedSourceName,
      GeneratorContext ctx) {
    String simpleName = SourceUtil.toSourceName(simpleName0);
    String generatedName = InjectionUtils.generatedProviderName(simpleName);
    String cleanedCanonical = SourceUtil.toSourceName(canonical);
    logger.log(Type.DEBUG, "Creating provider for " + packageName + "." + generatedName);

    PrintWriter printWriter = ctx.tryCreate(logger, packageName, generatedName);
    if (printWriter == null) {
      logger.log(Type.TRACE, "Already generated " + generatedName);
      return false;
    }
    logger.log(
        Type.TRACE, "Newly Generating provider " + generatedName + " <- " + qualifiedSourceName);

    ClassSourceFileComposerFactory composer =
        new ClassSourceFileComposerFactory(packageName, generatedName);
    composer.setSuperclass(SingletonInitializer.class.getName() + "<" + simpleName0 + ">");
    composer.addImport(cleanedCanonical);
    composer.addImport(GWT.class.getName());
    composer.addImport(SingletonProvider.class.getName());

    SourceWriter sw = composer.createSourceWriter(ctx, printWriter);

    sw.println("@Override");
    sw.println("public " + simpleName + " initialValue(){");
    sw.indent();

    sw.print("return GWT.<" + cleanedCanonical + ">create(");
    sw.print(SourceUtil.toSourceName(qualifiedSourceName) + ".class");
    sw.println(");");

    sw.outdent();
    sw.println("}");
    sw.println();
    // now, print a static final provider instance
    sw.print("public static final SingletonProvider<");
    sw.print(simpleName0 + "> ");
    sw.print("theProvider = ");
    sw.println("new " + generatedName + "();");
    sw.commit(logger);
    return true;
  }
 /**
  * Generate the implementation for a single locale, overriding from its parent only data that has
  * changed in this locale.
  *
  * @param logger
  * @param context
  * @param targetClass
  * @param locale
  * @param superClassName
  * @param currencies the set of currencies defined in this locale
  * @param allCurrencyData map of currency code -> unparsed CurrencyInfo for that code
  * @param defCurrencyCode default currency code for this locale
  * @return fully-qualified class name generated
  */
 private String generateOneLocale(
     TreeLogger logger,
     GeneratorContext context,
     JClassType targetClass,
     GwtLocale locale,
     String superClassName,
     String[] currencies,
     Map<String, CurrencyInfo> allCurrencyData,
     String defCurrencyCode) {
   String packageName = targetClass.getPackage().getName();
   String className = targetClass.getName().replace('.', '_') + "_" + locale.getAsString();
   PrintWriter pw = context.tryCreate(logger, packageName, className);
   if (pw != null) {
     ClassSourceFileComposerFactory factory =
         new ClassSourceFileComposerFactory(packageName, className);
     factory.setSuperclass(superClassName);
     factory.addImport(CURRENCY_DATA);
     factory.addImport(JAVASCRIPTOBJECT);
     factory.addImport(HASHMAP);
     SourceWriter writer = factory.createSourceWriter(context, pw);
     if (defCurrencyCode != null) {
       CurrencyInfo currencyInfo = allCurrencyData.get(defCurrencyCode);
       if (currencyInfo == null) {
         // Synthesize a null info if the specified default wasn't found.
         currencyInfo = new CurrencyInfo(defCurrencyCode, null, null);
         allCurrencyData.put(defCurrencyCode, currencyInfo);
       }
       writer.println();
       writer.println("@Override");
       writer.println("protected CurrencyData getDefaultJava() {");
       writer.println("  return " + currencyInfo.getJava() + ";");
       writer.println("}");
       writer.println();
       writer.println("@Override");
       writer.println("protected native CurrencyData getDefaultNative() /*-{");
       writer.println("  return " + currencyInfo.getJson() + ";");
       writer.println("}-*/;");
     }
     if (currencies.length > 0) {
       writeCurrencyMethodJava(writer, currencies, allCurrencyData);
       writeCurrencyMethodNative(writer, currencies, allCurrencyData);
       writeNamesMethodJava(writer, currencies, allCurrencyData);
       writeNamesMethodNative(writer, currencies, allCurrencyData);
     }
     writer.commit(logger);
   }
   return packageName + "." + className;
 }
  public String realize(TreeLogger logger) {
    logger =
        logger.branch(
            TreeLogger.DEBUG,
            "Generating TypeSerializer for service interface '" + typeSerializerClassName + "'",
            null);

    createFieldSerializers(logger, context);

    int index = 0;
    for (JType type : getSerializableTypes()) {

      String typeString;
      if (elideTypeNames) {
        typeString = Integer.toString(++index, Character.MAX_RADIX);
      } else {
        typeString = getTypeString(type);
      }
      typeStrings.put(type, typeString);
    }

    if (srcWriter != null) {
      writeStaticFields();
      writeStaticInitializer();

      if (context.isProdMode()) {
        writeLoadMethodsNative();
        writeLoadSignaturesNative();
      } else {
        writeLoadMethodsJava();
        writeLoadSignaturesJava();
      }

      writeConstructor();
      srcWriter.commit(logger);
    }

    return typeSerializerClassName;
  }
Ejemplo n.º 4
0
  /**
   * Creates the client-side proxy class.
   *
   * @throws UnableToCompleteException
   */
  public String create(TreeLogger logger, GeneratorContextExt context)
      throws UnableToCompleteException {
    TypeOracle typeOracle = context.getTypeOracle();

    JClassType serviceAsync = typeOracle.findType(serviceIntf.getQualifiedSourceName() + "Async");
    if (serviceAsync == null) {
      logger.branch(
          TreeLogger.ERROR,
          "Could not find an asynchronous version for the service interface "
              + serviceIntf.getQualifiedSourceName(),
          null);
      RemoteServiceAsyncValidator.logValidAsyncInterfaceDeclaration(logger, serviceIntf);
      throw new UnableToCompleteException();
    }

    SourceWriter srcWriter = getSourceWriter(logger, context, serviceAsync);
    if (srcWriter == null) {
      return getProxyQualifiedName();
    }

    // Make sure that the async and synchronous versions of the RemoteService
    // agree with one another
    //
    RemoteServiceAsyncValidator rsav = new RemoteServiceAsyncValidator(logger, typeOracle);
    Map<JMethod, JMethod> syncMethToAsyncMethMap = rsav.validate(logger, serviceIntf, serviceAsync);

    final PropertyOracle propertyOracle = context.getPropertyOracle();

    // Load the blacklist/whitelist
    TypeFilter blacklistTypeFilter = new BlacklistTypeFilter(logger, propertyOracle);

    // Determine the set of serializable types
    Event event = SpeedTracerLogger.start(CompilerEventType.GENERATOR_RPC_STOB);

    SerializableTypeOracleBuilder typesSentFromBrowserBuilder =
        new SerializableTypeOracleBuilder(logger, propertyOracle, context);
    typesSentFromBrowserBuilder.setTypeFilter(blacklistTypeFilter);
    SerializableTypeOracleBuilder typesSentToBrowserBuilder =
        new SerializableTypeOracleBuilder(logger, propertyOracle, context);
    typesSentToBrowserBuilder.setTypeFilter(blacklistTypeFilter);

    addRoots(logger, typeOracle, typesSentFromBrowserBuilder, typesSentToBrowserBuilder);

    try {
      ConfigurationProperty prop =
          context
              .getPropertyOracle()
              .getConfigurationProperty(TypeSerializerCreator.GWT_ELIDE_TYPE_NAMES_FROM_RPC);
      elideTypeNames = Boolean.parseBoolean(prop.getValues().get(0));
    } catch (BadPropertyValueException e) {
      logger.log(
          TreeLogger.ERROR,
          "Configuration property "
              + TypeSerializerCreator.GWT_ELIDE_TYPE_NAMES_FROM_RPC
              + " is not defined. Is RemoteService.gwt.xml inherited?");
      throw new UnableToCompleteException();
    }

    // Decide what types to send in each direction.
    // Log the decisions to a string that will be written later in this method
    SerializableTypeOracle typesSentFromBrowser;
    SerializableTypeOracle typesSentToBrowser;
    String rpcLog;
    {
      StringWriter stringWriter = new StringWriter();
      PrintWriter writer = new PrintWriter(stringWriter);

      typesSentFromBrowserBuilder.setLogOutputWriter(writer);
      typesSentToBrowserBuilder.setLogOutputWriter(writer);

      writer.write("====================================\n");
      writer.write("Types potentially sent from browser:\n");
      writer.write("====================================\n\n");
      writer.flush();
      typesSentFromBrowser = typesSentFromBrowserBuilder.build(logger);

      writer.write("===================================\n");
      writer.write("Types potentially sent from server:\n");
      writer.write("===================================\n\n");
      writer.flush();
      typesSentToBrowser = typesSentToBrowserBuilder.build(logger);

      writer.close();
      rpcLog = stringWriter.toString();
    }
    event.end();

    generateTypeHandlers(logger, context, typesSentFromBrowser, typesSentToBrowser);

    String serializationPolicyStrongName =
        writeSerializationPolicyFile(logger, context, typesSentFromBrowser, typesSentToBrowser);

    String remoteServiceInterfaceName =
        elideTypeNames
            ? TypeNameObfuscator.SERVICE_INTERFACE_ID
            : SerializationUtils.getRpcTypeName(serviceIntf);
    generateProxyFields(
        srcWriter, typesSentFromBrowser, serializationPolicyStrongName, remoteServiceInterfaceName);

    generateProxyContructor(srcWriter);

    generateProxyMethods(srcWriter, typesSentFromBrowser, typeOracle, syncMethToAsyncMethMap);

    generateStreamWriterOverride(srcWriter);

    generateCheckRpcTokenTypeOverride(srcWriter, typeOracle, typesSentFromBrowser);

    srcWriter.commit(logger);

    if (context.isProdMode() || logger.isLoggable(TreeLogger.DEBUG)) {
      // Create an artifact explaining STOB's decisions. It will be emitted by
      // RpcLogLinker
      context.commitArtifact(
          logger,
          new RpcLogArtifact(
              serviceIntf.getQualifiedSourceName(), serializationPolicyStrongName, rpcLog));
    }

    return getProxyQualifiedName();
  }
 /**
  * Generate a class which can select between alternate implementations at runtime based on the
  * runtime locale.
  *
  * @param logger TreeLogger instance for log messages
  * @param context GeneratorContext for generating source files
  * @param targetClass class to generate
  * @param compileLocale the compile-time locale we are generating for
  * @param locales set of all locales to generate
  * @return fully-qualified class name that was generated
  */
 private String generateRuntimeSelection(
     TreeLogger logger,
     GeneratorContext context,
     JClassType targetClass,
     GwtLocale compileLocale,
     Set<GwtLocale> locales) {
   String packageName = targetClass.getPackage().getName();
   String className =
       targetClass.getName().replace('.', '_')
           + "_"
           + compileLocale.getAsString()
           + "_runtimeSelection";
   PrintWriter pw = context.tryCreate(logger, packageName, className);
   if (pw != null) {
     ClassSourceFileComposerFactory factory =
         new ClassSourceFileComposerFactory(packageName, className);
     factory.setSuperclass(targetClass.getQualifiedSourceName());
     factory.addImport(CURRENCY_DATA);
     factory.addImport(JAVASCRIPTOBJECT);
     factory.addImport(HASHMAP);
     factory.addImport("com.google.gwt.i18n.client.LocaleInfo");
     SourceWriter writer = factory.createSourceWriter(context, pw);
     writer.println("private CurrencyList instance;");
     writer.println();
     writer.println("@Override");
     writer.println("protected CurrencyData getDefaultJava() {");
     writer.println("  ensureInstance();");
     writer.println("  return instance.getDefaultJava();");
     writer.println("}");
     writer.println();
     writer.println("@Override");
     writer.println("protected CurrencyData getDefaultNative() {");
     writer.println("  ensureInstance();");
     writer.println("  return instance.getDefaultNative();");
     writer.println("}");
     writer.println();
     writer.println("@Override");
     writer.println("protected HashMap<String, CurrencyData> loadCurrencyMapJava() {");
     writer.println("  ensureInstance();");
     writer.println("  return instance.loadCurrencyMapJava();");
     writer.println("}");
     writer.println();
     writer.println("@Override");
     writer.println("protected JavaScriptObject loadCurrencyMapNative() {");
     writer.println("  ensureInstance();");
     writer.println("  return instance.loadCurrencyMapNative();");
     writer.println("}");
     writer.println();
     writer.println("@Override");
     writer.println("protected HashMap<String, String> loadNamesMapJava() {");
     writer.println("  ensureInstance();");
     writer.println("  return instance.loadNamesMapJava();");
     writer.println("}");
     writer.println();
     writer.println("@Override");
     writer.println("protected JavaScriptObject loadNamesMapNative() {");
     writer.println("  ensureInstance();");
     writer.println("  return instance.loadNamesMapNative();");
     writer.println("}");
     writer.println();
     writer.println("private void ensureInstance() {");
     writer.indent();
     writer.println("if (instance != null) {");
     writer.println("  return;");
     writer.println("}");
     boolean fetchedLocale = false;
     Map<String, Set<GwtLocale>> localeMap = new TreeMap<String, Set<GwtLocale>>();
     String compileLocaleClass =
         processChildLocale(logger, context, targetClass, localeMap, compileLocale);
     if (compileLocaleClass == null) {
       // already gave warning, just use default implementation
       return null;
     }
     for (GwtLocale runtimeLocale : locales) {
       processChildLocale(logger, context, targetClass, localeMap, runtimeLocale);
     }
     for (Entry<String, Set<GwtLocale>> entry : localeMap.entrySet()) {
       if (!fetchedLocale) {
         writer.println("String runtimeLocale = LocaleInfo.getCurrentLocale().getLocaleName();");
         fetchedLocale = true;
       }
       boolean firstLocale = true;
       String generatedClass = entry.getKey();
       if (compileLocaleClass.equals(generatedClass)) {
         // The catch-all will handle this
         continue;
       }
       writer.print("if (");
       for (GwtLocale locale : entry.getValue()) {
         if (firstLocale) {
           firstLocale = false;
         } else {
           writer.println();
           writer.print("    || ");
         }
         writer.print("\"" + locale.toString() + "\".equals(runtimeLocale)");
       }
       writer.println(") {");
       writer.println("  instance = new " + generatedClass + "();");
       writer.println("  return;");
       writer.println("}");
     }
     writer.println("instance = new " + compileLocaleClass + "();");
     writer.outdent();
     writer.println("}");
     writer.commit(logger);
   }
   return packageName + "." + className;
 }
Ejemplo n.º 6
0
  @Override
  public String generate(TreeLogger logger, GeneratorContext context, String typeName)
      throws UnableToCompleteException {
    // make sure it is an interface
    TypeOracle oracle = context.getTypeOracle();

    propertyAccessInterface = oracle.findType(Name.getSourceNameForClass(PropertyAccess.class));
    modelKeyProviderInterface = oracle.findType(Name.getSourceNameForClass(ModelKeyProvider.class));
    valueProviderInterface = oracle.findType(Name.getSourceNameForClass(ValueProvider.class));
    labelProviderInterface = oracle.findType(Name.getSourceNameForClass(LabelProvider.class));
    JClassType toGenerate = oracle.findType(typeName).isInterface();
    if (toGenerate == null) {
      logger.log(TreeLogger.ERROR, typeName + " is not an interface type");
      throw new UnableToCompleteException();
    }
    if (!toGenerate.isAssignableTo(propertyAccessInterface)) {
      logger.log(Type.ERROR, "This isn't a PropertyAccess subtype...");
      throw new UnableToCompleteException();
    }

    // Get the name of the new type
    String packageName = toGenerate.getPackage().getName();
    String simpleSourceName = toGenerate.getName().replace('.', '_') + "Impl";
    PrintWriter pw = context.tryCreate(logger, packageName, simpleSourceName);
    if (pw == null) {
      return packageName + "." + simpleSourceName;
    }

    // start making the class, with basic imports
    ClassSourceFileComposerFactory factory =
        new ClassSourceFileComposerFactory(packageName, simpleSourceName);
    factory.addImplementedInterface(typeName);
    SourceWriter sw = factory.createSourceWriter(context, pw);

    // for each method,
    for (JMethod m : toGenerate.getOverridableMethods()) {
      TreeLogger l = logger.branch(Type.DEBUG, "Building method: " + m.getReadableDeclaration());

      // no support for params at this time
      if (m.getParameters().length != 0) {
        l.log(Type.ERROR, "Method " + m.toString() + " must not have parameters.");
        throw new UnableToCompleteException();
      }

      // ask for the types that provide the property data
      JClassType ret = m.getReturnType().isClassOrInterface();
      final AbstractCreator c;
      if (ret.isAssignableTo(valueProviderInterface)) {
        c = new ValueProviderCreator(context, l, m);
      } else if (ret.isAssignableTo(modelKeyProviderInterface)) {
        c = new ModelKeyProviderCreator(context, l, m);
      } else if (ret.isAssignableTo(labelProviderInterface)) {
        c = new LabelProviderCreator(context, l, m);
      } else {
        logger.log(Type.ERROR, "Method uses a return type that cannot be generated");
        throw new UnableToCompleteException();
      }
      c.create();
      // build the method
      // public ValueProvider<T, V> name() { return NameValueProvider.instance;
      // }
      sw.println("public %1$s %2$s() {", m.getReturnType().getQualifiedSourceName(), m.getName());
      sw.indentln("return %1$s;", c.getInstanceExpression());
      sw.println("}");
    }

    sw.commit(logger);

    return factory.getCreatedClassName();
  }
Ejemplo n.º 7
0
  public static InjectionCallbackArtifact ensureAsyncInjected(
      TreeLogger logger,
      String packageName,
      String className,
      String outputClass,
      GeneratorContext ctx)
      throws UnableToCompleteException {

    GwtInjectionMap gwtInjectionMap = getInjectionMap(logger, ctx);
    InjectionCallbackArtifact artifact =
        gwtInjectionMap.getOrCreateArtifact(ctx, packageName, className);
    if (artifact.isTargetUnbound()) {
      artifact.bindTo(outputClass);
      ensureProviderClass(
          logger,
          packageName,
          artifact.getSimpleName(),
          artifact.getCanonicalName(),
          artifact.getBoundTarget(),
          ctx);
      logger =
          logger.branch(
              Type.TRACE,
              "Creating asynchronous callback for "
                  + artifact.getCanonicalName()
                  + " -> "
                  + outputClass);
      String generatedName = InjectionUtils.generatedAsyncProviderName(artifact.getGeneratedName());
      String implPackage = artifact.getImplementationPackage();
      PrintWriter printWriter = ctx.tryCreate(logger, implPackage, generatedName);
      if (printWriter == null) {
        logger.log(
            Type.WARN,
            "Could not create the source writer for " + implPackage + "." + generatedName);
        return artifact;
      }
      artifact.addCallback(implPackage + "." + generatedName + ".Deproxy");
      ctx.commitArtifact(logger, artifact);

      ClassSourceFileComposerFactory composer =
          new ClassSourceFileComposerFactory(implPackage, generatedName);
      composer.setPrivacy("public final");

      composer.addImport(com.google.gwt.core.client.GWT.class.getName());
      composer.addImport(RunAsyncCallback.class.getName());
      composer.addImport(Fifo.class.getName());
      composer.addImport(JsFifo.class.getName());
      composer.addImport(AsyncProxy.class.getName());
      composer.addImport(ApplyMethod.class.getName());
      composer.addImport(ReceivesValue.class.getName());
      composer.addImport(ReceiverAdapter.class.getCanonicalName());
      composer.addImport(artifact.getCanonicalName());

      String simpleName = artifact.getSimpleName();
      SourceWriter sw = composer.createSourceWriter(ctx, printWriter);

      sw.println();
      sw.println("static final class Callbacks implements ApplyMethod{");
      sw.indent();
      sw.println("public void apply(Object ... args){");
      sw.println("}");
      sw.outdent();
      sw.println("}");
      sw.println();

      sw.println("static final class Deproxy implements ReceivesValue<" + simpleName + ">{");
      sw.indent();
      sw.println("public final void set(final " + simpleName + " value){");
      sw.indentln("getter = new ReceiverAdapter<" + simpleName + ">(value);");
      sw.println("}");
      sw.outdent();
      sw.println("}");
      sw.println();

      sw.println(
          "private static final class Proxy implements ReceivesValue<ReceivesValue<"
              + simpleName
              + ">>{");
      sw.indent();
      sw.println("public final void set(final ReceivesValue<" + simpleName + "> receiver){");
      sw.indent();

      sw.print("GWT.runAsync(");
      sw.println(artifact.getCanonicalName() + ".class,new Request(receiver));");

      sw.outdent();
      sw.println("}");
      sw.outdent();
      sw.println("}");
      sw.println();

      sw.println("private static final class Request");
      sw.indent();
      sw.println("extends AsyncProxy<" + simpleName + "> ");
      sw.println("implements RunAsyncCallback{");

      DefermentWriter defer = new DefermentWriter(sw);
      defer.setStrategy(DefermentStrategy.NONE);

      sw.println("private static final Fifo<ReceivesValue<" + simpleName + ">> pending =");
      sw.indentln("JsFifo.newFifo();");
      sw.println();

      sw.println("protected Request(ReceivesValue<" + simpleName + "> receiver){");
      sw.indentln("accept(receiver);");
      sw.println("}");
      sw.println();

      sw.println("@Override");
      sw.println("protected final Fifo<ReceivesValue<" + simpleName + ">> pending(){");
      sw.indentln("return pending;");
      sw.println("}");
      sw.println();

      sw.println("protected final void dispatch(){");
      sw.indentln("go();");
      sw.println("}");
      sw.println();

      sw.println("public final void onSuccess(){");
      sw.indent();
      defer.printStart();

      sw.println("final " + simpleName + " value = ");
      sw.print(packageName + "." + InjectionUtils.generatedProviderName(simpleName));
      sw.println(".theProvider.get();");
      sw.println();

      sw.print("final ApplyMethod callbacks = GWT.create(");
      sw.print(packageName + ".impl." + generatedName + ".Callbacks.class");
      sw.println(");");
      sw.println("callbacks.apply(value);");
      sw.println();

      sw.println("apply(value);");
      sw.outdent();
      sw.println("}");
      sw.outdent();
      defer.printFinish();
      sw.println("}");
      sw.println();

      sw.println(
          "private static ReceivesValue<ReceivesValue<" + simpleName + ">> getter = new Proxy();");
      sw.println();

      sw.println("static void request(final ReceivesValue<" + simpleName + "> request){");
      sw.indentln("getter.set(request);");
      sw.println("}");
      sw.println();

      sw.println("static void go(){");
      sw.indentln("request(null);");
      sw.println("}");
      sw.println();

      sw.println("private " + generatedName + "(){}");

      sw.commit(logger);

    } else {
      assert artifact.getBoundTarget().equals(outputClass)
          : "The injection target "
              + artifact.getCanonicalName()
              + " was bound "
              + "to "
              + artifact.getBoundTarget()
              + ", but you tried to bind it again, "
              + "to a different class: "
              + outputClass;
    }
    return artifact;
  }
Ejemplo n.º 8
0
  @Override
  public String generate(TreeLogger logger, GeneratorContext context, String typeName)
      throws UnableToCompleteException {
    TypeOracle oracle = context.getTypeOracle();

    // JClassType requestQueue = oracle.findType(RequestQueue.class.getName());
    JClassType toGenerate = oracle.findType(typeName);

    if (toGenerate == null) {
      logger.log(TreeLogger.ERROR, typeName + " is not an interface type");
      throw new UnableToCompleteException();
    }

    String packageName = toGenerate.getPackage().getName();
    String simpleSourceName = toGenerate.getName().replace('.', '_') + "_Impl";
    PrintWriter pw = context.tryCreate(logger, packageName, simpleSourceName);
    if (pw == null) {
      return packageName + "." + simpleSourceName;
    }

    ClassSourceFileComposerFactory factory =
        new ClassSourceFileComposerFactory(packageName, simpleSourceName);
    factory.setSuperclass(AbstractRequestQueueImpl.class.getName());
    factory.addImplementedInterface(typeName);
    SourceWriter sw = factory.createSourceWriter(context, pw);

    // Collect async services we need to provide access to, and the rpc calls they'll make
    RequestQueueModel model =
        collectModel(logger.branch(Type.DEBUG, "Collecting service info"), context, toGenerate);

    // Build a pair of RPC interfaces for serialization
    String realRpcInterfaceName =
        buildRpcInterfaces(logger.branch(Type.DEBUG, "Writing RPC interfaces"), context, model);

    // Build the getRealService() method
    String serviceQueueAsync = ServiceQueueBaseAsync.class.getName();
    sw.println("public %1$s getRealService() {", serviceQueueAsync);
    sw.indentln(
        "return %3$s.<%1$s>create(%2$s.class);",
        serviceQueueAsync, realRpcInterfaceName, GWT.class.getName());
    sw.println("}");

    // Build the methods (and maybe types?) that call addRequest()
    for (AsyncServiceModel service : model.getServices()) {
      sw.println(
          "public %1$s %2$s() {",
          service.getAsyncServiceInterfaceName(), service.getDeclaredMethodName());
      sw.indent();

      sw.println("return new %1$s() {", service.getAsyncServiceInterfaceName());
      sw.indent();

      for (AsyncServiceMethodModel method : service.getMethods()) {
        sw.println("public void %1$s(", method.getMethodName());
        StringBuilder argList = new StringBuilder();
        StringBuilder types = new StringBuilder("new String[]{");
        for (int i = 0; i < method.getArgTypes().size(); i++) {
          if (i != 0) {
            sw.print(", ");
            argList.append(", ");
            types.append(", ");
          }
          JType arg = method.getArgTypes().get(i);

          sw.print("%1$s arg%2$d", arg.getParameterizedQualifiedSourceName(), i);
          argList.append("arg").append(i);
          types.append("\"").append(escape(SerializationUtils.getRpcTypeName(arg))).append("\"");
        }
        types.append("}");
        if (method.hasCallback()) {
          if (method.getArgTypes().size() != 0) {
            sw.print(", ");
          }
          sw.print(
              "%1$s<%2$s> callback", AsyncCallback.class.getName(), method.getReturnTypeName());
        }
        sw.println(") {");
        sw.indent();

        sw.println(
            "addRequest(\"%1$s\", \"%2$s\",\n%3$s,\n",
            escape(service.getServiceName()), escape(method.getMethodName()), types.toString());
        if (method.hasCallback()) {
          sw.indentln("callback,");
        } else {
          sw.indentln("null,");
        }
        sw.indentln("new Object[]{%1$s});", argList.toString());

        sw.outdent();
        sw.println("}");
      }

      sw.outdent();
      sw.println("};");

      sw.outdent();
      sw.println("}");
    }

    sw.commit(logger);

    return factory.getCreatedClassName();
  }
Ejemplo n.º 9
0
  private String buildRpcInterfaces(
      TreeLogger logger, GeneratorContext context, RequestQueueModel model) {
    String rqType = model.getRequestQueueInterfaceName();
    int lastDot = rqType.lastIndexOf('.');
    String packageName = rqType.substring(0, lastDot - 1);
    String serviceSourceName = rqType.substring(lastDot).replace('.', '_') + "_ImplRPC";
    String asyncSourceName = serviceSourceName + "Async";
    PrintWriter pw = context.tryCreate(logger, packageName, asyncSourceName);
    if (pw == null) {
      return packageName + "." + serviceSourceName;
    }

    // Create async class
    ClassSourceFileComposerFactory factory =
        new ClassSourceFileComposerFactory(packageName, asyncSourceName);
    factory.addImplementedInterface(ServiceQueueBaseAsync.class.getName());
    factory.makeInterface();
    SourceWriter asyncSw = factory.createSourceWriter(context, pw);

    // Create service class
    pw = context.tryCreate(logger, packageName, serviceSourceName);
    assert pw != null;
    factory = new ClassSourceFileComposerFactory(packageName, serviceSourceName);
    factory.addImplementedInterface(ServiceQueueBase.class.getName());
    factory.makeInterface();
    SourceWriter serviceSw = factory.createSourceWriter(context, pw);

    // write out service and async
    int i = 0;
    for (AsyncServiceModel service : model.getServices()) {
      for (AsyncServiceMethodModel method : service.getMethods()) {
        String methodName = "a" + ++i;
        asyncSw.println("void %1$s(", methodName);
        serviceSw.println("%2$s %1$s(", methodName, method.getReturnTypeName());
        asyncSw.indent();
        serviceSw.indent();

        boolean firstArgument = true;
        int argIndex = 0;
        for (JType arg : method.getArgTypes()) {
          if (!firstArgument) {
            asyncSw.println(",");
            serviceSw.println(",");
          }
          firstArgument = false;

          if (arg.isPrimitive() != null) {
            JPrimitiveType t = arg.isPrimitive();
            asyncSw.println("%2$s arg%1$d", argIndex, t.getQualifiedBoxedSourceName());
            serviceSw.println("%2$s arg%1$d", argIndex, t.getQualifiedBoxedSourceName());
          } else {
            asyncSw.println("%2$s arg%1$d", argIndex, arg.getParameterizedQualifiedSourceName());
            serviceSw.println("%2$s arg%1$d", argIndex, arg.getParameterizedQualifiedSourceName());
          }

          argIndex++;
        }
        if (!firstArgument) {
          asyncSw.print(", ");
        }
        // TODO return type boxing
        asyncSw.println(
            "%1$s<%2$s>callback);", AsyncCallback.class.getName(), method.getReturnTypeName());
        serviceSw.print(")");
        if (!method.getThrowables().isEmpty()) {
          serviceSw.print(" throws ");
          boolean firstThrowable = true;
          for (JClassType throwable : method.getThrowables()) {
            if (!firstThrowable) {
              serviceSw.print(", ");
            }
            firstThrowable = false;
            serviceSw.print(throwable.getQualifiedSourceName());
          }
        }
        serviceSw.println(";");
        asyncSw.outdent();
        serviceSw.outdent();
      }
    }

    asyncSw.commit(logger);
    serviceSw.commit(logger);

    return factory.getCreatedClassName();
  }