fr.putnami.pwt.core.mvp.rebind.ProxyViewCreator.java Source code

Java tutorial

Introduction

Here is the source code for fr.putnami.pwt.core.mvp.rebind.ProxyViewCreator.java

Source

/**
 * This file is part of pwt.
 *
 * pwt is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser
 * General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * pwt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
 * General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with pwt. If not,
 * see <http://www.gnu.org/licenses/>.
 */
package fr.putnami.pwt.core.mvp.rebind;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.gwt.activity.shared.Activity;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JConstructor;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceTokenizer;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;

import java.io.PrintWriter;
import java.util.List;

import fr.putnami.pwt.core.mvp.client.ViewActivity;
import fr.putnami.pwt.core.mvp.client.ViewDecorator;
import fr.putnami.pwt.core.mvp.client.ViewPlace;
import fr.putnami.pwt.core.mvp.client.ViewProxy;
import fr.putnami.pwt.core.mvp.client.annotation.ActivityDescription;
import fr.putnami.pwt.core.mvp.client.annotation.ActivityDescription.Scope;
import fr.putnami.pwt.core.mvp.client.exception.ApplicationUnreachableException;

public class ProxyViewCreator {

    private static final String PROXY_SUFFIX = "_ProxyView";

    private final JClassType placeType;

    private final String viewProxyQualifiedName;
    private final String viewProxySimpleName;
    private final String packageName;
    private final ActivityDescription activityDescrition;
    private Class<? extends PlaceTokenizer> placeTokenizerClass;
    private Class<? extends ViewDecorator> viewDecoratorClass;

    public ProxyViewCreator(JClassType placeType) {
        this.placeType = placeType;
        this.packageName = this.placeType.getPackage().getName();
        String qualifiedName = this.placeType.getQualifiedSourceName() + ProxyViewCreator.PROXY_SUFFIX;
        this.viewProxyQualifiedName = qualifiedName.replace(placeType.getName(),
                placeType.getName().replace('.', '_'));
        this.viewProxySimpleName = this.viewProxyQualifiedName.replace(this.packageName + ".", "");
        this.activityDescrition = placeType.getAnnotation(ActivityDescription.class);
        this.placeTokenizerClass = this.activityDescrition.placeTokenizer();

        if (PlaceTokenizer.class.equals(this.placeTokenizerClass)) {
            this.placeTokenizerClass = null;
            this.getClass();
            try {
                Class<? extends ViewPlace> placeClass = (Class<? extends ViewPlace>) Class
                        .forName(this.placeType.getQualifiedSourceName());
                for (Class<?> inter : placeClass.getInterfaces()) {
                    if (inter.equals(PlaceTokenizer.class)) {
                        this.placeTokenizerClass = (Class<? extends PlaceTokenizer<?>>) placeClass;
                    }
                }
            } catch (ClassNotFoundException e) {
                this.placeTokenizerClass = null;
            }
        }
        this.viewDecoratorClass = this.activityDescrition.viewDecorator();
        if (ViewDecorator.class.equals(this.viewDecoratorClass)) {
            this.viewDecoratorClass = null;
        }
    }

    public String create(TreeLogger logger, GeneratorContext context) {
        PrintWriter printWriter = context.tryCreate(logger, this.packageName, this.viewProxySimpleName);
        if (printWriter == null) {
            return this.viewProxyQualifiedName;
        }

        SourceWriter srcWriter = this.getSourceWriter(printWriter, context);

        srcWriter.indent();
        this.generateProxy(logger, srcWriter);
        srcWriter.println();
        this.generateTokenPrefixes(logger, srcWriter);
        srcWriter.println();
        if (this.placeTokenizerClass == null) {
            this.generateInternalTokenizer(logger, srcWriter);
        } else {
            this.generateDelegateTokenizer(logger, srcWriter);
        }
        this.generateActivityFactory(logger, srcWriter);
        srcWriter.outdent();

        srcWriter.commit(logger);
        return this.viewProxyQualifiedName;
    }

    private void generateActivityFactory(TreeLogger logger, SourceWriter srcWriter) {
        srcWriter.println("@Override");
        srcWriter.println("public Activity createActivity(Place place) {");
        srcWriter.indent();
        srcWriter.println("return new ViewActivity(this, place);");
        srcWriter.outdent();
        srcWriter.println("}");
    }

    private void generateInternalTokenizer(TreeLogger logger, SourceWriter srcWriter) {
        boolean hasTokeConstructor = false;
        for (JConstructor constructor : this.placeType.getConstructors()) {
            if (constructor.getParameters().length == 1 && constructor.getParameters()[0].getType()
                    .getSimpleSourceName().equals(String.class.getSimpleName())) {
                hasTokeConstructor = true;
            }
        }
        srcWriter.println("@Override");
        srcWriter.println("public %s getPlace(String token) {", this.placeType.getSimpleSourceName());
        srcWriter.indent();
        if (hasTokeConstructor) {
            srcWriter.println("return new %s(token);", this.placeType.getSimpleSourceName());
        } else {
            srcWriter.println("%s place = new %s();", this.placeType.getSimpleSourceName(),
                    this.placeType.getSimpleSourceName());
            srcWriter.println("place.setToken(token);");
            srcWriter.println("return place;");
        }
        srcWriter.outdent();
        srcWriter.println("}");
        srcWriter.println("@Override");
        srcWriter.println("public String getToken(%s place) {", this.placeType.getSimpleSourceName());
        srcWriter.indent();
        srcWriter.println("if(place instanceof ViewPlace){");
        srcWriter.indent();
        srcWriter.println("return ((ViewPlace)place).getToken();");
        srcWriter.outdent();
        srcWriter.println("}");
        srcWriter.println("return null;");
        srcWriter.outdent();
        srcWriter.println("}");
    }

    private void generateDelegateTokenizer(TreeLogger logger, SourceWriter srcWriter) {
        srcWriter.println("@Override");
        srcWriter.println("public %s getPlace(String token) {", this.placeType.getSimpleSourceName());
        srcWriter.indent();
        srcWriter.println("return new %s().getPlace(token);", this.placeTokenizerClass.getSimpleName());
        srcWriter.outdent();
        srcWriter.println("}");
        srcWriter.println("@Override");
        srcWriter.println("public String getToken(%s place) {", this.placeType.getSimpleSourceName());
        srcWriter.indent();
        srcWriter.println("return new %s().getToken(place);", this.placeTokenizerClass.getSimpleName());
        srcWriter.outdent();
        srcWriter.println("}");
    }

    private void generateTokenPrefixes(TreeLogger logger, SourceWriter srcWriter) {
        List<String> tokens = Lists.newArrayList();
        tokens.add("\"" + this.placeType.getSimpleSourceName().replaceAll("Place$", "") + "\"");
        for (String alias : this.activityDescrition.aliases()) {
            tokens.add("\"" + alias + "\"");
        }

        srcWriter.println("@Override");
        srcWriter.println("public String[] getPlacePrefixes(){");
        srcWriter.indent();
        srcWriter.println("return new String[]{ %s };", Joiner.on(", ").join(tokens));
        srcWriter.outdent();
        srcWriter.println("}");
    }

    private void generateProxy(TreeLogger logger, SourceWriter srcWriter) {

        String viewName = this.activityDescrition.view().getSimpleName();
        srcWriter.println();
        srcWriter.println("private static %s view;", viewName);
        srcWriter.println();
        srcWriter.println("@Override");
        srcWriter.println("public void loadView(final ViewProxy.Callback callback) {");
        srcWriter.indent();
        if (this.activityDescrition.asyncView()) {
            srcWriter.println("GWT.runAsync(%s.class, new RunAsyncCallback() {", viewName);
            srcWriter.indent();
            srcWriter.println("public void onFailure(Throwable reason) {");
            srcWriter.indent();
            srcWriter.println("if (ApplicationUnreachableException.HTTP_DOWNLOAD_FAILURE_EXCEPTION"
                    + ".equals(reason.getClass().getSimpleName())) {");
            srcWriter.indent();
            srcWriter.println("reason = new ApplicationUnreachableException(reason);");
            srcWriter.outdent();
            srcWriter.println("}");
            srcWriter.println("GWT.reportUncaughtException(reason);");
            srcWriter.outdent();
            srcWriter.println("}");
            srcWriter.println("public void onSuccess() {");
            srcWriter.indent();
            srcWriter.println("if(view == null || %s){", this.activityDescrition.scope() == Scope.PROTOTYPE);
            srcWriter.indent();
            srcWriter.println("view = GWT.create(%s.class);", viewName);
            srcWriter.outdent();
            srcWriter.println("}");
            this.generateProxyResult(logger, srcWriter);
            srcWriter.outdent();
            srcWriter.println("}");
            srcWriter.outdent();
            srcWriter.println("});");
        } else {
            srcWriter.println("if(view == null || %s){", this.activityDescrition.scope() == Scope.PROTOTYPE);
            srcWriter.indent();
            srcWriter.println("view = GWT.create(%s.class);", viewName);
            srcWriter.outdent();
            srcWriter.println("}");
            this.generateProxyResult(logger, srcWriter);
        }
        srcWriter.outdent();
        srcWriter.println("}");
    }

    private void generateProxyResult(TreeLogger logger, SourceWriter srcWriter) {
        if (this.viewDecoratorClass == null) {
            srcWriter.println("callback.showView(view);");
        } else {
            String decoratorName = this.viewDecoratorClass.getSimpleName();
            srcWriter.println("%s decorator = %s.get();", decoratorName, decoratorName);
            srcWriter.println("decorator.setView(view);");
            srcWriter.println("callback.showView(decorator);");
        }
    }

    private SourceWriter getSourceWriter(PrintWriter printWriter, GeneratorContext ctx) {
        ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory(this.packageName,
                this.viewProxySimpleName);

        composerFactory.setSuperclass(this.placeType.getSimpleSourceName());

        composerFactory.addImport(GWT.class.getName());
        composerFactory.addImport(RunAsyncCallback.class.getName());
        composerFactory.addImport(ViewProxy.class.getName());
        composerFactory.addImport(Place.class.getName());
        composerFactory.addImport(ViewPlace.class.getName());
        composerFactory.addImport(Activity.class.getName());
        composerFactory.addImport(ViewActivity.class.getName());
        composerFactory.addImport(ApplicationUnreachableException.class.getName());
        composerFactory.addImport(this.placeType.getQualifiedSourceName());
        composerFactory.addImport(this.activityDescrition.view().getCanonicalName());
        if (this.placeTokenizerClass != null) {
            composerFactory.addImport(this.placeTokenizerClass.getCanonicalName());
        }
        if (this.viewDecoratorClass != null) {
            composerFactory.addImport(this.viewDecoratorClass.getCanonicalName());
        }

        composerFactory.addImplementedInterface(
                ViewProxy.class.getSimpleName() + "<" + this.placeType.getSimpleSourceName() + ">");

        return composerFactory.createSourceWriter(ctx, printWriter);
    }
}