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

org.nuiton.jaxx.plugin.GenerateMojo Maven / Gradle / Ivy

There is a newer version: 3.0-alpha-6
Show newest version
/*
 * #%L
 * JAXX :: Maven plugin
 * 
 * $Id: GenerateMojo.java 2490 2012-08-11 07:57:06Z tchemit $
 * $HeadURL: http://svn.nuiton.org/svn/jaxx/tags/jaxx-2.5.23/jaxx-maven-plugin/src/main/java/org/nuiton/jaxx/plugin/GenerateMojo.java $
 * %%
 * Copyright (C) 2008 - 2010 CodeLutin
 * %%
 * This program 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.
 * 
 * This program 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 General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */

package org.nuiton.jaxx.plugin;

import jaxx.compiler.CompiledObjectDecorator;
import jaxx.compiler.CompilerConfiguration;
import jaxx.compiler.I18nHelper;
import jaxx.compiler.JAXXCompiler;
import jaxx.compiler.JAXXEngine;
import jaxx.compiler.JAXXFactory;
import jaxx.compiler.beans.BeanInfoUtil;
import jaxx.compiler.binding.DataBindingHelper;
import jaxx.compiler.finalizers.JAXXCompilerFinalizer;
import jaxx.compiler.spi.DefaultInitializer;
import jaxx.compiler.spi.Initializer;
import jaxx.runtime.JAXXContext;
import jaxx.runtime.JAXXObject;
import jaxx.runtime.swing.help.JAXXHelpBroker;
import jaxx.runtime.validator.swing.SwingValidator;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.nuiton.i18n.I18n;
import org.nuiton.io.MirroredFileUpdater;
import org.nuiton.plugin.PluginHelper;

import java.beans.Introspector;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Generates some java code from jaxx files.
 *
 * @author tchemit 
 */
@Mojo(name = "generate", defaultPhase = LifecyclePhase.PROCESS_SOURCES,
      requiresDependencyResolution = ResolutionScope.COMPILE, requiresProject = true)
public class GenerateMojo extends AbstractJaxxMojo implements CompilerConfiguration {

    /** Default includes to use, if none provided */
    private static final String[] INCLUDES = {"**/*.jaxx", "**/*.css"};

    /**
     * Directory where jaxx files are located.
     */
    @Parameter(property = "jaxx.src", defaultValue = "${basedir}/src/main/java")
    protected File src;

    /**
     * Where to generate java files.
     */
    @Parameter(property = "jaxx.outJava", defaultValue = "${basedir}/target/generated-sources/java")
    protected File outJava;

    /**
     * To filter file to treat.
     */
    @Parameter(property = "jaxx.includes")
    protected String[] includes;

    /**
     * To filter files to NOt treat.
     */
    @Parameter(property = "jaxx.excludes")
    protected String[] excludes;

    /**
     * FQN of compiler to use (by default swing one).
     */
    @Parameter(property = "jaxx.compilerFQN", defaultValue = "jaxx.compiler.JAXXCompiler", required = true)
    protected String compilerFQN;

