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

com.gwtplatform.mvp.rebind.NonLeafTabContentProxyOutputter 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 java.util.ArrayList;
import java.util.List;

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.JField;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import com.gwtplatform.mvp.client.annotations.ChangeTab;
import com.gwtplatform.mvp.client.annotations.RequestTabs;
import com.gwtplatform.mvp.client.annotations.TabInfo;

/**
 * Proxy outputter for a proxy corresponding to a presenter which is displayed within a
 * {@link com.gwtplatform.mvp.client.TabContainerPresenter TabContainerPresenter}.
 *
 * @author Philippe Beaudoin
 */
public class NonLeafTabContentProxyOutputter extends ProxyOutputterBase {

    private JClassType tabContainerClass;
    private String tabContainerClassName;
    private Integer tabPriority;
    private String tabLabel;
    private TabInfoMethod tabInfoMethod;
    private String targetNameToken;
    private String nameToken;
    private String requestTabsFieldName;
    private String changeTabFieldName;

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

    @Override
    public void writeInnerClasses(SourceWriter writer) {
    }

    @Override
    void writeSubclassMethods(SourceWriter writer) throws UnableToCompleteException {
        writeGetTabDataInternalMethod(writer);
    }

    @Override
    void writeSubclassDelayedBind(SourceWriter writer) {
        writeRequestTabHandler(writer);
        presenterInspector.writeProviderAssignation(writer);
        presenterInspector.writeContentSlotHandlerRegistration(writer);
    }

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

    public void setNameToken(String nameToken) {
        this.nameToken = nameToken;
    }

    private void writeGetTabDataInternalMethod(SourceWriter writer) throws UnableToCompleteException {
        if (tabLabel != null) {
            // Simple string tab label
            writer.println();
            writer.println("protected TabData getTabDataInternal("
                    + ginjectorInspector.getGinjectorClassName() + " ginjector) {");
            writer.indent();
            writer.println("return new TabDataBasic(\"" + tabLabel + "\", " + tabPriority + ");");
            writer.outdent();
            writer.println("}");
        } else {
            tabInfoMethod.writeGetTabDataInternalMethod(writer);
        }
    }

    private void writeRequestTabHandler(SourceWriter writer) {
        writer.println("requestTabsEventType = " + tabContainerClassName + "."
                + requestTabsFieldName + ";");
        if (changeTabFieldName != null) {
            writer.println("changeTabEventType = " + tabContainerClassName + "."
                    + changeTabFieldName + ";");
        }
        writer.println("tabData = getTabDataInternal(ginjector);");
        writer.println("targetHistoryToken = \"" + getTargetNameToken() + "\";");
        writer.println("addRequestTabsHandler();");
    }

    @Override
    void initSubclass(JClassType proxyInterface) throws UnableToCompleteException {
        tabInfoMethod = presenterInspector.findTabInfoMethod();

        TabInfo tabInfoAnnotation = proxyInterface.getAnnotation(TabInfo.class);
        ensureExactlyOneTabInfoAnnotation(tabInfoAnnotation);

        tabPriority = null;
        tabLabel = null;
        if (tabInfoMethod == null) {
            findTabPriority(tabInfoAnnotation);
            findTabLabel(tabInfoAnnotation);
            targetNameToken = tabInfoAnnotation.nameToken();
            tabContainerClassName = tabInfoAnnotation.container().getCanonicalName();
        } else {
            targetNameToken = tabInfoMethod.getNameToken();
            tabContainerClassName = tabInfoMethod.getTabContainerClassName();
        }
        ensureNameTokenIsValid();
        findTabContainerClass();
        findRequestTabsFieldName();
        findChangeTabFieldName();
    }

    private void findRequestTabsFieldName() throws UnableToCompleteException {
        ClassInspector tabContainerInspector = new ClassInspector(logger, tabContainerClass);
        List requestTabsFields = new ArrayList();
        tabContainerInspector.collectStaticAnnotatedFields(classCollection.typeClass,
                classCollection.requestTabsHandlerClass, RequestTabs.class, requestTabsFields);
        if (requestTabsFields.size() == 0) {
            logger.log(TreeLogger.ERROR, "Did not find any static field annotated with @"
                    + RequestTabs.class.getSimpleName() + " on the container '"
                    + tabContainerClassName + "' while building proxy for presenter '"
                    + presenterInspector.getPresenterClassName() + "'.", null);
            throw new UnableToCompleteException();
        }
        if (requestTabsFields.size() > 1) {
            logger.log(TreeLogger.ERROR, "Found the annotation @" + RequestTabs.class.getSimpleName()
                    + " on more than one field in '" + tabContainerClassName
                    + "'. This is not allowed.", null);
            throw new UnableToCompleteException();
        }
        requestTabsFieldName = requestTabsFields.get(0).getName();
    }

    private void findChangeTabFieldName() throws UnableToCompleteException {
        ClassInspector tabContainerInspector = new ClassInspector(logger, tabContainerClass);
        List changeTabFields = new ArrayList();
        tabContainerInspector.collectStaticAnnotatedFields(classCollection.typeClass,
                classCollection.changeTabHandlerClass, ChangeTab.class, changeTabFields);
        if (changeTabFields.size() > 1) {
            logger.log(TreeLogger.ERROR, "Found the annotation @" + ChangeTab.class.getSimpleName()
                    + " on more than one field in '" + tabContainerClassName
                    + "'. This is not allowed.", null);
            throw new UnableToCompleteException();
        }
        if (changeTabFields.size() == 0) {
            changeTabFieldName = null;
        } else {
            changeTabFieldName = changeTabFields.get(0).getName();
        }
    }

    private void findTabContainerClass() throws UnableToCompleteException {
        if (tabContainerClassName == null) {
            logger.log(TreeLogger.ERROR, "The @" + TabInfo.class.getSimpleName()
                    + " in " + presenterInspector.getPresenterClassName()
                    + " must define the 'container' parameter.", null);
            throw new UnableToCompleteException();
        }

        tabContainerClass = oracle.findType(tabContainerClassName);
        if (tabContainerClass == null) {
            logger.log(TreeLogger.ERROR, "The container '" + tabContainerClassName + "' in @"
                    + TabInfo.class.getSimpleName() + " for '" + presenterInspector.getPresenterClassName()
                    + "' was not found.", null);
            throw new UnableToCompleteException();
        }
    }

    private void ensureNameTokenIsValid() throws UnableToCompleteException {
        if (targetNameToken.length() == 0) {
            targetNameToken = null;
        }

        if (targetNameToken != null && nameToken != null) {
            logger.log(TreeLogger.ERROR, "The @" + TabInfo.class.getSimpleName() + " in "
                    + presenterInspector.getPresenterClassName() + " defines the 'nameToken' parameter but "
                    + "its proxy is a place, this is not permitted.", null);
            throw new UnableToCompleteException();
        }
        if (targetNameToken == null && nameToken == null) {
            logger.log(TreeLogger.ERROR, "The @" + TabInfo.class.getSimpleName() + " in "
                    + presenterInspector.getPresenterClassName() + " does not define the 'nameToken' "
                    + "parameter and its proxy is not a place, this is not permitted.", null);
            throw new UnableToCompleteException();
        }
    }

    private void findTabLabel(TabInfo tabInfoAnnotation)
            throws UnableToCompleteException {
        if (tabInfoAnnotation.label().length() > 0) {
            tabLabel = tabInfoAnnotation.label();
        }

        if (tabLabel == null) {
            logger.log(TreeLogger.ERROR, "The @" + TabInfo.class.getSimpleName()
                    + " annotating a proxy in " + presenterInspector.getPresenterClassName()
                    + " must define the 'label' parameter.", null);
            throw new UnableToCompleteException();
        }
    }

    private void findTabPriority(TabInfo tabInfoAnnotation) {
        tabPriority = tabInfoAnnotation.priority();
        if (tabPriority < 0) {
            tabPriority = null;
        }
    }

    private void ensureExactlyOneTabInfoAnnotation(TabInfo tabInfoAnnotation)
            throws UnableToCompleteException {
        if (tabInfoAnnotation != null && tabInfoMethod != null) {
            logger.log(TreeLogger.ERROR, "Presenter " + presenterInspector.getPresenterClassName()
                    + " contains both a proxy and a method annotated with @' +"
                    + TabInfo.class.getSimpleName() + ". This is illegal.", null);
            throw new UnableToCompleteException();
        }
        if (tabInfoAnnotation == null && tabInfoMethod == null) {
            logger.log(TreeLogger.ERROR, "The proxy for '" + presenterInspector.getPresenterClassName()
                    + "' is a NonLeafTabContentProxy but is not annotated with @' +"
                    + TabInfo.class.getSimpleName()
                    + " and its presenter has no method annotated with it either.", null);
            throw new UnableToCompleteException();
        }
    }

    @Override
    void addSubclassImports(ClassSourceFileComposerFactory composerFactory) {
    }

    private String getTargetNameToken() {
        if (targetNameToken != null) {
            return targetNameToken;
        }
        return nameToken;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy