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

org.jnario.maven.JnarioDocGenerate Maven / Gradle / Ivy

package org.jnario.maven;

import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.transform;
import static java.util.Arrays.asList;
import static org.eclipse.xtext.util.Strings.concat;

import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;

import org.apache.maven.plugin.MojoExecutionException;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.xtend.core.compiler.batch.XtendBatchCompiler;
import org.eclipse.xtend.lib.macro.file.Path;
import org.eclipse.xtend.maven.MavenProjectAdapter;
import org.eclipse.xtend.maven.XtendTestCompile;
import org.eclipse.xtext.ISetup;
import org.eclipse.xtext.xbase.file.ProjectConfig;
import org.eclipse.xtext.xbase.file.RuntimeWorkspaceConfigProvider;
import org.eclipse.xtext.xbase.file.WorkspaceConfig;
import org.jnario.compiler.HtmlAssetsCompiler;
import org.jnario.compiler.JnarioDocCompiler;
import org.jnario.feature.FeatureStandaloneSetup;
import org.jnario.report.Executable2ResultMapping;
import org.jnario.report.HashBasedSpec2ResultMapping;
import org.jnario.report.SpecResultParser;
import org.jnario.spec.SpecStandaloneSetup;
import org.jnario.suite.SuiteStandaloneSetup;

import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;

/**
 * Goal which generates Jnario documentation.
 * 
 * @author Sebastian Benz - Initial contribution and API
 * @requiresDependencyResolution test
 * @goal generate	
 */
public class JnarioDocGenerate extends XtendTestCompile {

	private final class XmlFiles implements FilenameFilter {
		public boolean accept(File dir, String name) {
			return name.endsWith("xml");
		}
	}

	/**
	 * Location of the generated documentation.
	 * 
	 * @parameter default-value="${basedir}/target/jnario-doc"
	 * @required
	 */
	private String docOutputDirectory;
	
	/**
	 * Location of the generated JUnit XML reports.
	 * 
	 * @parameter default-value="${basedir}/target/surefire-reports"
	 * @required
	 */
	private String reportsDirectory;
	
	/**
	 * Location of the generated JUnit XML reports.
	 * 
	 * @parameter 
	 */
	private String sourceDirectory;
	
	@Inject
	private RuntimeWorkspaceConfigProvider workspaceConfigProvider;

	private Provider resourceSetProvider;

	@Override
	protected void internalExecute() throws MojoExecutionException {
		getLog().info("Generating Jnario reports to " + docOutputDirectory);
		
		// the order is important, the suite compiler must be executed last
		List injectors = createInjectors(new SpecStandaloneSetup(), new FeatureStandaloneSetup(), new SuiteStandaloneSetup());
		generateCssAndJsFiles(injectors);
		resourceSetProvider = new JnarioMavenProjectResourceSetProvider(project);

		HashBasedSpec2ResultMapping resultMapping = createSpec2ResultMapping(injectors);
		for (Injector injector : injectors) {
			generateDoc(injector, resultMapping);
		}
	}

	protected HashBasedSpec2ResultMapping createSpec2ResultMapping(List injectors) throws MojoExecutionException {
		HashBasedSpec2ResultMapping resultMapping = injectors.get(2).getInstance(HashBasedSpec2ResultMapping.class);
		File reportFolder = new File(reportsDirectory);
		if(reportFolder.exists()){
			addExecutionResults(resultMapping, reportFolder);
		}else{
			throw new MojoExecutionException("Surefire Report folder does not exist");
		}
		return resultMapping;
	}

	protected void generateCssAndJsFiles(List injectors) {
		HtmlAssetsCompiler assetsCompiler = injectors.get(0).getInstance(HtmlAssetsCompiler.class);
		assetsCompiler.setOutputPath(docOutputDirectory);
		getLog().info("Generating HTML assets to " + docOutputDirectory);
		assetsCompiler.compile();
	}

	protected void addExecutionResults(HashBasedSpec2ResultMapping resultMapping, File reportFolder) throws MojoExecutionException {
		SpecResultParser specResultParser = new SpecResultParser();
		for (File file : reportFolder.listFiles(new XmlFiles())) {
			FileInputStream is = null;
			try {
				is = new FileInputStream(file);
				specResultParser.parse(is, resultMapping);
			} catch (Exception e) {
				throw new MojoExecutionException("Exception while parsing spec for: " + file, e);
			}finally{
				try {
					is.close();
				} catch (IOException e) {
				}
			}
			
		}
	}

	protected void compileTestSources(XtendBatchCompiler xtend2BatchCompiler) throws MojoExecutionException {
		List testCompileSourceRoots = Lists.newArrayList(project.getTestCompileSourceRoots());
		String testClassPath = concat(File.pathSeparator, getTestClassPath());
		if(sourceDirectory != null){
			testCompileSourceRoots = Collections.singletonList(sourceDirectory);
		}
		getLog().debug("source folders: " + testCompileSourceRoots);
		compile(xtend2BatchCompiler, testClassPath, testCompileSourceRoots, docOutputDirectory);
	}
	
	private void generateDoc(Injector injector, Executable2ResultMapping resultMapping) throws MojoExecutionException {
		JnarioDocCompiler docCompiler = injector.getInstance(JnarioDocCompiler.class);
		docCompiler.setExecutable2ResultMapping(resultMapping);
		compileTestSources(docCompiler);
	}
	
	protected void compile(XtendBatchCompiler xtend2BatchCompiler, String classPath, List sourceDirectories,
			String outputPath) throws MojoExecutionException {
		configureWorkspace(sourceDirectories, outputPath);
		resourceSetProvider.get().eAdapters().clear();
		xtend2BatchCompiler.setResourceSetProvider(resourceSetProvider);
		MavenProjectAdapter.install(resourceSetProvider.get(), project);
		Iterable filtered = filter(sourceDirectories, FILE_EXISTS);
		if (Iterables.isEmpty(filtered)) {
			getLog().info(
					"skip compiling sources because the configured directory '" + Iterables.toString(sourceDirectories)
							+ "' does not exists.");
			return;
		}
		getLog().debug("Set temp directory: " + getTempDirectory());
		xtend2BatchCompiler.setTempDirectory(getTempDirectory());
		getLog().debug("Set DeleteTempDirectory: " + false);
		xtend2BatchCompiler.setDeleteTempDirectory(false);
		getLog().debug("Set classpath: " + classPath);
		xtend2BatchCompiler.setClassPath(classPath);
		getLog().debug("Set source path: " + concat(File.pathSeparator, newArrayList(filtered)));
		xtend2BatchCompiler.setSourcePath(concat(File.pathSeparator, newArrayList(filtered)));
		getLog().debug("Set output path: " + outputPath);
		xtend2BatchCompiler.setOutputPath(outputPath);
		getLog().debug("Set encoding: " + encoding);
		xtend2BatchCompiler.setFileEncoding(encoding);
		getLog().debug("Set writeTraceFiles: " + writeTraceFiles);
		xtend2BatchCompiler.setWriteTraceFiles(writeTraceFiles);
		if (!xtend2BatchCompiler.compile()) {
			throw new MojoExecutionException("Error compiling xtend sources in '"
					+ concat(File.pathSeparator, newArrayList(filtered)) + "'.");
		}
	}

	private void configureWorkspace(List sourceDirectories, String outputPath) throws MojoExecutionException {
		WorkspaceConfig workspaceConfig = new WorkspaceConfig(project.getBasedir().getParentFile().getAbsolutePath());
		ProjectConfig projectConfig = new ProjectConfig(project.getBasedir().getName());
		URI absoluteRootPath = project.getBasedir().getAbsoluteFile().toURI();
		URI relativizedTarget = absoluteRootPath.relativize(new File(outputPath).toURI());
		if (relativizedTarget.isAbsolute()) {
			throw new MojoExecutionException("Output path '" + outputPath
					+ "' must be a child of the project folder '" + absoluteRootPath + "'");
		}
		for (String source : sourceDirectories) {
			URI relativizedSrc = absoluteRootPath.relativize(new File(source).toURI());
			if (relativizedSrc.isAbsolute()) {
				throw new MojoExecutionException("Source folder " + source
						+ " must be a child of the project folder " + absoluteRootPath);
			}
			projectConfig.addSourceFolderMapping(relativizedSrc.getPath(), relativizedTarget.getPath());
		}
		workspaceConfig.addProjectConfig(projectConfig);
		workspaceConfigProvider.setWorkspaceConfig(workspaceConfig);
		if (getLog().isDebugEnabled()) {
			getLog().debug("WS config root: " + workspaceConfig.getAbsoluteFileSystemPath());
			getLog().debug("Project name: " + projectConfig.getName());
			getLog().debug("Project root path: " + projectConfig.getRootPath());
			for (Entry entry : projectConfig.getSourceFolderMappings().entrySet()) {
				getLog().debug("Source path: " + entry.getKey() + " -> " + entry.getValue());
			}
		}
	}	
	private List createInjectors(ISetup... setups) {
		return transform(asList(setups), new Function() {
			public Injector apply(ISetup input) {
				return input.createInjectorAndDoEMFRegistration();
			}
		});
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy