Package org.gwtoolbox.ioc.core.rebind.processor.multicaster

Source Code of org.gwtoolbox.ioc.core.rebind.processor.multicaster.MulticasterClassGenerator

package org.gwtoolbox.ioc.core.rebind.processor.multicaster;

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.Generator;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.core.ext.typeinfo.JPackage;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import com.google.gwt.user.client.Command;
import org.gwtoolbox.commons.generator.rebind.EasyTreeLogger;
import org.gwtoolbox.ioc.core.client.event.ApplicationEvent;
import org.gwtoolbox.ioc.core.client.event.ApplicationEventListener;
import org.gwtoolbox.ioc.core.client.event.DefaultApplicationEventMulticaster;
import org.gwtoolbox.ioc.core.client.annotation.EventPackages;

import java.io.PrintWriter;
import java.util.*;

/**
* @author Uri Boness
*/
public class MulticasterClassGenerator extends Generator {

    public String generate(TreeLogger logger, GeneratorContext context, String typeName) throws UnableToCompleteException {
        Set<JClassType> eventTypes = new HashSet<JClassType>();
        TypeOracle typeOracle = context.getTypeOracle();
        JClassType type = typeOracle.findType(typeName);
        if (type.isAnnotationPresent(EventPackages.class)) {
            JClassType eventType = typeOracle.findType(ApplicationEvent.class.getName());
            EventPackages eventPackages = type.getAnnotation(EventPackages.class);
            String[] patterns = eventPackages.value();
            for (JPackage pkg : typeOracle.getPackages()) {
                for (String pattern : patterns) {
                    if (pkg.getName().matches(pattern)) {
                        addEventTypes(pkg, eventTypes, eventType);
                    }
                }
            }
        }
        return generate(new EasyTreeLogger(logger), type, eventTypes, context);
    }

    public static String generate(EasyTreeLogger logger, JClassType multicasterType, Set<JClassType> eventTypes, GeneratorContext context) throws UnableToCompleteException {
        TypeOracle typeOracle = context.getTypeOracle();
        String packageName = multicasterType.getPackage().getName();

        String newClassName = multicasterType.getSimpleSourceName() + "Impl";
        String newQualifiedClassName = packageName + "." + newClassName;
        SourceWriter sourceWriter = getSourceWriter(logger, context, packageName, multicasterType, newClassName);
        if (sourceWriter == null) {
            return newQualifiedClassName;
        }
        write(logger, sourceWriter, typeOracle, context, multicasterType, eventTypes);
        sourceWriter.commit(logger);
        return newQualifiedClassName;
    }


    //================================================ Helper Methods ==================================================

    protected static void addEventTypes(JPackage pkg, Set<JClassType> types, JClassType eventType) {
        for (JClassType type : pkg.getTypes()) {
            if (type.isAssignableTo(eventType)) {
                types.add(type);
            }
        }
    }

    protected static SourceWriter getSourceWriter(
            TreeLogger logger,
            GeneratorContext context,
            String packageName,
            JClassType parentType,
            String multicasterClassName) {

        PrintWriter printWriter = context.tryCreate(logger, packageName, multicasterClassName);

        if (printWriter == null) {
            return null;
        }

        ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory(packageName, multicasterClassName);

        composerFactory.addImport(List.class.getName());
        composerFactory.addImport(LinkedList.class.getName());
        composerFactory.addImport(Command.class.getName());
        composerFactory.addImport(ApplicationEvent.class.getName());
        composerFactory.addImport(ApplicationEventListener.class.getName());

        composerFactory.setSuperclass(parentType.getQualifiedSourceName());

        return composerFactory.createSourceWriter(context, printWriter);
    }

    protected static void write(
            EasyTreeLogger logger,
            SourceWriter writer,
            TypeOracle typeOracle,
            GeneratorContext context,
            JClassType multicasterType,
            Set<JClassType> eventTypes) throws UnableToCompleteException {

        Map<String, String> listNameByEventName = new HashMap<String, String>();
        int count = 0;

        writer.println();
        for (JClassType eventType : eventTypes) {
            String listName = "listeners_" + (count++);
            writer.println("private final List<ApplicationEventListener> " + listName + " = new LinkedList<ApplicationEventListener>();");
            listNameByEventName.put(eventType.getQualifiedSourceName(), listName);
        }
        JClassType defaultMulticasterType = typeOracle.findType(DefaultApplicationEventMulticaster.class.getName());
        if (!multicasterType.isAssignableTo(defaultMulticasterType)) {
            writer.println("private final List<ApplicationEventListener> listeners = new LinkedList<ApplicationEventListener>();");
        }
        writer.println();

        boolean first = true;
        writer.println("public void notifyEvent(ApplicationEvent event) {");
        for (JClassType eventType : eventTypes) {
            if (!first) {
                writer.println("else");
            }
            first = false;
            String eventName = eventType.getQualifiedSourceName();
            String listName = listNameByEventName.get(eventName);
            writer.println("if (event instanceof " + eventName + ") {");
            writer.println("    for (ApplicationEventListener listener : " + listName + ".toArray(new ApplicationEventListener[" + listName + ".size()])) {");
            writer.println("        listener.handle(event);");
            writer.println("    }");
            writer.println("}");
        }
        if (!eventTypes.isEmpty()) {
            writer.println("else {");
        }
        writer.println("    for (ApplicationEventListener listener : listeners.toArray(new ApplicationEventListener[listeners.size()])) {");
        writer.println("        listener.handle(event);");
        writer.println("    }");
        if (!eventTypes.isEmpty()) {
            writer.println("}");
        }

        writer.println("for (Command command : event.getPostEventCommands()) {");
        writer.println("    command.execute();");
        writer.println("}");

        writer.println("}");

        first = true;
        writer.println("public void registerListener(ApplicationEventListener listener) {");
        for (JClassType eventType : eventTypes) {
            if (!first) {
                writer.println("else");
            }
            first = false;
            String eventName = eventType.getQualifiedSourceName();
            String listName = listNameByEventName.get(eventName);
            writer.println("if (event instanceof " + eventName + ") {");
            writer.println("    " + listName + ".add(event);");
            writer.println("}");
        }
        if (!eventTypes.isEmpty()) {
            writer.println("else {");
        }
        writer.println("    listeners.add(event);");
        writer.println("}");

        first = true;
        writer.println("public void unregisterListener(ApplicationEventListener listener) {");
        for (JClassType eventType : eventTypes) {
            if (!first) {
                writer.println("else");
            }
            first = false;
            String eventName = eventType.getQualifiedSourceName();
            String listName = listNameByEventName.get(eventName);
            writer.println("if (event instanceof " + eventName + ") {");
            writer.println("    " + listName + ".remove(event);");
            writer.println("}");
        }
        if (!eventTypes.isEmpty()) {
            writer.println("else {");
        }
        writer.println("    listeners.remove(event);");
        writer.println("}");

        writer.println("public void clearListeners() {");
        for (String listName : listNameByEventName.values()) {
            writer.println("    " + listName + ".clear();");
        }
        writer.println("listeners.clear();");
        writer.println("}");
    }
}
TOP

Related Classes of org.gwtoolbox.ioc.core.rebind.processor.multicaster.MulticasterClassGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.