/* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * 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 org.uberfire.annotations.processors; import java.io.BufferedWriter; import java.io.IOException; import java.io.StringWriter; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; import javax.lang.model.util.Elements; import javax.tools.Diagnostic.Kind; import freemarker.template.Template; import freemarker.template.TemplateException; import org.uberfire.annotations.processors.exceptions.GenerationException; import org.uberfire.annotations.processors.facades.ClientAPIModule; /** * A source code generator for Activities */ public class ScreenActivityGenerator extends AbstractGenerator { @Override public StringBuffer generate(final String packageName, final PackageElement packageElement, final String className, final Element element, final ProcessingEnvironment processingEnvironment) throws GenerationException { final Messager messager = processingEnvironment.getMessager(); messager.printMessage(Kind.NOTE, "Starting code generation for [" + className + "]"); final Elements elementUtils = processingEnvironment.getElementUtils(); //Extract required information final TypeElement classElement = (TypeElement) element; final String annotationName = ClientAPIModule.getWorkbenchScreenClass(); final boolean isDynamic = ClientAPIModule.getWbScreenIsDynamicValueOnClass(classElement); String identifier = null; Integer preferredHeight = null; Integer preferredWidth = null; for (final AnnotationMirror am : classElement.getAnnotationMirrors()) { if (annotationName.equals(am.getAnnotationType().toString())) { for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : am.getElementValues().entrySet()) { AnnotationValue aval = entry.getValue(); if ("identifier".equals(entry.getKey().getSimpleName().toString())) { identifier = aval.getValue().toString(); } else if ("preferredHeight".equals(entry.getKey().getSimpleName().toString())) { final int _preferredHeight = (Integer) aval.getValue(); if (_preferredHeight > 0) { preferredHeight = _preferredHeight; } } else if ("preferredWidth".equals(entry.getKey().getSimpleName().toString())) { final int _preferredWidth = (Integer) aval.getValue(); if (_preferredWidth > 0) { preferredWidth = _preferredWidth; } } } break; } } final String owningPlace = GeneratorUtils.getOwningPerspectivePlaceRequest(classElement, processingEnvironment); final String beanActivatorClass = GeneratorUtils.getBeanActivatorClassName(classElement, processingEnvironment); final ExecutableElement onStartupMethod = GeneratorUtils.getOnStartupMethodForNonEditors(classElement, processingEnvironment); final String onStartup0ParameterMethodName; final String onStartup1ParameterMethodName; if (onStartupMethod == null) { onStartup0ParameterMethodName = null; onStartup1ParameterMethodName = null; } else if (onStartupMethod.getParameters().isEmpty()) { onStartup0ParameterMethodName = onStartupMethod.getSimpleName().toString(); onStartup1ParameterMethodName = null; } else { onStartup0ParameterMethodName = null; onStartup1ParameterMethodName = onStartupMethod.getSimpleName().toString(); } final String onMayCloseMethodName = GeneratorUtils.getOnMayCloseMethodName(classElement, processingEnvironment); final String onCloseMethodName = GeneratorUtils.getOnCloseMethodName(classElement, processingEnvironment); final String onShutdownMethodName = GeneratorUtils.getOnShutdownMethodName(classElement, processingEnvironment); final String onOpenMethodName = GeneratorUtils.getOnOpenMethodName(classElement, processingEnvironment); final String onLostFocusMethodName = GeneratorUtils.getOnLostFocusMethodName(classElement, processingEnvironment); final String onFocusMethodName = GeneratorUtils.getOnFocusMethodName(classElement, processingEnvironment); final String getDefaultPositionMethodName = GeneratorUtils.getDefaultPositionMethodName(classElement, processingEnvironment); final String getTitleMethodName = GeneratorUtils.getTitleMethodName(classElement, processingEnvironment); final String getContextIdMethodName = GeneratorUtils.getContextIdMethodName(classElement, processingEnvironment); final ExecutableElement getTitleWidgetMethod = GeneratorUtils.getTitleWidgetMethodName(classElement, processingEnvironment); final String getTitleWidgetMethodName = getTitleWidgetMethod == null ? null : getTitleWidgetMethod.getSimpleName().toString(); final boolean isTitleWidgetMethodReturnTypeElement = getTitleWidgetMethod != null && GeneratorUtils.getIsElement(getTitleWidgetMethod.getReturnType(), processingEnvironment); final ExecutableElement getWidgetMethod = GeneratorUtils.getWidgetMethodName(classElement, processingEnvironment); final String getWidgetMethodName = getWidgetMethod == null ? null : getWidgetMethod.getSimpleName().toString(); final boolean isWidgetMethodReturnTypeElement = getWidgetMethod != null && GeneratorUtils.getIsElement(getWidgetMethod.getReturnType(), processingEnvironment); final boolean hasUberView = GeneratorUtils.hasUberViewReference(classElement, processingEnvironment, getWidgetMethod); final boolean hasUberElement = GeneratorUtils.hasUberElementReference(classElement, processingEnvironment, getWidgetMethod); final boolean isWidget = GeneratorUtils.getIsWidget(classElement, processingEnvironment); final String getMenuBarMethodName = GeneratorUtils.getMenuBarMethodName(classElement, processingEnvironment); final String getToolBarMethodName = GeneratorUtils.getToolBarMethodName(classElement, processingEnvironment); final boolean needsElementWrapper = isWidgetMethodReturnTypeElement || isTitleWidgetMethodReturnTypeElement; final List<String> qualifiers = GeneratorUtils.getAllQualifiersDeclarationFromType(classElement); if (GeneratorUtils.debugLoggingEnabled()) { messager.printMessage(Kind.NOTE, "Package name: " + packageName); messager.printMessage(Kind.NOTE, "Class name: " + className); messager.printMessage(Kind.NOTE, "Identifier: " + identifier); messager.printMessage(Kind.NOTE, "Owning Perspective Identifier: " + owningPlace); messager.printMessage(Kind.NOTE, "Preferred Height: " + preferredHeight); messager.printMessage(Kind.NOTE, "Preferred Width: " + preferredWidth); messager.printMessage(Kind.NOTE, "getContextIdMethodName: " + getContextIdMethodName); messager.printMessage(Kind.NOTE, "onStartup0ParameterMethodName: " + onStartup0ParameterMethodName); messager.printMessage(Kind.NOTE, "onStartup1ParameterMethodName: " + onStartup1ParameterMethodName); messager.printMessage(Kind.NOTE, "onMayCloseMethodName: " + onMayCloseMethodName); messager.printMessage(Kind.NOTE, "onCloseMethodName: " + onCloseMethodName); messager.printMessage(Kind.NOTE, "onShutdownMethodName: " + onShutdownMethodName); messager.printMessage(Kind.NOTE, "onOpenMethodName: " + onOpenMethodName); messager.printMessage(Kind.NOTE, "onLostFocusMethodName: " + onLostFocusMethodName); messager.printMessage(Kind.NOTE, "onFocusMethodName: " + onFocusMethodName); messager.printMessage(Kind.NOTE, "getDefaultPositionMethodName: " + getDefaultPositionMethodName); messager.printMessage(Kind.NOTE, "getTitleMethodName: " + getTitleMethodName); messager.printMessage(Kind.NOTE, "getTitleWidgetMethodName: " + getTitleWidgetMethodName); messager.printMessage(Kind.NOTE, "isTitleWidgetMethodReturnTypeElement: " + isTitleWidgetMethodReturnTypeElement); messager.printMessage(Kind.NOTE, "getWidgetMethodName: " + getWidgetMethodName); messager.printMessage(Kind.NOTE, "isWidgetMethodReturnTypeElement: " + isWidgetMethodReturnTypeElement); messager.printMessage(Kind.NOTE, "isWidget: " + Boolean.toString(isWidget)); messager.printMessage(Kind.NOTE, "hasUberView: " + Boolean.toString(hasUberView)); messager.printMessage(Kind.NOTE, "hasUberElement: " + Boolean.toString(hasUberElement)); messager.printMessage(Kind.NOTE, "needsElementWrapper: " + Boolean.toString(needsElementWrapper)); messager.printMessage(Kind.NOTE, "getMenuBarMethodName: " + getMenuBarMethodName); messager.printMessage(Kind.NOTE, "getToolBarMethodName: " + getToolBarMethodName); messager.printMessage(Kind.NOTE, "Qualifiers: " + String.join(", ", qualifiers)); } //Validate getWidgetMethodName and isWidget if (!isWidget && getWidgetMethodName == null) { throw new GenerationException("The WorkbenchScreen must either extend IsWidget or provide a @WorkbenchPartView annotated method to return a com.google.gwt.user.client.ui.IsWidget or preferably org.jboss.errai.common.client.api.IsElement.", packageName + "." + className); } if (isWidget && getWidgetMethodName != null) { final String msg = "The WorkbenchScreen both extends com.google.gwt.user.client.ui.IsWidget and provides a @WorkbenchPartView annotated method. The annotated method will take precedence."; messager.printMessage(Kind.WARNING, msg, classElement); } //Validate getTitleMethodName and getTitleWidgetMethodName if (getTitleMethodName == null) { throw new GenerationException("The WorkbenchScreen must provide a @WorkbenchPartTitle annotated method to return a java.lang.String.", packageName + "." + className); } //Setup data for template sub-system Map<String, Object> root = new HashMap<String, Object>(); root.put("packageName", packageName); root.put("className", className); root.put("identifier", identifier); root.put("owningPlace", owningPlace); root.put("preferredHeight", preferredHeight); root.put("preferredWidth", preferredWidth); root.put("getContextIdMethodName", getContextIdMethodName); root.put("realClassName", classElement.getSimpleName().toString()); root.put("beanActivatorClass", beanActivatorClass); root.put("onStartup0ParameterMethodName", onStartup0ParameterMethodName); root.put("onStartup1ParameterMethodName", onStartup1ParameterMethodName); root.put("onMayCloseMethodName", onMayCloseMethodName); root.put("onCloseMethodName", onCloseMethodName); root.put("onShutdownMethodName", onShutdownMethodName); root.put("onOpenMethodName", onOpenMethodName); root.put("onLostFocusMethodName", onLostFocusMethodName); root.put("onFocusMethodName", onFocusMethodName); root.put("getDefaultPositionMethodName", getDefaultPositionMethodName); root.put("getTitleMethodName", getTitleMethodName); root.put("getTitleWidgetMethodName", getTitleWidgetMethodName); root.put("isTitleWidgetMethodReturnTypeElement", isTitleWidgetMethodReturnTypeElement); root.put("getWidgetMethodName", getWidgetMethodName); root.put("isWidgetMethodReturnTypeElement", isWidgetMethodReturnTypeElement); root.put("isWidget", isWidget); root.put("hasUberView", hasUberView); root.put("hasUberElement", hasUberElement); root.put("needsElementWrapper", needsElementWrapper); root.put("getMenuBarMethodName", getMenuBarMethodName); root.put("getToolBarMethodName", getToolBarMethodName); root.put("isDynamic", isDynamic); root.put("qualifiers", qualifiers); //Generate code final StringWriter sw = new StringWriter(); final BufferedWriter bw = new BufferedWriter(sw); try { final Template template = config.getTemplate("activityScreen.ftl"); template.process(root, bw); } catch (IOException ioe) { throw new GenerationException(ioe); } catch (TemplateException te) { throw new GenerationException(te); } finally { try { bw.close(); sw.close(); } catch (IOException ioe) { throw new GenerationException(ioe); } } messager.printMessage(Kind.NOTE, "Successfully generated code for [" + className + "]"); return sw.getBuffer(); } }