    /**
     * The name of implementation of {@link JAXXContext}to be used on {@link JAXXObject}.
     * 

* Must not be abstract. */ @Parameter(property = "jaxx.jaxxContextFQN", defaultValue = "jaxx.runtime.context.DefaultJAXXContext", required = true) protected String jaxxContextFQN; /** * The FQN of the ui to use for error notification. *

* If not given, will use the one defined in validator */ @Parameter(property = "jaxx.defaultErrorUIFQN") protected String defaultErrorUIFQN; /** * The FQN of the ui to use for error notification. *

* If not given, will use the one defined in validator * * @see CompiledObjectDecorator */ @Parameter(property = "jaxx.defaultDecoratorFQN", defaultValue = "jaxx.compiler.decorators.DefaultCompiledObjectDecorator") protected String defaultDecoratorFQN; /** * Flag to include in compiler classpath the java sources directories (src * and outJava). *

* By default, false. */ @Parameter(property = "jaxx.addSourcesToClassPath", defaultValue = "false") protected boolean addSourcesToClassPath; /** * Flag to include in compiler classpath the java resources directories (src * and outJava). *

* By default, false. * * @since 1.6.0 */ @Parameter(property = "jaxx.addResourcesToClassPath", defaultValue = "false") protected boolean addResourcesToClassPath; /** * Flag to include in compiler classpath the compile class-path (can only be * used in a test phase). *

* By default, false. * * @since 1.6.0 */ @Parameter(property = "jaxx.addCompileClassPath", defaultValue = "false") protected boolean addCompileClassPath; /** * Flag to include in compiler classpath the project compile classpath. *

* By default, false. */ @Parameter(property = "jaxx.addProjectClassPath", defaultValue = "false") protected boolean addProjectClassPath; /** * A flag to mark the mojo to be used in a test phase. This will permits to * add generated sources in test compile roots. * * @since 1.6.0 */ @Parameter(property = "jaxx.testPhase", defaultValue = "false") protected boolean testPhase; /** * To make compiler i18nable, says add the {@link I18n#_(String, Object...)} * method invocation on {@link I18nHelper#I18N_ATTRIBUTES} attributes. * * @see I18nHelper */ @Parameter(property = "jaxx.i18nable", defaultValue = "true") protected boolean i18nable; /** * To optimize generated code. */ @Parameter(property = "jaxx.optimize", defaultValue = "false") protected boolean optimize; /** * To auto import css files for a jaxx file. * * @since 2.0.2 */ @Parameter(property = "jaxx.autoImportCss", defaultValue = "false") protected boolean autoImportCss; /** * To let jaxx recurses in css when a JAXX Object auto import css files * for a jaxx file. *

* Warning: This option will be removed in version 3.0 or at least * default value will become {@code false}. * * @since 2.0.2 */ @Parameter(property = "jaxx.autoRecurseInCss", defaultValue = "true") protected boolean autoRecurseInCss; /** * Flag to add logger to each generated jaxx file. *

* By default, always add it. */ @Parameter(property = "jaxx.addLogger", defaultValue = "true") protected boolean addLogger; /** * Flag to keep compilers after the generate operation (usefull for tests. *

* By default, always reset. */ @Parameter(property = "jaxx.resetAfterCompile", defaultValue = "true") protected boolean resetAfterCompile; /** * Extra path to be added in {@link Introspector#setBeanInfoSearchPath(String[])}. *

* add beanInfoSearchPath to be registred by {@link BeanInfoUtil#addJaxxBeanInfoPath(String...)} *

* and then will be use by {@link DefaultInitializer#initialize()}. *

*

* This permit to use real beanInfo of imported graphic libraries. */ @Parameter(property = "jaxx.beanInfoSearchPath") protected String[] beanInfoSearchPath; /** * List of fqn of class toimport for all generated jaxx files. */ @Parameter(property = "jaxx.extraImportList") protected String extraImportList; /** * A flag to use UIManager to retreave icons. */ @Parameter(property = "jaxx.useUIManagerForIcon", defaultValue = "false") protected boolean useUIManagerForIcon; /** * flag to activate profile mode. *

* By default, not active. */ @Parameter(property = "jaxx.profile", defaultValue = "false") protected boolean profile; /** * To show detected bindings. *

* By default, do not show them. * * @since 2.0.0 */ @Parameter(property = "jaxx.showBinding", defaultValue = "false") protected boolean showBinding; /** * the FQN of help broker *

* By default, use the JAXX implementation {@link JAXXHelpBroker}. * * @since 1.3 */ @Parameter(property = "jaxx.helpBrokerFQN", defaultValue = "jaxx.runtime.swing.help.JAXXHelpBroker") protected String helpBrokerFQN; /** * the FQN of validator factory. *

* By default, use the JAXX implementation {@link SwingValidator}. * * @since 2.6 */ @Parameter(property = "jaxx.validatorFactoryFQN", defaultValue = "jaxx.runtime.validator.swing.SwingValidator") protected String validatorFactoryFQN; /** * To trace class descriptor loading. *

* By default, do not trace it. * * @since 2.4 */ @Parameter(property = "jaxx.showClassDescriptorLoading", defaultValue = "false") private boolean showClassDescriptorLoading; /** * Decorators available in engine. * * @since 2.0.2 */ @Component(role = CompiledObjectDecorator.class) protected Map decorators; /** * Finalizers available in engine. * * @since 2.0.2 */ @Component(role = JAXXCompilerFinalizer.class) protected Map finalizers; /** * Initializers available to init engine. * * @since 2.0.2 */ @Component(role = Initializer.class) protected Map initializers; /** detected jaxx files in {@link #init()} method */ protected String[] files; /** * file updater used to detect jaxx files. *

* Note: if {@link #verbose} flag is on, will ne be used */ protected MirroredFileUpdater updater; /** type of error ui class (in validation) to use */ private Class defaultErrorUIClass; /** type of {@link CompiledObjectDecorator} to use */ private Class defaultDecoratorClass; /** type of {@link JAXXContext} to use */ private Class jaxxContextClass; /** type of compiler to use */ private Class compilerClass; /** extra imports to always add in each generated java file */ private String[] extraImports; /** internal state to known if a files has to be generated */ private boolean nofiles; /** customized classloader to use in engine */ protected ClassLoader cl; /** JAXX engine */ private JAXXEngine engine; @SuppressWarnings("unchecked") @Override public void init() throws Exception { if (getLog().isDebugEnabled()) { // if debug is on, then verbose also setVerbose(true); } fixCompileSourceRoots(); if (includes == null || includes.length == 0) { // use default includes includes = INCLUDES; } updater = new JaxxFileUpdater(src, outJava); Map result = new HashMap(); getFilesToTreateForRoots( includes, excludes, Arrays.asList(src.getAbsolutePath()), result, isForce() ? null : updater); files = result.get(src); // Evolution #435: Regenerates jaxx files when his css file is modified // filter css and jaxx files to obtain only jaxx files // if a css is modified, try to find the corresponding jaxx files if (files != null && files.length > 0) { Set filterFiles = new HashSet(files.length); for (String path : files) { if (path.endsWith(".css")) { // take the jaxx file String jaxxFilePath = path.substring(0, path.length() - 4) + ".jaxx"; File f = new File(src, jaxxFilePath); if (f.exists()) { if (isVerbose()) { getLog().info("will treate jaxx file from css " + f); } filterFiles.add(jaxxFilePath); } else { getLog().warn("can not find jaxx file corresponding " + "to modified css file " + path); } continue; } if (path.endsWith(".jaxx")) { filterFiles.add(path); } } files = filterFiles.toArray(new String[filterFiles.size()]); } nofiles = files == null || files.length == 0; if (nofiles) { if (getLog().isDebugEnabled()) { getLog().debug("No file to treate."); } return; } cl = initClassLoader(getProject(), src, addSourcesToClassPath, testPhase, addResourcesToClassPath, addCompileClassPath, addProjectClassPath); Thread.currentThread().setContextClassLoader(cl); compilerClass = (Class) Class.forName(compilerFQN, false, cl); defaultDecoratorClass = (Class) Class.forName(defaultDecoratorFQN, false, cl); jaxxContextClass = (Class) Class.forName(jaxxContextFQN, false, cl); if (!JAXXContext.class.isAssignableFrom(jaxxContextClass)) { throw new MojoExecutionException( "jaxxContextFQN must be an implementation of " + JAXXContext.class + " but was : " + jaxxContextClass); } // validatorClass = Class.forName(validatorFQN, false, cl); if (defaultErrorUIFQN != null && !defaultErrorUIFQN.trim().isEmpty()) { defaultErrorUIClass = Class.forName(defaultErrorUIFQN, false, cl); } if (beanInfoSearchPath != null && beanInfoSearchPath.length > 0) { // register extra path BeanInfoUtil.addJaxxBeanInfoPath(beanInfoSearchPath); } createDirectoryIfNecessary(getTargetDirectory()); // compute extra imports (can not use java classes since some of // imports can not be still compiled) if (extraImportList != null && !extraImportList.isEmpty()) { String[] imports = extraImportList.split(","); int i = 0; for (String importS : imports) { imports[i++] = importS.trim(); } if (isVerbose()) { getLog().info("extra imports " + Arrays.toString(imports)); } extraImports = imports; } if (isVerbose()) { // getLog().info(toString()); getLog().info("includes : " + Arrays.toString(includes)); for (String file : files) { getLog().info("will parse " + file); } } } @Override protected boolean checkSkip() { if (nofiles) { getLog().info("Nothing to generate - all files are up to date."); return false; } return true; } @Override public void doAction() throws Exception { getLog().info("Detects " + files.length + " modified jaxx file(s). "); if (showBinding) { DataBindingHelper.SHOW_LOG = showBinding; } try { long t0 = System.nanoTime(); // register configuration to factory JAXXFactory.setConfiguration(this); // create new engine engine = JAXXFactory.newEngine(src, files); //FIXME-TC20100502 remove this managment by -1 for error! // run engine int nbFiles = engine.run(); // report engine results (errors, warnings,...) report(engine); if (nbFiles == -1) { throw new MojoExecutionException( "Aborting due to errors reported by jaxxc"); } String delay = PluginHelper.convertTime(System.nanoTime() - t0); getLog().info("Generated " + nbFiles + " file(s) in " + delay); } finally { DataBindingHelper.SHOW_LOG = false; } } @Override public File getTargetDirectory() { return outJava; } @Override public void setTargetDirectory(File targetDirectory) { outJava = targetDirectory; } @Override public boolean getOptimize() { return optimize; } @Override public boolean isAutoImportCss() { return autoImportCss; } @Override public boolean isAutoRecurseInCss() { return autoRecurseInCss; } @Override public boolean isI18nable() { return i18nable; } @Override public boolean isUseUIManagerForIcon() { return useUIManagerForIcon; } @Override public boolean isAddLogger() { return addLogger; } @Override public boolean isShowClassDescriptorLoading() { return showClassDescriptorLoading; } @Override public Class getJaxxContextClass() { return jaxxContextClass; } @Override public String[] getExtraImports() { return extraImports; } @Override public boolean isResetAfterCompile() { return resetAfterCompile; } @Override public boolean isOptimize() { return optimize; } @Override public Class getDefaultErrorUI() { return defaultErrorUIClass; } @Override public ClassLoader getClassLoader() { return cl; } @Override public Class getCompilerClass() { return compilerClass; } @Override public Class getDefaultDecoratorClass() { return defaultDecoratorClass; } @Override public boolean isProfile() { return profile; } @Override public boolean isGenerateHelp() { return generateHelp; } @Override public String getHelpBrokerFQN() { return helpBrokerFQN; } @Override public String getValidatorFactoryFQN() { return validatorFactoryFQN; } @Override public Map getDecorators() { return decorators; } @Override public Map getFinalizers() { return finalizers; } @Override public Map getInitializers() { return initializers; } public JAXXEngine getEngine() { return engine; } @Override public String toString() { return ToStringBuilder.reflectionToString( this, ToStringStyle.MULTI_LINE_STYLE); } protected void fixCompileSourceRoots() { //FIXME TC20091222 : why this test ? should always have a project ? // even in tests... if (getProject() == null) { // no project defined, can not fix anything // this case could appear if we wanted to do some tests of the plugin return; } if (testPhase) { addTestCompileSourceRoots(getTargetDirectory()); } else { addCompileSourceRoots(getTargetDirectory()); } } protected void report(JAXXEngine engine) { List warnings = engine.getWarnings(); if (!warnings.isEmpty()) { StringBuilder buffer = new StringBuilder( "JAXX detects " + (warnings.size() == 1 ? "1 warning" : warnings.size() + " warnings")); buffer.append(" :"); for (String s : warnings) { buffer.append("\n").append(s); } getLog().warn(buffer.toString()); } List errors = engine.getErrors(); if (!errors.isEmpty()) { StringBuilder buffer = new StringBuilder( "JAXX detects " + (errors.size() == 1 ? "1 error" : errors.size() + " errors")); buffer.append(" :"); for (String s : errors) { buffer.append("\n").append(s); } getLog().error(buffer.toString()); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy