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

org.nuiton.jaxx.compiler.JAXXEngine Maven / Gradle / Ivy

The newest version!
/*
 * #%L
 * JAXX :: Compiler
 * %%
 * Copyright (C) 2008 - 2024 Code Lutin, Ultreia.io
 * %%
 * 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.compiler;

import io.ultreia.java4all.i18n.spi.builder.I18nKeySet;
import io.ultreia.java4all.i18n.spi.builder.I18nModuleNotInitializedException;
import io.ultreia.java4all.lang.Strings;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.nuiton.jaxx.compiler.finalizers.I18nKeysFileModel;
import org.nuiton.jaxx.compiler.reflect.ClassDescriptor;
import org.nuiton.jaxx.compiler.reflect.ClassDescriptorHelper;
import org.nuiton.jaxx.compiler.reflect.FieldDescriptor;
import org.nuiton.jaxx.compiler.reflect.MethodDescriptor;
import org.nuiton.jaxx.compiler.tasks.CompileFirstPassTask;
import org.nuiton.jaxx.compiler.tasks.CompileSecondPassTask;
import org.nuiton.jaxx.compiler.tasks.FinalizeTask;
import org.nuiton.jaxx.compiler.tasks.GenerateConstructorsTask;
import org.nuiton.jaxx.compiler.tasks.GenerateMissingRulesTask;
import org.nuiton.jaxx.compiler.tasks.GenerateTask;
import org.nuiton.jaxx.compiler.tasks.InitTask;
import org.nuiton.jaxx.compiler.tasks.JAXXEngineTask;
import org.nuiton.jaxx.compiler.tasks.ProfileTask;
import org.nuiton.jaxx.compiler.tasks.StyleSheetTask;

import java.beans.Introspector;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;

/**
 * The engine to compile jaxx files.
 * 

* The method {@link #run()} launch the compilation of files. * * @author Tony Chemit - [email protected] * @since 2.0.0 was previously JAXXCompilerLaunchor */ @SuppressWarnings("unused") public class JAXXEngine { /** Logger */ private static final Logger log = LogManager.getLogger(JAXXEngine.class); /** configuration of the launchor and underlines compilers */ protected final CompilerConfiguration configuration; /** original list of files to compile (says the detected modfied files) */ protected final JAXXCompilerFile[] incomingFiles; /** Files to compile */ protected final List compilingFiles; /** Warnings detected while running. */ protected final List warnings; /** Errors detected while running. */ protected final List errors; /** To manage i18n keys. */ private final I18nKeySet getterFile; /** * */ private final Map i18nPropertyMapping; private final Map i18nKeys = new TreeMap<>(); /** tasks to launch */ protected JAXXEngineTask[] tasks; /** current pass of the engine */ protected JAXXEngineTask currentTask; /** profile attached to the engine (can be null) */ protected JAXXProfile profiler; private Class validatorFactory; private ClassDescriptor validatorFactoryClass; protected JAXXEngine(CompilerConfiguration configuration, File base, String... relativePaths) { if (configuration == null) { // use a default configuration configuration = new DefaultCompilerConfiguration(); } this.configuration = configuration; warnings = new ArrayList<>(); errors = new ArrayList<>(); compilingFiles = new ArrayList<>(); i18nPropertyMapping = new TreeMap<>(); if (configuration.isShowClassDescriptorLoading()) { ClassDescriptorHelper.setShowLoading(true); } // add all default files to compile for (String relativePath : relativePaths) { JAXXCompilerFile compilerFile = new JAXXCompilerFile(base, new File(base, relativePath), configuration.getCssExtension()); addFileToCompile(compilerFile); } if (configuration.getI18nModule() != null) { try { this.getterFile = configuration.getI18nModule().getModuleKeySet("jaxx"); } catch (I18nModuleNotInitializedException e) { throw new RuntimeException("No i18n configuration found, please invoke mojo i18n:init"); } } else { this.getterFile = null; } // fix once for all incoming files to compile incomingFiles = compilingFiles.toArray(new JAXXCompilerFile[0]); JAXXCompiler.commonCssDetectedCount = 0; } public JAXXEngineTask[] getTasks() { if (tasks == null) { List tasks = new ArrayList<>(); tasks.add(new InitTask()); tasks.add(new CompileFirstPassTask()); tasks.add(new CompileSecondPassTask()); tasks.add(new StyleSheetTask()); tasks.add(new FinalizeTask()); tasks.add(new GenerateConstructorsTask()); tasks.add(new GenerateTask()); if (getConfiguration().isGenerateMissingIdsAndStyleClassesInCss()) { tasks.add(new GenerateMissingRulesTask()); } if (getConfiguration().isProfile()) { tasks.add(new ProfileTask()); } this.tasks = tasks.toArray(new JAXXEngineTask[0]); } return tasks; } /** @return the errors of the engine */ public List getErrors() { return errors; } /** @return the warnings of the engine */ public List getWarnings() { return warnings; } public JAXXProfile getProfiler() { if (profiler == null && getConfiguration().isProfile()) { profiler = new JAXXProfile(); } return profiler; } public CompilerConfiguration getConfiguration() { return configuration; } public JAXXCompilerFile[] getFilesToCompile() { List files = new ArrayList<>(); for (JAXXCompilerFile file : compilingFiles) { if (file.getCompiler() == null) { files.add(file); } } return files.toArray(new JAXXCompilerFile[0]); } public JAXXCompilerFile[] getCompiledFiles() { List files = new ArrayList<>(); for (JAXXCompilerFile file : compilingFiles) { if (file.getCompiler() != null) { files.add(file); } } // always send a copy to be safe. return files.toArray(new JAXXCompilerFile[0]); } public boolean containsJaxxFileClassName(String className) { for (JAXXCompilerFile file : compilingFiles) { if (className.equals(file.getClassName())) { return true; } } return false; } public boolean isCompileFirstPassTask() { return currentTask != null && CompileFirstPassTask.TASK_NAME.equals(currentTask.getName()); } /** * Resets all state in preparation for a new compilation session. * * @param cleanReports should we also clean reports ? */ protected void reset(boolean cleanReports) { for (JAXXCompilerFile compilerFile : compilingFiles) { compilerFile.clear(); } compilingFiles.clear(); if (profiler != null) { profiler.clear(); profiler = null; } if (cleanReports) { clearReports(); } ClassDescriptorHelper.setShowLoading(false); } public void clearReports() { getWarnings().clear(); getErrors().clear(); } public String getVersion() { return "2.4"; } /** * Obtain the jaxx compiler of the given class name. * * @param className the name of the class to use * @return the compiler instance which is processing the specified JAXX class. * Each class is compiled by a different compiler instance. */ public JAXXCompilerFile getJAXXCompilerFile(String className) { for (JAXXCompilerFile compilingFile : compilingFiles) { if (className.equals(compilingFile.getClassName())) { return compilingFile; } } return null; } /** * Obtain the jaxx compiler of the given class name. * * @param className the name of the class to use * @return the compiler instance which is processing the specified JAXX class. * Each class is compiled by a different compiler instance. */ public JAXXCompiler getJAXXCompiler(String className) { JAXXCompilerFile compilerFile = getJAXXCompilerFile(className); if (compilerFile == null) { return null; } return compilerFile.getCompiler(); } /** * Obtain the decorator of the given name. * * @param name the name of the decorator * @return the decorator found. * @throws IllegalArgumentException if decorator not found for the given name. */ public CompiledObjectDecorator getDecorator(String name) throws IllegalArgumentException { Map decorators = getConfiguration().getDecorators(); CompiledObjectDecorator decorator = decorators.get(name); if (decorator == null) { throw new IllegalArgumentException( "could not find decorator with key " + name + " (known decorators : " + decorators.keySet() + ")"); } return decorator; } /** * Obtain the decorator of the given type. * * @param type the type of the decorator (syas his fqn) * @return the decorator found */ public CompiledObjectDecorator getDecorator(Class type) { Map decorators = getConfiguration().getDecorators(); for (CompiledObjectDecorator decorator : decorators.values()) { if (decorator.getClass().equals(type)) { return decorator; } } return null; } /** * Add a warning to the engine. * * @param warning the warning to add */ public void addWarning(String warning) { warnings.add(warning); } /** * Add an error to the engine. * * @param error the error to add */ public void addError(String error) { errors.add(error); } /** * Compiled a set of files. * * @return {@code -1} if errors appears, the number of generated files * otherwise. */ public int run() { try { boolean success = true; for (JAXXEngineTask task : getTasks()) { if (!success) { // stop as soon as a engine phase failed break; } currentTask = task; long t0 = System.nanoTime(); if (isVerbose()) { log.info("Start task '" + task.getName() + "' on " + compilingFiles.size() + " file(s)"); } success = task.perform(this); if (isVerbose()) { log.info("task '" + task.getName() + "' done in " + Strings.convertTime(System.nanoTime() - t0) ); } } return success ? compilingFiles.size() : -1; //FIXME : deal better the exception treatment... } catch (Throwable e) { log.error(e.getMessage(), e); return -1; } finally { if (configuration.isResetAfterCompile()) { reset(false); } } } /** * Adds a {@code file} to be compiled. * * @param file the {@link JAXXCompilerFile} to add. */ public void addFileToCompile(JAXXCompilerFile file) { if (isVerbose()) { log.info("register jaxx file " + file.getJaxxFile()); } compilingFiles.add(file); } /** * Adds a {@link JAXXCompilerFile} given the jaxx file and the * corresponding class fully qualified name. * * @param jaxxFile the jaxx file location * @param jaxxClassName the fully qualified name of the jaxx class */ public void addFileToCompile(File jaxxFile, String jaxxClassName) { if (log.isDebugEnabled()) { log.debug("file = " + jaxxFile + ", fqn = " + jaxxClassName); } JAXXCompilerFile file = new JAXXCompilerFile(jaxxFile, jaxxClassName, configuration.getCssExtension()); addFileToCompile(file); } /** * Create a new compiler and attach it to the given {@code jaxxFile}. * * @param jaxxFile the definition of jaxx file to compile * @return the new compiler * @throws Exception if any pb while creating of compiler */ public JAXXCompiler newCompiler(JAXXCompilerFile jaxxFile) throws Exception { Class compilerClass = getConfiguration().getCompilerClass(); if (compilerClass == null) { throw new NullPointerException( "Configuration compilerClass is null"); } Constructor cons = compilerClass.getConstructor( JAXXEngine.class, JAXXCompilerFile.class, List.class ); /* Arrays.asList( "java.awt.*", "java.awt.event.*", "java.io.*", "java.lang.*", "java.util.*", "javax.swing.*", "javax.swing.border.*", "javax.swing.event.*", "jaxx.runtime.*", "jaxx.runtime.swing.*", "static io.ultreia.java4all.i18n.I18n.t", "static org.nuiton.jaxx.runtime.swing.SwingUtil.createImageIcon" ) */ JAXXCompiler jaxxCompiler = (JAXXCompiler) cons.newInstance( this, jaxxFile, Arrays.asList( "java.awt.*", // "java.awt.event.*", // "java.io.*", "java.lang.*", // "java.util.*", "javax.swing.*", "javax.swing.border.*", // "javax.swing.event.*", // "jaxx.runtime.*", "org.nuiton.jaxx.runtime.swing.*" ) ); jaxxFile.setCompiler(jaxxCompiler); return jaxxCompiler; } public boolean isVerbose() { return getConfiguration().isVerbose(); } /** * Add a profile time for the given compiler and key. *

* Note: if {@link #profiler} is {@code null}, do nothing * * @param compiler the compiler to profile * @param key the key of profiling */ public void addProfileTime(JAXXCompiler compiler, String key) { JAXXProfile profiler = getProfiler(); if (profiler != null) { profiler.addTime(compiler, key); } } String getI18nProperty(ClassDescriptor objectClass) { String className = objectClass.getName(); String result = i18nPropertyMapping.get(className); if (result == null) { Optional field = Optional.empty(); for (String i18nAttribute : I18nHelper.I18N_ATTRIBUTES) { field = objectClass.tryToGetFieldDescriptor(i18nAttribute); if (field.isPresent()) { break; } } if (field.isPresent()) { result = field.get().getName(); if (isVerbose()) { log.info(String.format("Discover i18n property: %s for %s", result, className)); } i18nPropertyMapping.put(className, result); } else { Optional method = Optional.empty(); for (String i18nAttribute : I18nHelper.I18N_ATTRIBUTES) { method = objectClass.tryToGetSetterMethodDescriptor(i18nAttribute); if (method.isPresent()) { break; } } if (method.isPresent()) { result = Introspector.decapitalize(StringUtils.removeStart(method.get().getName(), "set")); if (isVerbose()) { log.info(String.format("Discover i18n property: %s for %s", result, className)); } i18nPropertyMapping.put(className, result); } else { throw new IllegalStateException(String.format("Can't find i18n property for type: %s", className)); } } } return result; } public void registerI18nKey(String key) { getterFile.addKey(key); } public void flushI18nGetterFile() throws IOException { if (getterFile != null) { configuration.getI18nModule().storeModuleKeySet(getterFile); } } public Class getValidatorFactory() { try { return validatorFactory == null ? validatorFactory = Class.forName(getConfiguration().getValidatorFactoryFQN(), false, getConfiguration().getClassLoader()) : validatorFactory; } catch (ClassNotFoundException e) { throw new IllegalStateException("Can't find validator class", e); } } public ClassDescriptor getValidatorFactoryClass() { try { return validatorFactoryClass == null ? validatorFactoryClass = ClassDescriptorHelper.getClassDescriptor(getConfiguration().getValidatorFactoryFQN(), getConfiguration().getClassLoader()) : validatorFactoryClass; } catch (ClassNotFoundException e) { throw new IllegalStateException(e); } } public I18nKeysFileModel getI18nKeysFileModel(String fqn, boolean loadIfNotFound) { I18nKeysFileModel result = i18nKeys.get(fqn); if (result == null && loadIfNotFound) { result = I18nKeysFileModel.of(getConfiguration().getClassLoader(), fqn, getConfiguration().isVerbose()); if (result != null) { i18nKeys.put(fqn, result); } } return result; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy