/*
* MenuEmitter.java
*
* Copyright (C) 2009-12 by RStudio, Inc.
*
* Unless you have received this program directly from RStudio pursuant
* to the terms of a commercial license agreement with RStudio, then
* this program is licensed to you under the terms of version 3 of the
* GNU Affero General Public License. This program is distributed WITHOUT
* ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
* AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
*
*/
package org.rstudio.core.rebind.command;
import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import java.io.PrintWriter;
public class MenuEmitter
{
public MenuEmitter(TreeLogger logger,
GeneratorContext context,
JClassType bundleType,
Element menuEl) throws UnableToCompleteException
{
logger_ = logger;
context_ = context;
bundleType_ = bundleType;
menuEl_ = menuEl;
menuId_ = menuEl.getAttribute("id");
if (menuId_.length() == 0)
{
logger.log(TreeLogger.Type.ERROR, "Menu must have an id attribute");
throw new UnableToCompleteException();
}
packageName_ = bundleType.getPackage().getName();
}
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;
}
private void emitFields(SourceWriter writer)
{
writer.println("private "
+ bundleType_.getQualifiedSourceName()
+ " cmds;");
}
private void emitConstructor(SourceWriter writer, String className)
{
writer.println("public " + className + "("
+ bundleType_.getQualifiedSourceName() + " commands) {");
writer.indentln("this.cmds = commands;");
writer.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 emitMenu(SourceWriter writer, Element el) throws UnableToCompleteException
{
for (Node n = el.getFirstChild(); n != null; n = n.getNextSibling())
{
if (n.getNodeType() != Node.ELEMENT_NODE)
continue;
Element child = (Element)n;
if (child.getTagName().equals("cmd"))
{
String cmdId = child.getAttribute("refid");
writer.print("callback.addCommand(");
writer.print("\"" + Generator.escape(cmdId) + "\", ");
writer.println("this.cmds." + cmdId + "());");
}
else if (child.getTagName().equals("separator"))
{
writer.println("callback.addSeparator();");
}
else if (child.getTagName().equals("menu"))
{
String label = child.getAttribute("label");
writer.println("callback.beginMenu(\"" +
Generator.escape(label) +
"\");");
emitMenu(writer, child);
writer.println("callback.endMenu();");
}
else if (child.getTagName().equals("dynamic"))
{
String dynamicClass = child.getAttribute("class");
writer.println("new " + dynamicClass + "().execute(callback);");
}
else
{
logger_.log(TreeLogger.Type.ERROR,
"Unexpected tag " + el.getTagName() + " in menu");
throw new UnableToCompleteException();
}
}
}
private final TreeLogger logger_;
private final GeneratorContext context_;
private final JClassType bundleType_;
private final String menuId_;
private final Element menuEl_;
private final String packageName_;
}