com.greenpepper.maven.plugin.FixtureGeneratorMojo Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2007 Pyxis Technologies inc.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software 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 Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA,
* or see the FSF site: http://www.fsf.org.
*/
package com.greenpepper.maven.plugin;
import com.greenpepper.dialect.SpecificationDialect;
import com.greenpepper.document.CommentTableFilter;
import com.greenpepper.document.Document;
import com.greenpepper.document.GreenPepperInterpreterSelector;
import com.greenpepper.document.GreenPepperTableFilter;
import com.greenpepper.html.HtmlDocumentBuilder;
import com.greenpepper.maven.plugin.spy.SpyFixture;
import com.greenpepper.maven.plugin.spy.SpySystemUnderDevelopment;
import com.greenpepper.maven.plugin.spy.impl.JavaFixtureGenerator;
import com.greenpepper.repository.DocumentNotFoundException;
import com.greenpepper.repository.DocumentRepository;
import com.greenpepper.runner.FactoryConverter;
import com.greenpepper.spy.FixtureGenerator;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static java.io.File.separator;
import static java.lang.String.format;
import static org.apache.commons.io.FileUtils.readFileToString;
import static org.apache.commons.lang3.StringUtils.*;
/**
* Generate a fixture from a Specifciation.
*
* @goal generate-fixtures
*/
public class FixtureGeneratorMojo extends SpecificationNavigatorMojo {
/**
* The source directory containing the fixture sources to be compiled.
*
* @parameter default-value="${basedir}/src/fixture/java"
* @required
*/
protected File fixtureSourceDirectory;
/**
* The directory to run the compiler from if fork is true.
*
* @parameter property="basedir"
* @required
* @readonly
*/
protected File basedir;
/**
* A file on the disk from which to generate the Fixture.
*
* @parameter property="greenpepper.specification"
*/
File specification;
/**
* Set this to a Specification name to use this specification for fixture generation.
* The test is searched inside the default repository.
*
* @parameter property="gp.test"
*/
String specificationName;
/**
* Set this to a default package where to fallback when greenpepper could not determine
* where to put the generated classes. If not set, the fixture will be generated in the root package.
* This is only valid when generating fixture using the Default JAVA Fixtures generator.
*
* @parameter property="greenpepper.fixtures.defaultpackage"
*/
String defaultPackage;
/**
* The FixtureGeneratorDefinition is meant to allow the specification of a JAVA class implementing a generation of fixtures.
*
* @parameter
*/
FixtureGeneratorDefinition fixtureGenerator;
FixtureGenerator actualFixtureGenerator;
@Override
public void execute() throws MojoExecutionException {
try {
validateConfiguration();
generateAllFixtures();
} catch (Exception e) {
throw new MojoExecutionException("Generation Failed", e);
}
}
private void generateAllFixtures() throws Exception {
if (specification != null) {
printSpecificationName(specification.getName());
Document doc = HtmlDocumentBuilder.tablesAndLists().build(new FileInputStream(specification));
generateFixturesForDocument(doc);
} else {
boolean atLeastOneRepositoryProcessed = false;
boolean specificationFound = false;
try {
for (Repository repository : repositories) {
if (isNotEmpty(selectedRepository)) {
if (StringUtils.equals(selectedRepository, repository.getName())) {
specificationFound = processRepository(repository);
atLeastOneRepositoryProcessed = true;
} else {
getLog().debug(format("Skipping repository '%s', selected is '%s' ", repository.getName(), selectedRepository));
}
} else {
specificationFound = processRepository(repository);
}
if (specificationFound) {
getLog().debug("Already found the required specification. We stop here.");
break;
}
}
} catch (Exception e) {
throw new MojoExecutionException("Error running the Goal", e);
}
if (isNotEmpty(selectedRepository) && !atLeastOneRepositoryProcessed) {
throw new MojoExecutionException("No repository could match your requirements");
}
if (isNotBlank(specificationName) && !specificationFound) {
throw new MojoExecutionException(format("The specification %s has not been found", specificationName));
}
}
}
private boolean processRepository(Repository repository) throws Exception {
try {
DocumentRepository documentRepository = repository.getDocumentRepository();
if (isNotBlank(repository.getDialect())) {
FactoryConverter factoryConverter = new FactoryConverter();
documentRepository.setSpecificationDialect((SpecificationDialect) factoryConverter.convert(repository.getDialect()));
}
if (isNotBlank(specificationName)) {
printSpecificationName(specificationName);
Document document = documentRepository.loadDocument(specificationName);
generateFixturesForDocument(document);
return true;
} else {
getLog().info("Generating fixture for the whole repository: " + repository.getName());
List specifications = listRepositorySpecifications(repository);
for (String spec : specifications) {
printSpecificationName(spec);
Document document = documentRepository.loadDocument(spec);
generateFixturesForDocument(document);
}
return false;
}
} catch (DocumentNotFoundException e) {
getLog().debug("failed to load the document from repository : " + e.getMessage());
return false;
}
}
private void generateFixturesForDocument(Document doc) throws Exception {
SpySystemUnderDevelopment spySut = new SpySystemUnderDevelopment();
GreenPepperInterpreterSelector interpreterSelector = new GreenPepperInterpreterSelector(spySut);
doc.addFilter(new CommentTableFilter());
doc.addFilter(new GreenPepperTableFilter(false));
doc.execute(interpreterSelector);
HashMap fixtures = spySut.getFixtures();
for (String fixtureName : fixtures.keySet()) {
SpyFixture spyFixture = fixtures.get(fixtureName);
FixtureGenerator.Result result = actualFixtureGenerator.generateFixture(spyFixture, spySut, getFixtureSourceDirectory());
File classSource = result.getFixtureFile();
switch (result.getAction()) {
case CREATED:
getLog().info(format("\t %s: %s", "Generated", difference(basedir.getAbsolutePath() + separator, classSource.getAbsolutePath())));
break;
case UPDATED:
getLog().info(format("\t %s: %s", "Updated", difference(basedir.getAbsolutePath() + separator, classSource.getAbsolutePath())));
break;
case NONE:
getLog().debug(format("\t %s: %s", "Nothing done for", difference(basedir.getAbsolutePath() + separator, classSource.getAbsolutePath())));
break;
}
if (getLog().isDebugEnabled()){
getLog().debug(format("\t Code of fixtureName :\n %s", readFileToString(classSource)));
}
}
}
private void validateConfiguration() throws MojoFailureException, ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException {
if (fixtureGenerator == null ) {
JavaFixtureGenerator javaFixtureGenerator = new JavaFixtureGenerator();
if (isNotBlank(defaultPackage)) {
javaFixtureGenerator.setDefaultPackage(defaultPackage);
}
actualFixtureGenerator = javaFixtureGenerator;
} else {
getLog().debug(format("Found a fixture generator definition:\n%s", fixtureGenerator));
@SuppressWarnings("unchecked")
Class generatorClass = (Class) Class.forName(fixtureGenerator.getImpl());
FixtureGenerator customFixtureGenerator = generatorClass.newInstance();
Map properties = fixtureGenerator.getProperties();
BeanUtils.populate(customFixtureGenerator, properties);
actualFixtureGenerator = customFixtureGenerator;
}
if (specification != null && !specification.isFile()) {
throw new MojoFailureException("The specified file doesn't exist : " + specification);
}
if (specification == null) {
if (repositories == null || repositories.isEmpty()) {
throw new MojoFailureException("When not using a File to generate the fixtures, you need to set some repositories");
}
}
}
private void printSpecificationName(String specificationName) {
System.out.println();
String title = format(" Generating fixture for : %s ", specificationName);
System.out.println(title);
System.out.println(StringUtils.repeat("-",title.length()));
System.out.println();
}
public File getFixtureSourceDirectory() {
return fixtureSourceDirectory;
}
public void setFixtureSourceDirectory(File fixtureSourceDirectory) {
this.fixtureSourceDirectory = fixtureSourceDirectory;
}
public void setBasedir(File baseDir) {
this.basedir = baseDir;
}
}