/** * Writes a loadNamesMapNative method for the current locale, based on its the supplied names map * and its superclass (if any). * * <p>If no new names are added for this locale over its superclass, the method is omitted * entirely. * * @param writer SourceWriter instance to use for writing the class * @param currencies array of valid currency names in the order they should be listed * @param allCurrencyData map of currency codes to currency data for the current locale, including * all inherited currencies data */ private void writeNamesMethodNative( SourceWriter writer, String[] currencies, Map<String, CurrencyInfo> allCurrencyData) { boolean needHeader = true; for (String currencyCode : currencies) { // TODO(jat): only emit new data where it differs from superclass! CurrencyInfo currencyInfo = allCurrencyData.get(currencyCode); String displayName = currencyInfo.getDisplayName(); if (displayName != null && !currencyCode.equals(displayName)) { if (needHeader) { needHeader = false; writer.println(); writer.println("@Override"); writer.println("protected JavaScriptObject loadNamesMapNative() {"); writer.indent(); writer.println( "return overrideMap(super.loadNamesMapNative(), loadMyNamesMapOverridesNative());"); writer.outdent(); writer.println("}"); writer.println(); writer.println("private native JavaScriptObject loadMyNamesMapOverridesNative() /*-{"); writer.indent(); writer.println("return {"); writer.indent(); } writer.println("\"" + quote(currencyCode) + "\": \"" + quote(displayName) + "\","); } } if (!needHeader) { writer.outdent(); writer.println("};"); writer.outdent(); writer.println("}-*/;"); } }
protected void generateCheckRpcTokenTypeOverride( SourceWriter srcWriter, TypeOracle typeOracle, SerializableTypeOracle typesSentFromBrowser) { JClassType rpcTokenType = typeOracle.findType(RpcToken.class.getName()); JClassType[] rpcTokenSubtypes = rpcTokenType.getSubtypes(); String rpcTokenImplementation = ""; for (JClassType rpcTokenSubtype : rpcTokenSubtypes) { if (typesSentFromBrowser.isSerializable(rpcTokenSubtype)) { if (rpcTokenImplementation.length() > 0) { // >1 implematation of RpcToken, bail rpcTokenImplementation = ""; break; } else { rpcTokenImplementation = rpcTokenSubtype.getQualifiedSourceName(); } } } if (rpcTokenImplementation.length() > 0) { srcWriter.println("@Override"); srcWriter.println("protected void checkRpcTokenType(RpcToken token) {"); srcWriter.indent(); srcWriter.println("if (!(token instanceof " + rpcTokenImplementation + ")) {"); srcWriter.indent(); srcWriter.println( "throw new RpcTokenException(\"Invalid RpcToken type: " + "expected '" + rpcTokenImplementation + "' but got '\" + " + "token.getClass() + \"'\");"); srcWriter.outdent(); srcWriter.println("}"); srcWriter.outdent(); srcWriter.println("}"); } }
private void writeMethod(TreeLogger logger, MethodWrapper method, SourceWriter writer) { JType ptype = this.resolveType(method.getDeclaringType()); writer.println("new Method(){ "); writer.indent(); writer.println("public String getName() {"); writer.indentln("return \"" + method.getBaseMethod().getName() + "\";"); writer.println(" }"); writer.println("public Object invoke( Object target, Object[] args ) throws Exception {"); writer.indent(); writer.println(ptype.getQualifiedSourceName() + " casted ="); writer.println("(" + ptype.getQualifiedSourceName() + ") target;"); logger.log( TreeLogger.SPAM, "Method: " + method.getBaseMethod().getName() + " " + method.getBaseMethod().getReturnType().getQualifiedSourceName(), null); if (!(method.getBaseMethod().getReturnType().isPrimitive() == JPrimitiveType.VOID)) { writer.print("return "); } JType type = this.resolveType(method.getBaseMethod().getReturnType()); boolean boxed = this.box(type, writer); writer.print("casted." + method.getBaseMethod().getName() + "("); if (method.getBaseMethod().getParameters() != null) { for (int j = 0; j < method.getBaseMethod().getParameters().length; j++) { JType arg = this.resolveType(method.getBaseMethod().getParameters()[j].getType()); this.unbox(arg, "args[" + j + "]", writer); if (j != (method.getBaseMethod().getParameters().length - 1)) { writer.print(", "); } } } writer.print(")"); if (boxed) { writer.print(")"); } writer.println(";"); if (method.getBaseMethod().getReturnType().getQualifiedSourceName().equals("void")) { writer.println("return null;"); } writer.outdent(); writer.println("}"); writer.outdent(); writer.println("};"); }
/** Writes the UiCommonListenerMap for the edited model */ private void writeListenerMap() { logger.log(Type.DEBUG, "Starting to write ListenerMap"); // $NON-NLS-1$ sw.println(); sw.println("@Override"); // $NON-NLS-1$ sw.println( "protected " + UiCommonListenerMap.class.getName() + " getListenerMap() {"); //$NON-NLS-1$ //$NON-NLS-2$ sw.indent(); sw.println( UiCommonListenerMap.class.getName() + " listenerMap = new " + UiCommonListenerMap.class.getName() // $NON-NLS-1$ + "();"); //$NON-NLS-1$ sw.println(); logger.log(Type.DEBUG, "Looking for top-level Editor Fields"); // $NON-NLS-1$ for (EditorData editorData : model.getEditorData()) { logger.log(Type.DEBUG, "Going over Field: " + editorData); // $NON-NLS-1$ String path = editorData.getPath(); // Change first letter to Upper to comply with UiCommon Property Names path = Character.toUpperCase(path.charAt(0)) + path.substring(1, path.length()); if (path.length() == 0) { continue; } // only relevant for top-level properties if (!editorData.isDeclaredPathNested()) { logger.log(Type.DEBUG, "Found top-level Field: " + editorData); // $NON-NLS-1$ sw.println( "listenerMap.addListener(\"%s\", \"PropertyChanged\", new org.ovirt.engine.ui.uicompat.IEventListener() {", //$NON-NLS-1$ path); sw.indent(); sw.println("@Override"); // $NON-NLS-1$ sw.println( "public void eventRaised(org.ovirt.engine.ui.uicompat.Event ev, Object sender, org.ovirt.engine.ui.uicompat.EventArgs args) {"); //$NON-NLS-1$ sw.indent(); sw.println( "getEditor().%s.setValue(getObject()%s);", //$NON-NLS-1$ editorData.getExpression(), editorData.getGetterExpression()); sw.outdent(); sw.println("}"); // $NON-NLS-1$ sw.outdent(); sw.println("});"); // $NON-NLS-1$ sw.println(); } } sw.println("return listenerMap;"); // $NON-NLS-1$ sw.outdent(); sw.println("}"); // $NON-NLS-1$ }
/** * Writes a method to produce a native map of type string -> handler funcs. * * <pre> * private static native MethodMap loadMethodsNative() /*-{ * var result = {}; * result["java.lang.String/2004016611"] = [ * @com.google.gwt.user.client.rpc.core.java.lang.String_CustomFieldSerializer::instantiate(Lcom/google/gwt/user/client/rpc/SerializationStreamReader;), * @com.google.gwt.user.client.rpc.core.java.lang.String_CustomFieldSerializer::deserialize(Lcom/google/gwt/user/client/rpc/SerializationStreamReader;Ljava/lang/String;), * @com.google.gwt.user.client.rpc.core.java.lang.String_CustomFieldSerializer::serialize(Lcom/google/gwt/user/client/rpc/SerializationStreamWriter;Ljava/lang/String;) * ]; * ... * return result; * }-*/; * </pre> */ private void writeLoadMethodsNative() { srcWriter.println("@SuppressWarnings(\"deprecation\")"); srcWriter.println("@GwtScriptOnly"); srcWriter.println("private static native MethodMap loadMethodsNative() /*-{"); srcWriter.indent(); srcWriter.println("var result = {};"); List<JType> filteredTypes = new ArrayList<JType>(); JType[] types = getSerializableTypes(); int n = types.length; for (int index = 0; index < n; ++index) { JType type = types[index]; if (serializationOracle.maybeInstantiated(type) || deserializationOracle.maybeInstantiated(type)) { filteredTypes.add(type); } } boolean shard = shardSize > 0 && filteredTypes.size() > shardSize; int shardCount = 0; if (shard) { srcWriter.println("(function() {"); } for (JType type : filteredTypes) { if (shard && ++shardCount % shardSize == 0) { srcWriter.println("})();"); srcWriter.println("(function() {"); } String typeString = typeStrings.get(type); assert typeString != null : "Missing type signature for " + type.getQualifiedSourceName(); srcWriter.println("result[\"" + typeString + "\"] = ["); srcWriter.indent(); writeTypeMethodsNative(type); srcWriter.outdent(); srcWriter.indentln("];"); srcWriter.println(); } if (shard) { srcWriter.println("})();"); } srcWriter.println("return result;"); srcWriter.outdent(); srcWriter.println("}-*/;"); srcWriter.println(); }
private void emitBody(SourceWriter w) throws NotFoundException { JClassType baseClass = context_.getTypeOracle().getType("org.rstudio.core.client.js.JsObjectInjector"); JClassType c = baseType_.asParameterizationOf(baseClass.isGenericType()); JType typeToInject = c.isParameterized().getTypeArgs()[0]; w.print("public native final void injectObject("); w.print(typeToInject.getQualifiedSourceName()); w.println(" value) /*-{"); w.indent(); w.println(baseExpression_ + " = {"); w.indent(); JMethod[] methods = typeToInject.isClassOrInterface().getMethods(); for (int i = 0; i < methods.length; i++) { JMethod method = methods[i]; final JParameter[] jParameters = method.getParameters(); StringBuilder argString = new StringBuilder(); for (int j = 0; j < jParameters.length; j++) { argString.append("_").append(j); if (j < jParameters.length - 1) argString.append(", "); } w.println(method.getName() + ": function(" + argString + ") {"); w.indent(); if (!method.getReturnType().getQualifiedSourceName().equals("void")) w.print("return "); w.print("value.@"); w.print(typeToInject.getQualifiedSourceName()); w.print("::"); w.print(method.getName()); w.print("("); for (JParameter param : jParameters) w.print(param.getType().getJNISignature()); w.print(")("); w.print(argString.toString()); w.println(");"); w.outdent(); w.print("}"); w.println((i < methods.length - 1) ? "," : ""); } w.outdent(); w.println("};"); w.outdent(); w.println("}-*/;"); }
/** Writes the map of the owner Models */ private void writeOwnerModels() { logger.log(Type.DEBUG, "Starting to write OwnerModels"); // $NON-NLS-1$ sw.println(); sw.println("@Override"); // $NON-NLS-1$ sw.println( "protected java.util.Map<String, org.ovirt.engine.ui.uicommonweb.models.Model> getOwnerModels() {"); //$NON-NLS-1$ sw.indent(); sw.println( "java.util.Map<String, org.ovirt.engine.ui.uicommonweb.models.Model> regs = new java.util.HashMap<String, org.ovirt.engine.ui.uicommonweb.models.Model>();"); //$NON-NLS-1$ logger.log(Type.DEBUG, "Going over Editor Fields"); // $NON-NLS-1$ for (EditorData editorData : model.getEditorData()) { logger.log(Type.DEBUG, "Going over Field: " + editorData); // $NON-NLS-1$ String path = editorData.getPath(); if (path.length() == 0) { continue; } JClassType propertyOwnerType = eraseType(editorData.getPropertyOwnerType()); if (propertyOwnerType == listModelType || propertyOwnerType == entityModelType) { logger.log(Type.DEBUG, "Found owner Model Field: " + editorData); // $NON-NLS-1$ sw.println( "regs.put(\"%s\", getObject()%s);", path, editorData.getBeanOwnerExpression()); // $NON-NLS-1$ } } sw.println("return regs;"); // $NON-NLS-1$ sw.outdent(); sw.println("}"); // $NON-NLS-1$ }
/** * Writes a method to produce a map of class name to type string for Java. * * <pre> * private static Map<String<?>, String> loadSignaturesJava() { * Map<String<?>, String> result = new HashMap<String<?>, String>(); * result.put( * com.google.gwt.user.client.rpc.core.java.lang.String_FieldSerializer.concreteType(), * "java.lang.String/2004016611"); * ... * return result; * } * </pre> */ private void writeLoadSignaturesJava() { srcWriter.println("@SuppressWarnings(\"deprecation\")"); srcWriter.println("private static Map<String, String> loadSignaturesJava() {"); srcWriter.indent(); srcWriter.println("Map<String, String> result = new HashMap<String, String>();"); for (JType type : getSerializableTypes()) { String typeString = typeStrings.get(type); if (!serializationOracle.maybeInstantiated(type) && !deserializationOracle.maybeInstantiated(type)) { continue; } String typeRef; JClassType customSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer(typeOracle, type); if (customSerializer != null && CustomFieldSerializerValidator.getConcreteTypeMethod(customSerializer) != null) { typeRef = customSerializer.getQualifiedSourceName() + ".concreteType()"; } else { typeRef = '"' + SerializationUtils.getRpcTypeName(type) + '"'; } srcWriter.println("result.put(" + typeRef + ", \"" + typeString + "\");"); } srcWriter.println("return result;"); srcWriter.outdent(); srcWriter.println("}"); srcWriter.println(); }
/** * Writes a method to produce a map of type string -> class name of {@link TypeHandler} for Java. * * <pre> * private static Map<String, String> loadMethodsJava() { * Map<String, String> result = new HashMap<String, String>(); * result.put( * "java.lang.String/2004016611", * "com.google.gwt.user.client.rpc.core.java.lang.String_FieldSerializer" * ... * return result; * } * </pre> */ private void writeLoadMethodsJava() { srcWriter.println("@SuppressWarnings(\"deprecation\")"); srcWriter.println("private static Map<String, String> loadMethodsJava() {"); srcWriter.indent(); srcWriter.println("Map<String, String> result = new HashMap<String, String>();"); List<JType> filteredTypes = new ArrayList<JType>(); JType[] types = getSerializableTypes(); int n = types.length; for (int index = 0; index < n; ++index) { JType type = types[index]; if (serializationOracle.maybeInstantiated(type) || deserializationOracle.maybeInstantiated(type)) { filteredTypes.add(type); } } for (JType type : filteredTypes) { String typeString = typeStrings.get(type); assert typeString != null : "Missing type signature for " + type.getQualifiedSourceName(); srcWriter.println( "result.put(\"" + typeString + "\", \"" + SerializationUtils.getStandardSerializerName((JClassType) type) + "\");"); } srcWriter.println("return result;"); srcWriter.outdent(); srcWriter.println("}"); srcWriter.println(); }
private void generateClass(TreeLogger logger, GeneratorContext context) { // get print writer that receives the source code PrintWriter printWriter = null; printWriter = context.tryCreate(logger, packageName, className); // print writer if null, source code has ALREADY been generated, return if (printWriter == null) { return; } // init composer, set class properties, create source writer ClassSourceFileComposerFactory composer = null; composer = new ClassSourceFileComposerFactory(packageName, className); composer.addImplementedInterface("org.pentaho.ui.xul.gwt.binding.TypeController"); composer.addImport("org.pentaho.ui.xul.gwt.binding.*"); composer.addImport("java.util.Map"); composer.addImport("java.util.HashMap"); composer.addImport("org.pentaho.ui.xul.XulException"); SourceWriter sourceWriter = null; sourceWriter = composer.createSourceWriter(context, printWriter); // generator constructor source code generateConstructor(sourceWriter); writeMethods(sourceWriter); // close generated class sourceWriter.outdent(); sourceWriter.println("}"); // commit generated class context.commit(logger, printWriter); }
/** * Writes a loadNamesMapJava method for the current locale, based on its the supplied names map * and its superclass (if any). * * <p>If no new names are added for this locale over its superclass, the method is omitted * entirely. * * @param writer SourceWriter instance to use for writing the class * @param currencies array of valid currency names in the order they should be listed * @param allCurrencyData map of currency codes to currency data for the current locale, including * all inherited currencies data */ private void writeNamesMethodJava( SourceWriter writer, String[] currencies, Map<String, CurrencyInfo> allCurrencyData) { boolean needHeader = true; for (String currencyCode : currencies) { // TODO(jat): only emit new data where it differs from superclass! CurrencyInfo currencyInfo = allCurrencyData.get(currencyCode); String displayName = currencyInfo.getDisplayName(); if (displayName != null && !currencyCode.equals(displayName)) { if (needHeader) { needHeader = false; writer.println(); writer.println("@Override"); writer.println("protected HashMap<String, String> loadNamesMapJava() {"); writer.indent(); writer.println("HashMap<String, String> result = super.loadNamesMapJava();"); } writer.println( "result.put(\"" + quote(currencyCode) + "\", \"" + quote(displayName) + "\");"); } } if (!needHeader) { writer.println("return result;"); writer.outdent(); writer.println("}"); } }
/** Writes the UiCommonEventMap for the edited model */ private void writeEventMap() { logger.log(Type.DEBUG, "Starting to write EventMap"); // $NON-NLS-1$ sw.println(); sw.println("@Override"); // $NON-NLS-1$ sw.println( "protected " + UiCommonEventMap.class.getName() + " getEventMap() {"); //$NON-NLS-1$ //$NON-NLS-2$ sw.indent(); sw.println( UiCommonEventMap.class.getName() + " eventMap = new " + UiCommonEventMap.class.getName() + "();"); //$NON-NLS-1$ //$NON-NLS-2$ logger.log(Type.DEBUG, "Looking for Model Fields"); // $NON-NLS-1$ for (EditorData editorData : model.getEditorData()) { logger.log(Type.DEBUG, "Going over Field: " + editorData); // $NON-NLS-1$ String path = editorData.getPath(); if (path.length() == 0) { continue; } JClassType propertyOwnerType = eraseType(editorData.getPropertyOwnerType()); if (propertyOwnerType == entityModelType) { logger.log(Type.DEBUG, "Found EntityModel Field: " + editorData); // $NON-NLS-1$ sw.println( "eventMap.addEvent(\"%s\", \"EntityChanged\", getObject()%s.getEntityChangedEvent());", //$NON-NLS-1$ path, editorData.getBeanOwnerExpression()); } else if (propertyOwnerType == listModelType) { logger.log(Type.DEBUG, "Found ListModel Field: " + editorData); // $NON-NLS-1$ sw.println( "eventMap.addEvent(\"%s\", \"ItemsChanged\", getObject()%s.getItemsChangedEvent());", //$NON-NLS-1$ path, editorData.getBeanOwnerExpression()); sw.println( "eventMap.addEvent(\"%s\", \"SelectedItemsChanged\", getObject()%s.getSelectedItemsChangedEvent());", //$NON-NLS-1$ path, editorData.getBeanOwnerExpression()); sw.println( "eventMap.addEvent(\"%s\", \"SelectedItemChanged\", getObject()%s.getSelectedItemChangedEvent());", //$NON-NLS-1$ path, editorData.getBeanOwnerExpression()); } } sw.println("return eventMap;"); // $NON-NLS-1$ sw.outdent(); sw.println("}"); // $NON-NLS-1$ }
private void writeCleanup() { logger.log( Type.DEBUG, "Starting to write cleanup impl. for editor " //$NON-NLS-1$ + model.getEditorType().getQualifiedSourceName()); sw.println(); sw.println("@Override"); // $NON-NLS-1$ sw.println("public void cleanup() {"); // $NON-NLS-1$ sw.indent(); // 1. clean up the Editor instance Set<String> editorFieldExpressions = getEditorFieldCleanupExpressions(); for (String expr : editorFieldExpressions) { sw.println(String.format("if (%s != null) {", expr)); // $NON-NLS-1$ sw.indent(); sw.println(String.format("%s.cleanup();", expr)); // $NON-NLS-1$ sw.outdent(); sw.println("}"); // $NON-NLS-1$ } // 2. clean up the edited Model object Set<String> modelExpressions = getModelCleanupExpressions(); if (!modelExpressions.isEmpty()) { sw.println("if (getObject() != null) {"); // $NON-NLS-1$ sw.indent(); for (String expr : modelExpressions) { sw.println(String.format("%s.cleanup();", expr)); // $NON-NLS-1$ } sw.outdent(); sw.println("}"); // $NON-NLS-1$ } sw.outdent(); sw.println("}"); // $NON-NLS-1$ }
/** * Generate the proxy constructor and delegate to the superclass constructor using the default * address for the {@link com.google.gwt.user.client.rpc.RemoteService RemoteService}. */ protected void generateProxyContructor(SourceWriter srcWriter) { srcWriter.println("public " + getProxySimpleName() + "() {"); srcWriter.indent(); srcWriter.println("super(GWT.getModuleBaseURL(),"); srcWriter.indent(); srcWriter.println(getRemoteServiceRelativePath() + ", "); srcWriter.println("SERIALIZATION_POLICY, "); srcWriter.println("SERIALIZER);"); srcWriter.outdent(); srcWriter.outdent(); srcWriter.println("}"); }
private void emitMethod(SourceWriter writer) throws UnableToCompleteException { writer.println("public void createMenu(MenuCallback callback) {"); writer.indent(); writer.println("callback.beginMainMenu();"); // Vertical defaults to true emitMenu(writer, menuEl_); writer.println("callback.endMainMenu();"); writer.outdent(); writer.println("}"); }
private void writeMethods(SourceWriter sourceWriter) { sourceWriter.println("public GwtBindingMethod findGetMethod(Object obj, String propertyName){"); sourceWriter.indent(); sourceWriter.println( "GwtBindingMethod retVal = findMethod(obj,\"get\"+propertyName.substring(0,1).toUpperCase()" + "+propertyName.substring(1));"); sourceWriter.println("if(retVal == null){"); sourceWriter.indent(); sourceWriter.println( "retVal = findMethod(obj,\"is\"+propertyName.substring(0,1).toUpperCase()+propertyName." + "substring(1));"); sourceWriter.outdent(); sourceWriter.println("}"); sourceWriter.println("return retVal;"); sourceWriter.outdent(); sourceWriter.println("}"); sourceWriter.println("public GwtBindingMethod findSetMethod(Object obj, String propertyName){"); sourceWriter.indent(); sourceWriter.println( "return findMethod(obj,\"set\"+propertyName.substring(0,1).toUpperCase()+propertyName" + ".substring(1));"); sourceWriter.outdent(); sourceWriter.println("}"); sourceWriter.println("public GwtBindingMethod findMethod(Object obj, String propertyName){"); sourceWriter.indent(); sourceWriter.println("return findOrCreateMethod(obj.getClass().getName(), propertyName);"); sourceWriter.outdent(); sourceWriter.println("}"); createFindMethod(sourceWriter); }
private void generateConstructor(SourceWriter sourceWriter) { sourceWriter.println( "public Map<String, GwtBindingMethod> wrappedTypes = new HashMap<String, GwtBindingMethod>();"); // start constructor source generation sourceWriter.println("public " + className + "() { "); sourceWriter.indent(); sourceWriter.println("super();"); sourceWriter.outdent(); sourceWriter.println("}"); }
/** * Statically initializes the class fields either for script or JVM. * * <pre> * static { * if (GWT.isScript()) { * methodMapJava = null; * methodMapNative = loadMethodsNative(); * signatureMapJava = null; * signatureMapNative = loadSignaturesNative(); * } else { * methodMapJava = loadMethodsJava(); * methodMapNative = null; * signatureMapJava = loadSignaturesJava(); * signatureMapNative = null; * } * } * </pre> */ private void writeStaticInitializer() { srcWriter.println("static {"); srcWriter.indent(); if (context.isProdMode()) { srcWriter.println("methodMapNative = loadMethodsNative();"); srcWriter.println("signatureMapNative = loadSignaturesNative();"); } else { srcWriter.println("methodMapJava = loadMethodsJava();"); srcWriter.println("signatureMapJava = loadSignaturesJava();"); } srcWriter.outdent(); srcWriter.println("}"); srcWriter.println(); }
protected void generateStreamWriterOverride(SourceWriter srcWriter) { srcWriter.println("@Override"); srcWriter.println("public SerializationStreamWriter createStreamWriter() {"); srcWriter.indent(); /* * Need an explicit cast since we've widened the declaration of the method * in RemoteServiceProxy. */ srcWriter.println("ClientSerializationStreamWriter toReturn ="); srcWriter.indentln("(ClientSerializationStreamWriter) super.createStreamWriter();"); if (elideTypeNames) { srcWriter.println( "toReturn.addFlags(ClientSerializationStreamWriter." + "FLAG_ELIDE_TYPE_NAMES);"); } srcWriter.println("if (getRpcToken() != null) {"); srcWriter.indent(); srcWriter.println( "toReturn.addFlags(ClientSerializationStreamWriter." + "FLAG_RPC_TOKEN_INCLUDED);"); srcWriter.outdent(); srcWriter.println("}"); srcWriter.println("return toReturn;"); srcWriter.outdent(); srcWriter.println("}"); }
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; }
private void writeResolver(List introspectables, SourceWriter writer) { writer.println("public Class resolveClass(Object object){"); writer.indent(); for (Iterator it = introspectables.iterator(); it.hasNext(); ) { BeanResolver type = (BeanResolver) it.next(); writer.println( "if( object instanceof " + type.getType().getQualifiedSourceName() + " ) return " + type.getType().getQualifiedSourceName() + ".class;"); } writer.println("throw new RuntimeException( \"Object \"+object+\"could not be resolved.\" );"); writer.outdent(); writer.println("}"); }
/** * Writes a method to produce a native map of system hash code to type string. * * <pre> * private static native JsArrayString loadSignaturesNative() /*-{ * var result = []; * result[@com.google.gwt.core.client.impl.Impl::getHashCode(Ljava/lang/Object;)(@java.lang.String::class)] = "java.lang.String/2004016611"; * ... * return result; * }-*/; * </pre> */ private void writeLoadSignaturesNative() { srcWriter.println("@SuppressWarnings(\"deprecation\")"); srcWriter.println("@GwtScriptOnly"); srcWriter.println("private static native JsArrayString loadSignaturesNative() /*-{"); srcWriter.indent(); srcWriter.println("var result = [];"); boolean shard = shardSize > 0 && getSerializableTypes().length > shardSize; int shardCount = 0; if (shard) { srcWriter.println("(function() {"); } for (JType type : getSerializableTypes()) { String typeString = typeStrings.get(type); if (!serializationOracle.maybeInstantiated(type) && !deserializationOracle.maybeInstantiated(type)) { continue; } if (shard && ++shardCount % shardSize == 0) { srcWriter.println("})();"); srcWriter.println("(function() {"); } srcWriter.println( "result[@com.google.gwt.core.client.impl.Impl::getHashCode(Ljava/lang/Object;)(@" + type.getQualifiedSourceName() + "::class)] = \"" + typeString + "\";"); } if (shard) { srcWriter.println("})();"); } srcWriter.println("return result;"); srcWriter.outdent(); srcWriter.println("}-*/;"); srcWriter.println(); }
public String generate() throws Exception { String simpleName = baseType_.getName().replace('.', '_') + "__Impl"; PrintWriter printWriter = context_.tryCreate(logger_, packageName_, simpleName); if (printWriter != null) { ClassSourceFileComposerFactory factory = new ClassSourceFileComposerFactory(packageName_, simpleName); factory.addImplementedInterface(baseType_.getName()); SourceWriter writer = factory.createSourceWriter(context_, printWriter); emitBody(writer); // Close the class and commit it writer.outdent(); writer.println("}"); context_.commit(logger_, printWriter); } return packageName_ + "." + simpleName; }
public String generate() throws UnableToCompleteException { String className = bundleType_.getSimpleSourceName() + "__Menu_" + menuId_; PrintWriter printWriter = context_.tryCreate(logger_, packageName_, className); if (printWriter == null) return null; ClassSourceFileComposerFactory factory = new ClassSourceFileComposerFactory(packageName_, className); factory.addImport("org.rstudio.core.client.Debug"); factory.addImport("org.rstudio.core.client.command.MenuCallback"); SourceWriter writer = factory.createSourceWriter(context_, printWriter); emitFields(writer); emitConstructor(writer, className); emitMethod(writer); writer.outdent(); writer.println("}"); context_.commit(logger_, printWriter); return packageName_ + "." + className; }
/** * Write an entry in the methodMapNative for one type. * * @param type type to generate entry for */ private void writeTypeMethodsNative(JType type) { srcWriter.indent(); String serializerName = SerializationUtils.getFieldSerializerName(typeOracle, type); JClassType customSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer(typeOracle, type); // First the initialization method if (deserializationOracle.maybeInstantiated(type)) { srcWriter.print("@"); if (customSerializer != null) { if (hasInstantiateMethod(customSerializer, type)) { srcWriter.print(serializerName); } else { srcWriter.print(SerializationUtils.getStandardSerializerName((JClassType) type)); } } else { srcWriter.print(serializerName); } srcWriter.print("::instantiate"); srcWriter.print("(L" + SerializationStreamReader.class.getName().replace('.', '/') + ";)"); } srcWriter.println(","); // Now the deserialization method if (deserializationOracle.isSerializable(type)) { // Assume param type is the concrete type of the serialized type. JType paramType = type; if (customSerializer != null) { // But a custom serializer may specify a looser type. JMethod deserializationMethod = CustomFieldSerializerValidator.getDeserializationMethod( customSerializer, (JClassType) type); paramType = deserializationMethod.getParameters()[1].getType(); } srcWriter.print("@" + serializerName); srcWriter.print( "::deserialize(L" + SerializationStreamReader.class.getName().replace('.', '/') + ";" + paramType.getJNISignature() + ")"); } srcWriter.println(","); // Now the serialization method if (serializationOracle.isSerializable(type)) { // Assume param type is the concrete type of the serialized type. JType paramType = type; if (customSerializer != null) { // But a custom serializer may specify a looser type. JMethod serializationMethod = CustomFieldSerializerValidator.getSerializationMethod( customSerializer, (JClassType) type); paramType = serializationMethod.getParameters()[1].getType(); } srcWriter.print("@" + serializerName); srcWriter.print( "::serialize(L" + SerializationStreamWriter.class.getName().replace('.', '/') + ";" + paramType.getJNISignature() + ")"); srcWriter.println(); } srcWriter.outdent(); }
/** * 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; }
private void writeBeanDescriptor( TreeLogger logger, BeanResolver info, MethodWrapper[] methods, SourceWriter writer) { writer.println("new BeanDescriptor() { "); writer.indent(); writer.println("private HashMap lookup;"); writer.println("private Property[] properties;"); writer.println("public Property[] getProperties(){"); writer.indent(); { writer.println("if( this.properties != null ) "); writer.indentln("return this.properties;"); writer.println("this.properties = new Property[" + (info.getProperties().size()) + "];"); Collection pds = info.getProperties().values(); String[] propertyNames = new String[pds.size()]; logger.log(TreeLogger.SPAM, "" + (pds == null), null); if (pds != null) { int i = 0; for (Iterator it = pds.iterator(); it.hasNext(); i++) { RProperty p = (RProperty) it.next(); propertyNames[i] = p.getName(); writer.println("{"); writer.indent(); writer.print("Method readMethod = "); if (p.getReadMethod() == null) { writer.println("null;"); } else { writer.println( this.packageName + "." + this.methodsImplementationName + ".METHOD_" + +this.find(methods, p.getReadMethod()) + ";"); } writer.print("Method writeMethod = "); if (p.getWriteMethod() == null) { writer.println("null;"); } else { writer.println( this.packageName + "." + this.methodsImplementationName + ".METHOD_" + +this.find(methods, p.getWriteMethod()) + ";"); } logger.log( TreeLogger.DEBUG, p.getName() + " " + p.getType().getQualifiedSourceName(), null); JType ptype = this.resolveType(p.getType()); logger.log( TreeLogger.DEBUG, p.getName() + " (Erased) " + ptype.getQualifiedSourceName(), null); writer.println( "this.properties[" + (i) + "] = new Property( \"" + p.getName() + "\", " + ((p.getType() != null) ? ptype.getQualifiedSourceName() : "Object") + ".class, readMethod, writeMethod );"); writer.outdent(); writer.println("}"); } } writer.println("return this.properties;"); } writer.outdent(); writer.println("} //end getProperties()"); writer.println("public Property getProperty( String name ) {"); writer.indent(); // TODO Rewrite this to a nested if loop using the propertyNames parameter. writer.println("Property p = null;"); writer.println("if( this.lookup != null ) {"); writer.indentln("p = (Property) lookup.get(name); "); writer.println("} else {"); writer.indent(); writer.println("this.lookup = new HashMap();"); writer.println("Property[] props = this.getProperties(); "); writer.println("for( int i=0; i < props.length; i++ ) {"); writer.indent(); writer.println("this.lookup.put( props[i].getName(), props[i] );"); writer.outdent(); writer.println("}"); writer.println("p = (Property) this.lookup.get(name);"); writer.outdent(); writer.println("}"); writer.println( "if( p == null ) throw new RuntimeException(\"Couldn't find property \"+name+\" for " + info.getType().getQualifiedSourceName() + "\");"); writer.println("else return p;"); writer.outdent(); writer.println("}"); writer.outdent(); writer.print("}"); }
public String generate(TreeLogger logger, GeneratorContext context, String typeName) throws UnableToCompleteException { // .println("Introspector Generate."); try { this.objectType = context.getTypeOracle().getType("java.lang.Object"); } catch (NotFoundException ex) { logger.log(TreeLogger.ERROR, typeName, ex); return null; } List<BeanResolver> introspectables = this.getIntrospectableTypes(logger, context.getTypeOracle()); MethodWrapper[] methods = this.findMethods(logger, introspectables); ClassSourceFileComposerFactory mcf = new ClassSourceFileComposerFactory(this.packageName, this.methodsImplementationName); mcf.addImport(Method.class.getCanonicalName()); PrintWriter methodsPrintWriter = context.tryCreate(logger, this.packageName, this.methodsImplementationName); if (methodsPrintWriter != null) { SourceWriter methodsWriter = mcf.createSourceWriter(context, methodsPrintWriter); this.writeMethods(logger, methods, methodsWriter); methodsWriter.println("}"); context.commit(logger, methodsPrintWriter); } ClassSourceFileComposerFactory cfcf = new ClassSourceFileComposerFactory(this.packageName, this.implementationName); cfcf.addImplementedInterface(typeName); cfcf.addImport("java.util.HashMap"); cfcf.addImport(Method.class.getCanonicalName()); cfcf.addImport(com.totsp.gwittir.introspection.Property.class.getCanonicalName()); cfcf.addImport(com.totsp.gwittir.introspection.BeanDescriptor.class.getCanonicalName()); PrintWriter printWriter = context.tryCreate(logger, packageName, implementationName); if (printWriter == null) { // .println( "Introspector Generate skipped."); return packageName + "." + implementationName; } SourceWriter writer = cfcf.createSourceWriter(context, printWriter); this.writeIntrospectables(logger, introspectables, methods, writer); this.writeResolver(introspectables, writer); writer.println( "private HashMap<Class,BeanDescriptor> beanDescriptorLookup = new HashMap<Class,BeanDescriptor>();"); writer.println(); writer.println("public BeanDescriptor getDescriptor( Object object ){ "); writer.indent(); writer.println( "if( object == null ) throw new NullPointerException(\"Attempt to introspect null object\");"); writer.println( "if( object instanceof " + SelfDescribed.class.getCanonicalName() + " ) return ((SelfDescribed)object).__descriptor();"); writer.println("BeanDescriptor descriptor = beanDescriptorLookup.get(object.getClass());"); writer.println("if (descriptor!=null){"); writer.indentln("return descriptor;"); writer.outdent(); writer.println("}"); writer.println("descriptor=_getDescriptor(object);"); writer.println("beanDescriptorLookup.put(object.getClass(),descriptor);"); writer.println("return descriptor;"); writer.outdent(); writer.println("}"); writer.println("private BeanDescriptor _getDescriptor( Object object ){ "); writer.indent(); for (BeanResolver resolver : introspectables) { writer.println( "if( object instanceof " + resolver.getType().getQualifiedSourceName() + " ) {"); writer.indent(); String name = resolver.getType().getQualifiedSourceName().replaceAll("\\.", "_"); logger.log(TreeLogger.DEBUG, "Writing : " + name, null); writer.print("return " + name + " == null ? " + name + " = "); this.writeBeanDescriptor(logger, resolver, methods, writer); writer.print(": " + name + ";"); writer.outdent(); writer.println("}"); } writer.println(" throw new IllegalArgumentException(\"Unknown type\" + object.getClass() ); "); writer.outdent(); writer.println("}"); writer.println("public Object createInstance(Class clazz) {"); writer.indent(); for (BeanResolver resolver : introspectables) { boolean hasPNA = false; for (JConstructor constructor : resolver.getType().getConstructors()) { if (constructor.getParameters() == null || constructor.getParameters().length == 0 && constructor.isPublic()) { hasPNA = true; break; } if (hasPNA) { break; } } writer.println( "if(clazz.equals(" + resolver.getType().getQualifiedSourceName() + ".class)){"); writer.indent(); logger.log( TreeLogger.Type.TRACE, resolver.getType().getQualifiedSourceName() + " abstract " + resolver.getType().isAbstract() + " intf " + (resolver.getType().isInterface() != null) + " def " + resolver.getType().isDefaultInstantiable()); if (resolver.getType().isAbstract() || resolver.getType().isInterface() != null) { writer.println("throw new IllegalArgumentException(clazz+\" is abstract\");"); } else if (hasPNA) { writer.println("return new " + resolver.getType().getQualifiedSourceName() + "();"); } else { writer.println( "throw new IllegalArgumentException(clazz+\" has no public no args constructor\");"); } writer.outdent(); writer.println("}"); } writer.println(" throw new IllegalArgumentException(\"Unknown type\" +clazz ); "); writer.outdent(); writer.println("}"); writer.println("HashMap<String, Class> classes = new HashMap<String, Class>();"); writer.println("public Class forName(String className){"); writer.indent(); writer.println("Class clazz = classes.get(className);"); writer.println("if(clazz != null) return clazz;"); for (BeanResolver resolver : introspectables) { writer.println( "if(className.equals(\"" + resolver.getType().getQualifiedSourceName() + "\")){"); writer.indent(); writer.println("clazz = " + resolver.getType().getQualifiedSourceName() + ".class;"); writer.println("classes.put(className, clazz);"); writer.println("return clazz;"); writer.outdent(); writer.println("}"); } writer.println("throw new IllegalArgumentException(className+\" is not introspecable.\");"); writer.outdent(); writer.println("}"); writer.outdent(); writer.println("}"); context.commit(logger, printWriter); // .println( "Introspector Generate completed."); return packageName + "." + implementationName; }
/** * Generates the client's asynchronous proxy method. * * @param serializableTypeOracle the type oracle */ protected void generateProxyMethod( SourceWriter w, SerializableTypeOracle serializableTypeOracle, TypeOracle typeOracle, JMethod syncMethod, JMethod asyncMethod) { w.println(); // Write the method signature JType asyncReturnType = asyncMethod.getReturnType().getErasedType(); w.print("public "); w.print(asyncReturnType.getQualifiedSourceName()); w.print(" "); w.print(asyncMethod.getName() + "("); boolean needsComma = false; NameFactory nameFactory = new NameFactory(); JParameter[] asyncParams = asyncMethod.getParameters(); for (int i = 0; i < asyncParams.length; ++i) { JParameter param = asyncParams[i]; if (needsComma) { w.print(", "); } else { needsComma = true; } /* * Ignoring the AsyncCallback parameter, if any method requires a call to * SerializationStreamWriter.writeObject we need a try catch block */ JType paramType = param.getType(); paramType = paramType.getErasedType(); w.print(paramType.getQualifiedSourceName()); w.print(" "); String paramName = param.getName(); nameFactory.addName(paramName); w.print(paramName); } w.println(") {"); w.indent(); String helperName = nameFactory.createName("helper"); String helperClassName = RemoteServiceProxy.ServiceHelper.class.getCanonicalName(); w.println( "%s %s = new %s(\"%s\", \"%s\");", helperClassName, helperName, helperClassName, getProxySimpleName(), syncMethod.getName()); w.println("try {"); w.indent(); // Write the parameter count followed by the parameter values JParameter[] syncParams = syncMethod.getParameters(); String streamWriterName = nameFactory.createName("streamWriter"); w.println( "%s %s = %s.start(REMOTE_SERVICE_INTERFACE_NAME, %s);", SerializationStreamWriter.class.getSimpleName(), streamWriterName, helperName, syncParams.length); for (JParameter param : syncParams) { JType paramType = param.getType().getErasedType(); String typeNameExpression = computeTypeNameExpression(paramType); assert typeNameExpression != null : "Could not compute a type name for " + paramType.getQualifiedSourceName(); w.println(streamWriterName + ".writeString(" + typeNameExpression + ");"); } // Encode all of the arguments to the asynchronous method, but exclude the // last argument which is the callback instance. // for (int i = 0; i < asyncParams.length - 1; ++i) { JParameter asyncParam = asyncParams[i]; w.print(streamWriterName + "."); w.print(Shared.getStreamWriteMethodNameFor(asyncParam.getType())); w.println("(" + asyncParam.getName() + ");"); } /* * Depending on the return type for the async method, return a * RequestBuilder, a Request, or nothing at all. */ JParameter callbackParam = asyncParams[asyncParams.length - 1]; JType returnType = syncMethod.getReturnType(); String callbackName = callbackParam.getName(); if (asyncReturnType == JPrimitiveType.VOID) { w.println( "%s.finish(%s, ResponseReader.%s);", helperName, callbackName, getResponseReaderFor(returnType).name()); } else if (asyncReturnType.getQualifiedSourceName().equals(RequestBuilder.class.getName())) { w.println( "return %s.finishForRequestBuilder(%s, ResponseReader.%s);", helperName, callbackName, getResponseReaderFor(returnType).name()); } else if (asyncReturnType.getQualifiedSourceName().equals(Request.class.getName())) { w.println( "return %s.finish(%s, ResponseReader.%s);", helperName, callbackName, getResponseReaderFor(returnType).name()); } else { // This method should have been caught by RemoteServiceAsyncValidator throw new RuntimeException( "Unhandled return type " + asyncReturnType.getQualifiedSourceName()); } w.outdent(); w.print("} catch (SerializationException "); String exceptionName = nameFactory.createName("ex"); w.println(exceptionName + ") {"); w.indent(); if (!asyncReturnType.getQualifiedSourceName().equals(RequestBuilder.class.getName())) { /* * If the method returns void or Request, signal the serialization error * immediately. If the method returns RequestBuilder, the error will be * signaled whenever RequestBuilder.send() is invoked. */ w.println(callbackName + ".onFailure(" + exceptionName + ");"); } if (asyncReturnType.getQualifiedSourceName().equals(RequestBuilder.class.getName())) { w.println( "return new " + FailingRequestBuilder.class.getName() + "(" + exceptionName + ", " + callbackName + ");"); } else if (asyncReturnType.getQualifiedSourceName().equals(Request.class.getName())) { w.println("return new " + FailedRequest.class.getName() + "();"); } else { assert asyncReturnType == JPrimitiveType.VOID; } w.outdent(); w.println("}"); w.outdent(); w.println("}"); }
private void createFindMethod(SourceWriter sourceWriter) { // We create more than one findMethod as the body of one method would be too large. This is the // int that we // increment to add to the name // i.e. findMethod0() int methodNum = 0; // This int keeps track of how many methods are generated. When it gets to 200 we create a new // findMethodX() // and chain it to the previous. int methodCount = 0; sourceWriter.println( "private GwtBindingMethod findOrCreateMethod(String obj, String methodName){ "); sourceWriter.indent(); sourceWriter.println("GwtBindingMethod newMethod;"); // dummy first condition, rest are "else if". Keeps us from having conditional logic. sourceWriter.println("if(false){ }"); for (JClassType type : implementingTypes) { // close last method, chain it to a new one. if (methodCount > 200) { sourceWriter.println("return findOrCreateMethod" + (methodNum) + "(obj, methodName);"); sourceWriter.println("}"); sourceWriter.println( "private GwtBindingMethod findOrCreateMethod" + (methodNum++) + "(String obj, String methodName){ "); sourceWriter.println("GwtBindingMethod newMethod;"); // dummy first condition, rest are "else if". Keeps us from having conditional logic. sourceWriter.println("if(false){ }"); methodCount = 0; } String keyRoot = generateTypeKey(type); // if(type.isAbstract()){ // System.out.println("abstract"); // continue; // } // determine if there are any methods that are bindable before writing out conditional for // class JClassType loopType = type; boolean hasBindableMethods = false; JClassType eventSourceType = null; try { eventSourceType = typeOracle.getType("org.pentaho.ui.xul.XulEventSource"); } catch (NotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } // CHECKSTYLE IGNORE Indentation FOR NEXT 1 LINES outer: while (loopType.getSuperclass() != null && loopType.getSimpleSourceName().equals("Object") == false && loopType.isAssignableTo(eventSourceType)) { for (JMethod m : loopType.getMethods()) { if (m.isPublic() && m.getAnnotation(Bindable.class) != null) { hasBindableMethods = true; break outer; } } loopType = loopType.getSuperclass(); } if (hasBindableMethods == false) { continue; } sourceWriter.println("else if(obj.equals(\"" + type.getQualifiedSourceName() + "\")){ "); try { loopType = type; sourceWriter.indent(); // Loop over class heirarchy and generate methods for every object that is declared a // XulEventSource while (loopType.getSuperclass() != null && loopType.getSimpleSourceName().equals("Object") == false && loopType.isAssignableTo(eventSourceType)) { String superName = generateTypeKey(loopType); boolean first = true; for (JMethod m : loopType.getMethods()) { methodCount++; if (!m.isPublic() || m.getAnnotation(Bindable.class) == null) { continue; } sourceWriter.println( (first ? "" : "else ") + "if(methodName.equals(\"" + m.getName() + "\")){ "); if (first) { first = false; } sourceWriter.indent(); String methodName = m.getName(); // check to see if we've already processed this classes' method. Point to that class // instead. if (generatedMethods.contains((superName + "_" + methodName).toLowerCase()) && type != loopType) { sourceWriter.println("return findOrCreateMethod(\"" + superName + "\", methodName);"); } else { // See if it's already been created and cached. If so, return that. String keyName = (keyRoot + "_" + methodName).toLowerCase(); sourceWriter.println( "GwtBindingMethod found = wrappedTypes.get(\"" + keyName + "\");"); sourceWriter.println("if(found != null){"); sourceWriter.indent(); sourceWriter.println("return found;"); sourceWriter.outdent(); sourceWriter.println("} else {"); sourceWriter.indent(); // Not cached, create a new instance and put it in the cache. sourceWriter.println("newMethod = new GwtBindingMethod(){"); sourceWriter.println( "public Object invoke(Object obj, Object[] args) throws XulException { "); sourceWriter.indent(); sourceWriter.println("try{"); sourceWriter.println( loopType.getQualifiedSourceName() + " target = (" + loopType.getQualifiedSourceName() + ") obj;"); JParameter[] params = m.getParameters(); String argList = ""; int pos = 0; for (JParameter param : params) { if (pos > 0) { argList += ", "; } argList += "(" + getTypeName(param.getType()) + ") args[" + pos + "]"; pos++; } if (isVoidReturn(m.getReturnType())) { sourceWriter.println("target." + methodName + "(" + argList + ");"); sourceWriter.println("return null;"); } else { sourceWriter.println( "return " + boxReturnType(m) + " target." + methodName + "(" + argList + ");"); } sourceWriter.println( "}catch(Exception e){ e.printStackTrace(); throw new XulException(\"error with " + type.getQualifiedSourceName() + "\"+e.getMessage());}"); sourceWriter.println("}"); sourceWriter.outdent(); sourceWriter.println("};"); // Add it to the HashMap cache as type and decendant type if available. sourceWriter.println("wrappedTypes.put((\"" + keyName + "\"), newMethod);"); if (keyRoot.equals(superName) == false) { sourceWriter.println("wrappedTypes.put((\"" + keyName + "\"), newMethod);"); } generatedMethods.add((keyRoot + "_" + methodName).toLowerCase()); generatedMethods.add((superName + "_" + methodName).toLowerCase()); sourceWriter.println("return newMethod;"); sourceWriter.outdent(); sourceWriter.println("}"); } sourceWriter.outdent(); sourceWriter.println("}"); } // go up a level in the heirarchy and check again. loopType = loopType.getSuperclass(); } sourceWriter.outdent(); sourceWriter.println("}"); } catch (Exception e) { // record to logger that Map generation threw an exception logger.log(TreeLogger.ERROR, "PropertyMap ERROR!!!", e); } } sourceWriter.outdent(); // This is the end of the line, if not found return null. sourceWriter.println("return null;"); sourceWriter.println("}"); }