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

com.vaadin.flow.plugin.maven.FlowModeAbstractMojo Maven / Gradle / Ivy

/*
 * Copyright 2000-2022 Vaadin Ltd.
 *
 * 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.vaadin.flow.plugin.maven;

import static com.vaadin.flow.server.Constants.VAADIN_SERVLET_RESOURCES;
import static com.vaadin.flow.server.Constants.VAADIN_WEBAPP_RESOURCES;
import static com.vaadin.flow.server.frontend.FrontendUtils.FRONTEND;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;

import com.vaadin.flow.plugin.base.BuildFrontendUtil;
import com.vaadin.flow.plugin.base.PluginAdapterBase;
import com.vaadin.flow.server.Constants;
import com.vaadin.flow.server.InitParameters;
import com.vaadin.flow.server.frontend.FrontendTools;
import com.vaadin.flow.server.frontend.installer.NodeInstaller;
import com.vaadin.flow.server.frontend.installer.Platform;
import com.vaadin.flow.server.frontend.scanner.ClassFinder;

/**
 * The base class of Flow Mojos in order to compute correctly the modes.
 *
 * @since 2.0
 */
public abstract class FlowModeAbstractMojo extends AbstractMojo
        implements PluginAdapterBase {

    /**
     * Additionally include compile-time-only dependencies matching the pattern.
     */
    public static final String INCLUDE_FROM_COMPILE_DEPS_REGEX = ".*(/|\\\\)(portlet-api|javax\\.servlet-api)-.+jar$";

    /**
     * Application properties file in Spring project.
     */
    @Parameter(defaultValue = "${project.basedir}/src/main/resources/application.properties")
    private File applicationProperties;

    /**
     * Whether or not insert the initial Uidl object in the bootstrap index.html
     */
    @Parameter(defaultValue = "${vaadin."
            + Constants.SERVLET_PARAMETER_INITIAL_UIDL + "}")
    private boolean eagerServerLoad;

    /**
     * A directory with project's frontend source files.
     */
    @Parameter(defaultValue = "${project.basedir}/" + FRONTEND)
    private File frontendDirectory;

    /**
     * The folder where flow will put generated files that will be used by
     * webpack.
     */
    @Parameter(defaultValue = "${project.build.directory}/" + FRONTEND)
    private File generatedFolder;

    /**
     * The folder where flow will put TS API files for client projects.
     */
    @Parameter(defaultValue = "${project.basedir}/" + FRONTEND + "/generated")
    private File generatedTsFolder;

    /**
     * Java source folders for scanning.
     */
    @Parameter(defaultValue = "${project.basedir}/src/main/java")
    private File javaSourceFolder;

    /**
     * Java resource folder.
     */
    @Parameter(defaultValue = "${project.basedir}/src/main/resources")
    private File javaResourceFolder;

    /**
     * Download node.js from this URL. Handy in heavily firewalled corporate
     * environments where the node.js download can be provided from an intranet
     * mirror. Defaults to null which will cause the downloader to use
     * {@link NodeInstaller#DEFAULT_NODEJS_DOWNLOAD_ROOT}.
     * 

*

* Example: "https://nodejs.org/dist/". */ @Parameter(property = InitParameters.NODE_DOWNLOAD_ROOT) private String nodeDownloadRoot; /** * The node.js version to be used when node.js is installed automatically by * Vaadin, for example `"v16.0.0"`. Defaults to null which uses the * Vaadin-default node version - see {@link FrontendTools} for details. */ @Parameter(property = InitParameters.NODE_VERSION, defaultValue = FrontendTools.DEFAULT_NODE_VERSION) private String nodeVersion; /** * Setting defining if the automatically installed node version may be * updated to the default Vaadin node version. */ @Parameter(property = InitParameters.NODE_AUTO_UPDATE, defaultValue = "" + Constants.DEFAULT_NODE_AUTO_UPDATE) private boolean nodeAutoUpdate; /** * The folder where `package.json` file is located. Default is project root * dir. */ @Parameter(defaultValue = "${project.basedir}") private File npmFolder; /** * Default generated path of the OpenAPI json. */ @Parameter(defaultValue = "${project.build.directory}/generated-resources/openapi.json") private File openApiJsonFile; /** * Instructs to use pnpm for installing npm frontend resources. */ @Parameter(property = InitParameters.SERVLET_PARAMETER_ENABLE_PNPM, defaultValue = "" + Constants.ENABLE_PNPM_DEFAULT) private boolean pnpmEnable; /** * Instructs to use globally installed pnpm tool or the default supported * pnpm version. */ @Parameter(property = InitParameters.SERVLET_PARAMETER_GLOBAL_PNPM, defaultValue = "" + Constants.GLOBAL_PNPM_DEFAULT) private boolean useGlobalPnpm; /** * Whether or not we are running in productionMode. */ @Parameter(defaultValue = "${vaadin.productionMode}") private boolean productionMode; @Parameter(defaultValue = "${project}", readonly = true, required = true) MavenProject project; /** * The folder where `package.json` file is located. Default is project root * dir. */ @Parameter(defaultValue = "${project.basedir}") private File projectBasedir; /** * Whether vaadin home node executable usage is forced. If it's set to * {@code true} then vaadin home 'node' is checked and installed if it's * absent. Then it will be used instead of globally 'node' or locally * installed installed 'node'. */ @Parameter(property = Constants.REQUIRE_HOME_NODE_EXECUTABLE, defaultValue = "" + Constants.DEFAULT_REQUIRE_HOME_NODE_EXECUTABLE) private boolean requireHomeNodeExec; /** * Defines the output directory for generated non-served resources, such as * the token file. */ @Parameter(defaultValue = "${project.build.outputDirectory}/" + VAADIN_SERVLET_RESOURCES) private File resourceOutputDirectory; /** * Whether or not we are running in legacy V14 bootstrap mode. True if * defined or if it's set to true. */ @Parameter(defaultValue = "${vaadin.useDeprecatedV14Bootstrapping}") private String useDeprecatedV14Bootstrapping; /** * The folder where webpack should output index.js and other generated * files. */ @Parameter(defaultValue = "${project.build.outputDirectory}/" + VAADIN_WEBAPP_RESOURCES) private File webpackOutputDirectory; /** * Build directory for the project. */ @Parameter(property = "build.folder", defaultValue = "${project.build.directory}") private String projectBuildDir; /** * Additional npm packages to run post install scripts for. *

* Post install is automatically run for internal dependencies which rely on * post install scripts to work, e.g. esbuild. */ @Parameter(property = "npm.postinstallPackages", defaultValue = "") private List postinstallPackages; /** * Generates a List of ClasspathElements (Run and CompileTime) from a * MavenProject. * * @param project * a given MavenProject * @return List of ClasspathElements */ public static List getClasspathElements(MavenProject project) { try { final Stream classpathElements = Stream.concat( project.getRuntimeClasspathElements().stream(), project.getCompileClasspathElements().stream().filter( s -> s.matches(INCLUDE_FROM_COMPILE_DEPS_REGEX))); return classpathElements.collect(Collectors.toList()); } catch (DependencyResolutionRequiredException e) { throw new IllegalStateException(String.format( "Failed to retrieve runtime classpath elements from project '%s'", project), e); } } @Override public File applicationProperties() { return applicationProperties; } @Override public boolean eagerServerLoad() { return eagerServerLoad; } @Override public File frontendDirectory() { return frontendDirectory; } @Override public File generatedFolder() { return generatedFolder; } @Override public File generatedTsFolder() { return generatedTsFolder; } @Override public ClassFinder getClassFinder() { List classpathElements = getClasspathElements(project); return BuildFrontendUtil.getClassFinder(classpathElements); } @Override public Set getJarFiles() { return project.getArtifacts().stream() .filter(artifact -> "jar".equals(artifact.getType())) .map(Artifact::getFile).collect(Collectors.toSet()); } @Override public String getUseDeprecatedV14Bootstrapping() { return useDeprecatedV14Bootstrapping; } @Override public boolean isDebugEnabled() { return getLog().isDebugEnabled(); } @Override public File javaSourceFolder() { return javaSourceFolder; } @Override public File javaResourceFolder() { return javaResourceFolder; } @Override public void logDebug(CharSequence debugMessage) { getLog().debug(debugMessage); } @Override public void logInfo(CharSequence infoMessage) { getLog().info(infoMessage); } @Override public void logWarn(CharSequence warning) { getLog().warn(warning); } @Override public void logWarn(CharSequence warning, Throwable e) { getLog().warn(warning, e); } @Override public void logError(CharSequence warning, Throwable e) { getLog().error(warning, e); } @Override public URI nodeDownloadRoot() throws URISyntaxException { if (nodeDownloadRoot == null) { nodeDownloadRoot = Platform.guess().getNodeDownloadRoot(); } try { return new URI(nodeDownloadRoot); } catch (URISyntaxException e) { logError("Failed to parse nodeDownloadRoot uri", e); throw new URISyntaxException(nodeDownloadRoot, "Failed to parse nodeDownloadRoot uri"); } } @Override public boolean nodeAutoUpdate() { return nodeAutoUpdate; } @Override public String nodeVersion() { return nodeVersion; } @Override public File npmFolder() { return npmFolder; } @Override public File openApiJsonFile() { return openApiJsonFile; } @Override public boolean pnpmEnable() { return pnpmEnable; } @Override public boolean useGlobalPnpm() { return useGlobalPnpm; } @Override public boolean productionMode() { return productionMode; } @Override public Path projectBaseDirectory() { return projectBasedir.toPath(); } @Override public boolean requireHomeNodeExec() { return requireHomeNodeExec; } @Override public File servletResourceOutputDirectory() { return resourceOutputDirectory; } @Override public File webpackOutputDirectory() { return webpackOutputDirectory; } @Override public boolean isJarProject() { return "jar".equals(project.getPackaging()); } @Override public String buildFolder() { if (projectBuildDir.startsWith(projectBasedir.toString())) { return projectBaseDirectory().relativize(Paths.get(projectBuildDir)) .toString(); } return projectBuildDir; } @Override public List postinstallPackages() { return postinstallPackages; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy