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

net.roboconf.maven.ValidateApplicationMojo Maven / Gradle / Ivy

There is a newer version: 0.9.1
Show newest version
/**
 * Copyright 2014-2016 Linagora, Université Joseph Fourier, Floralis
 *
 * The present code is developed in the scope of the joint LINAGORA -
 * Université Joseph Fourier - Floralis research program and is designated
 * as a "Result" pursuant to the terms and conditions of the LINAGORA
 * - Université Joseph Fourier - Floralis research program. Each copyright
 * holder of Results enumerated here above fully & independently holds complete
 * ownership of the complete Intellectual Property rights applicable to the whole
 * of said Results, and may freely exploit it in any manner which does not infringe
 * the moral rights of the other copyright holders.
 *
 * 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 net.roboconf.maven;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import net.roboconf.core.Constants;
import net.roboconf.core.ErrorCode;
import net.roboconf.core.ErrorCode.ErrorLevel;
import net.roboconf.core.RoboconfError;
import net.roboconf.core.model.ParsingError;
import net.roboconf.core.model.RuntimeModelIo;
import net.roboconf.core.model.RuntimeModelIo.ApplicationLoadResult;
import net.roboconf.core.model.beans.ApplicationTemplate;
import net.roboconf.core.model.helpers.RoboconfErrorHelpers;
import net.roboconf.core.utils.Utils;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
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.project.MavenProject;

/**
 * The mojo in charge of checking the application.
 * 

* It must be invoked only once dependencies have been resolved and * imported in the project. And after the original model files in this * project have been filtered by the maven-resources-plugin. *

*

* This mojo works on a directory under the "target" build directory. *

* * @author Vincent Zurczak - Linagora */ @Mojo( name="validate-application", defaultPhase = LifecyclePhase.COMPILE ) public class ValidateApplicationMojo extends AbstractMojo { @Parameter( defaultValue = "${project}", readonly = true ) private MavenProject project; @Parameter( defaultValue = "false" ) private boolean recipe; @Parameter( defaultValue = "false" ) private boolean official; @Override public void execute() throws MojoExecutionException, MojoFailureException { // Find the target directory File completeAppDirectory = new File( this.project.getBuild().getOutputDirectory()); if( ! completeAppDirectory.isDirectory()) throw new MojoExecutionException( "The target model directory could not be found. " + completeAppDirectory ); // Load and validate the application ApplicationLoadResult alr; Collection recipeErrors = null; if( this.recipe ) { alr = RuntimeModelIo.loadApplicationFlexibly( completeAppDirectory ); RoboconfErrorHelpers.filterErrorsForRecipes( alr ); recipeErrors = validateRecipesSpecifics( this.project, alr.getApplicationTemplate(), this.official ); alr.getLoadErrors().addAll( recipeErrors ); } else { alr = RuntimeModelIo.loadApplication( completeAppDirectory ); } // Analyze the result try { if( alr.getLoadErrors().size() > 0 ) { reportErrors( alr ); if( RoboconfErrorHelpers.containsCriticalErrors( alr.getLoadErrors())) throw new MojoFailureException( "Errors were found in the application." ); if( this.official && ! recipeErrors.isEmpty()) throw new MojoFailureException( "Warnings were found in official recipes. Please, fix them." ); } } catch( IOException e ) { throw new MojoExecutionException( "A problem occurred during the validation.", e ); } } /** * Reports errors (in the logger and in a file). * @param alr * @throws IOException */ private void reportErrors( ApplicationLoadResult alr ) throws IOException { // Add a log entry getLog().info( "Generating a report for validation errors under " + MavenPluginConstants.VALIDATION_RESULT_PATH ); // Generate the report (file and console too) StringBuilder globalSb = new StringBuilder(); List resolvedErrors = RoboconfErrorHelpers.resolveErrorsWithLocation( alr ); for( RoboconfError error : resolvedErrors ) { StringBuilder sb = new StringBuilder(); sb.append( "[ " ); sb.append( error.getErrorCode().getCategory().toString().toLowerCase()); sb.append( " ] " ); sb.append( error.getErrorCode().getMsg()); if( ! Utils.isEmptyOrWhitespaces( error.getDetails())) sb.append( " " + error.getDetails()); if( ! sb.toString().endsWith( "." )) sb.append( "." ); if( error instanceof ParsingError ) { sb.append( " See " ); sb.append(((ParsingError) error).getFile().getName()); sb.append( ", line " ); sb.append(((ParsingError) error).getLine()); sb.append( "." ); } if( error.getErrorCode().getLevel() == ErrorLevel.WARNING ) getLog().warn( sb.toString()); else getLog().error( sb.toString()); globalSb.append( sb ); globalSb.append( "\n" ); } // Write the report. // Reporting only makes sense when there is an error or a warning. File targetFile = new File( this.project.getBasedir(), MavenPluginConstants.VALIDATION_RESULT_PATH ); Utils.createDirectory( targetFile.getParentFile()); Utils.writeStringInto( globalSb.toString(), targetFile ); } /** * Validate aspects that are specific to recipes (i.e. partial Roboconf applications). *

* Most of this validation could have been handled through enforcer rules. However, * they are all warnings and we do not want to create hundreds of projects. We can * see these rules as good practices that will be shared amongst all the Roboonf users. *

*

* At worst, users can ignore these warnings. * Or they can submit a feature request to add or remove validation rules. *

* * @param project a Maven project * @param tpl an application template * @param official true if this recipe is maintained by the Roboconf team, false otherwise * @return a non-null list of errors */ static Collection validateRecipesSpecifics( MavenProject project, ApplicationTemplate tpl, boolean official ) { Collection result = new ArrayList (); if( ! project.getArtifactId().equals( project.getArtifactId().toLowerCase())) result.add( new RoboconfError( ErrorCode.REC_ARTIFACT_ID_IN_LOWER_CASE )); if( ! tpl.getRootInstances().isEmpty()) result.add( new RoboconfError( ErrorCode.REC_AVOID_INSTANCES )); if( official && ! Constants.OFFICIAL_RECIPES_GROUP_ID.equals( project.getGroupId())) result.add( new RoboconfError( ErrorCode.REC_OFFICIAL_GROUP_ID )); if( ! project.getArtifactId().equals( project.getArtifactId())) result.add( new RoboconfError( ErrorCode.REC_NON_MATCHING_ARTIFACT_ID )); File[] files = project.getBasedir().listFiles(); boolean found = false; if( files != null ) { for( int i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy