All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gwtplatform.mvp.rebind.ProxyPlaceOutputter Maven / Gradle / Ivy

There is a newer version: 1.6
Show newest version
/**
 * Copyright 2011 ArcBees Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.gwtplatform.mvp.rebind;

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.core.ext.typeinfo.TypeOracle;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import com.gwtplatform.mvp.client.annotations.DefaultGatekeeper;
import com.gwtplatform.mvp.client.annotations.GatekeeperParams;
import com.gwtplatform.mvp.client.annotations.NameToken;
import com.gwtplatform.mvp.client.annotations.NoGatekeeper;
import com.gwtplatform.mvp.client.annotations.Title;
import com.gwtplatform.mvp.client.annotations.TitleFunction;
import com.gwtplatform.mvp.client.annotations.UseGatekeeper;
import com.gwtplatform.mvp.client.proxy.GetPlaceTitleEvent;

/**
 * Proxy outputter for a proxy that is also a place.
 *
 * @author Philippe Beaudoin
 */
public class ProxyPlaceOutputter extends ProxyOutputterBase {

  public static final String WRAPPED_CLASS_NAME = "WrappedProxy";

  private String nameToken;
  private String getGatekeeperMethod;
  private String[] gatekeeperParams;

  private String title;
  private PresenterTitleMethod presenterTitleMethod;

  public ProxyPlaceOutputter(TypeOracle oracle,
      TreeLogger logger,
      ClassCollection classCollection,
      GinjectorInspector ginjectorInspector,
      PresenterInspector presenterInspector) {
    super(oracle, logger, classCollection, ginjectorInspector, presenterInspector);
  }

  @Override
  public void writeInnerClasses(SourceWriter writer) throws UnableToCompleteException {
    beginWrappedProxy(writer, ClassCollection.proxyImplClassName);
    BasicProxyOutputter basicOutputter = new BasicProxyOutputter(oracle, logger, classCollection,
        ginjectorInspector, presenterInspector);
    basicOutputter.writeFields(writer);
    basicOutputter.writeInnerClasses(writer);
    basicOutputter.writeConstructor(writer, WRAPPED_CLASS_NAME, false);
    basicOutputter.writeMethods(writer);
    endWrappedProxy(writer);
  }

  public void beginWrappedProxy(SourceWriter writer, String wrappedProxySuperclassName) {
    writer.println();
    writer.println("public static class " + WRAPPED_CLASS_NAME);
    writer.println("extends " + wrappedProxySuperclassName + "<"
        + presenterInspector.getPresenterClassName() + "> " + "implements "
        + ClassCollection.delayedBindClassName + " {");
    writer.indent();
  }

  public void endWrappedProxy(SourceWriter writer) {
    writer.outdent();
    writer.println("}");
  }

  @Override
  String getSuperclassName() {
    return ClassCollection.proxyPlaceImplClassName;
  }

  public String getNameToken() {
    return nameToken;
  }

  public String getGatekeeperParamsString() {
    if (gatekeeperParams == null) {
      return "null";
    }
    StringBuilder builder = new StringBuilder("new String[] {");
    for (String param : gatekeeperParams) {
      builder.append("\"").append(param).append("\",");
    }
    if (',' == builder.charAt(builder.length() - 1)) {
      builder.deleteCharAt(builder.length() - 1);
    }
    builder.append("}");
    return builder.toString();
  }

  @Override
  void initSubclass(JClassType proxyInterface)
      throws UnableToCompleteException {
    findNameToken(proxyInterface);
    findGatekeeperMethod(proxyInterface);
    findGatekeeperParams(proxyInterface);
    findTitle(proxyInterface);
  }

  @Override
  void addSubclassImports(ClassSourceFileComposerFactory composerFactory) {
    if (title != null || presenterTitleMethod != null) {
      composerFactory.addImport(GetPlaceTitleEvent.class.getCanonicalName());
      composerFactory.addImport(AsyncCallback.class.getCanonicalName());
      composerFactory.addImport(Throwable.class.getCanonicalName());
    }
  }

  private void findNameToken(JClassType proxyInterface)
      throws UnableToCompleteException {
    NameToken nameTokenAnnotation = proxyInterface.getAnnotation(NameToken.class);
    if (nameTokenAnnotation == null) {
      logger.log(TreeLogger.ERROR,
          "The proxy for '" + presenterInspector.getPresenterClassName()
              + "' is a Place, but is not annotated with @' +"
              + NameToken.class.getSimpleName() + ".", null);
      throw new UnableToCompleteException();
    }
    nameToken = nameTokenAnnotation.value();
  }

  private void findGatekeeperMethod(JClassType proxyInterface)
      throws UnableToCompleteException {
    UseGatekeeper gatekeeperAnnotation = proxyInterface.getAnnotation(UseGatekeeper.class);
    if (gatekeeperAnnotation != null) {
      String gatekeeperName = gatekeeperAnnotation.value().getCanonicalName();
      JClassType customGatekeeperClass = oracle.findType(gatekeeperName);
      if (customGatekeeperClass == null) {
        logger.log(TreeLogger.ERROR, "The class '" + gatekeeperName
            + "' provided to @" + UseGatekeeper.class.getSimpleName()
            + " can't be found.", null);
        throw new UnableToCompleteException();
      }
      if (!customGatekeeperClass.isAssignableTo(classCollection.gatekeeperClass)) {
        logger.log(TreeLogger.ERROR, "The class '" + gatekeeperName
            + "' provided to @" + UseGatekeeper.class.getSimpleName()
            + " does not inherit from '" + ClassCollection.gatekeeperClassName + "'.", null);
        throw new UnableToCompleteException();
      }
      // Find the appropriate get method in the Ginjector
      getGatekeeperMethod = ginjectorInspector.findGetMethod(customGatekeeperClass);
      if (getGatekeeperMethod == null) {
        logger.log(TreeLogger.ERROR,
            "The Ginjector '" + ginjectorInspector.getGinjectorClassName()
                + "' does not have a get() method returning '"
                + gatekeeperName + "'. This is required when using @"
                + UseGatekeeper.class.getSimpleName() + ".", null);
        throw new UnableToCompleteException();
      }
    }
    if (getGatekeeperMethod == null
        && proxyInterface.getAnnotation(NoGatekeeper.class) == null) {
      // No Gatekeeper specified, see if there is a DefaultGatekeeper defined in the ginjector
      getGatekeeperMethod = ginjectorInspector.findAnnotatedGetMethod(
          classCollection.gatekeeperClass, DefaultGatekeeper.class, true);
    }
  }

  private void findGatekeeperParams(JClassType proxyInterface) {
    GatekeeperParams gatekeeperParamsAnnotation = proxyInterface.getAnnotation(GatekeeperParams.class);
    if (gatekeeperParamsAnnotation != null) {
      gatekeeperParams = gatekeeperParamsAnnotation.value();
    }
  }

  private void findTitle(JClassType proxyInterface)
      throws UnableToCompleteException {
    presenterTitleMethod = presenterInspector.findPresenterTitleMethod();
    Title titleAnnotation = proxyInterface.getAnnotation(Title.class);
    if (titleAnnotation != null) {
      title = titleAnnotation.value();
    }
    if (presenterTitleMethod != null && title != null) {
      logger.log(TreeLogger.ERROR, "The proxy for '" + presenterInspector.getPresenterClassName()
          + "' is annotated with @' +" + Title.class.getSimpleName()
          + " and its presenter has a method annotated with @"
          + TitleFunction.class.getSimpleName() + ". Only once can be used.",
          null);
      throw new UnableToCompleteException();
    }
  }

  private String getPlaceInstantiationString() {
    if (getGatekeeperMethod == null) {
      return "new " + ClassCollection.placeImplClassName + "( nameToken )";
    } else {
        if (gatekeeperParams == null) {
          return "new " + ClassCollection.placeWithGatekeeperClassName
            + "( nameToken, ginjector." + getGatekeeperMethod + "() )";
        } else {
            return "new " + ClassCollection.placeWithGatekeeperWithParamsClassName
              + "( nameToken, ginjector." + getGatekeeperMethod + "(), gatekeeperParams )";
      }
    }
  }

  /**
   * Writes the method {@code protected void getPlaceTitle(final GetPlaceTitleEvent event)} if
   * one is needed.
   *
   * @param writer The {@link SourceWriter}.
   */
  private void writeGetPlaceTitleMethod(SourceWriter writer) {
    if (title != null) {
      writeGetPlaceTitleMethodConstantText(writer);
    } else if (presenterTitleMethod != null) {
      presenterTitleMethod.writeProxyMethod(writer);
    }
  }

  private void writeGetPlaceTitleMethodConstantText(SourceWriter writer) {
    writer.println();
    writer.println("protected void getPlaceTitle(GetPlaceTitleEvent event) {");
    writer.indent();
    writer.println("event.getHandler().onSetPlaceTitle( \"" + title
        + "\" );");
    writer.outdent();
    writer.println("}");
  }

  @Override
  void writeSubclassDelayedBind(SourceWriter writer) {
    writer.println(WRAPPED_CLASS_NAME + " wrappedProxy = GWT.create(" + WRAPPED_CLASS_NAME
        + ".class);");
    writer.println("wrappedProxy.delayedBind( ginjector ); ");
    writer.println("setProxy(wrappedProxy); ");
    writer.println("String nameToken = \"" + getNameToken() + "\"; ");
    writer.println("String[] gatekeeperParams = " + getGatekeeperParamsString() + ";");
    writer.println("setPlace(" + getPlaceInstantiationString() + ");");
  }

  @Override
  void writeSubclassMethods(SourceWriter writer) {
    writeGetPlaceTitleMethod(writer);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy