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; }
/** * 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; }
@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(); }
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; }
@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(); }
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(); }