You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by re...@apache.org on 2013/03/15 23:24:52 UTC
svn commit: r1457149 -
/uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/EnhanceMojo.java
Author: rec
Date: Fri Mar 15 22:24:52 2013
New Revision: 1457149
URL: http://svn.apache.org/r1457149
Log:
[UIMA-2610] Report and fail build if meta data is missing
https://issues.apache.org/jira/browse/UIMA-2610
- Added option to generate the report (enabled by default)
- Added option to fail if meta data is missing (disabled by default)
Modified:
uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/EnhanceMojo.java
Modified: uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/EnhanceMojo.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/EnhanceMojo.java?rev=1457149&r1=1457148&r2=1457149&view=diff
==============================================================================
--- uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/EnhanceMojo.java (original)
+++ uima/sandbox/uimafit/trunk/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/EnhanceMojo.java Fri Mar 15 22:24:52 2013
@@ -19,8 +19,15 @@
package org.apache.uima.fit.maven;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -38,9 +45,13 @@ import javassist.bytecode.annotation.Ann
import javassist.bytecode.annotation.MemberValue;
import javassist.bytecode.annotation.StringMemberValue;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.LineIterator;
+import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
@@ -56,6 +67,8 @@ import org.apache.uima.resource.metadata
import org.codehaus.plexus.util.FileUtils;
import org.sonatype.plexus.build.incremental.BuildContext;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
import com.thoughtworks.qdox.model.JavaSource;
/**
@@ -125,7 +138,31 @@ public class EnhanceMojo extends Abstrac
@Parameter(defaultValue = "${project.build.sourceEncoding}", required = true)
private String encoding;
- public void execute() throws MojoExecutionException {
+ /**
+ * Generate a report of missing meta data in {@code
+ * ${project.build.directory}/uimafit-missing-meta-data-report.txt}
+ */
+ @Parameter(defaultValue = "true", required = true)
+ private boolean generateMissingMetaDataReport;
+
+ /**
+ * Fail on missing meta data. This setting has no effect unless
+ * {@code generateMissingMetaDataReport} is enabled.
+ */
+ @Parameter(defaultValue = "false", required = true)
+ private boolean failOnMissingMetaData;
+
+ /**
+ * Start of a line containing a class name in the missing meta data report file
+ */
+ private static final String MARK_CLASS = "Class:";
+
+ /**
+ * Marker that no missing meta data report was found.
+ */
+ private static final String MARK_NO_MISSING_META_DATA = "No missing meta data was found.";
+
+ public void execute() throws MojoExecutionException, MojoFailureException {
// Get the compiled classes from this project
String[] files = FileUtils.getFilesFromExtension(project.getBuild().getOutputDirectory(),
new String[] { "class" });
@@ -136,6 +173,21 @@ public class EnhanceMojo extends Abstrac
ClassPool classPool = new ClassPool(true);
classPool.appendClassPath(new LoaderClassPath(componentLoader));
+ // Set up map to keep a report per class.
+ Multimap<String, String> reportData = LinkedHashMultimap.create();
+
+ // Determine where to write the missing meta data report file
+ File reportFile = new File(project.getBuild().getDirectory(),
+ "uimafit-missing-meta-data-report.txt");
+
+ // Read existing report
+ if (generateMissingMetaDataReport) {
+ readMissingMetaDataReport(reportFile, reportData);
+ }
+
+ // Remember the names of all examined components, whether processed or not.
+ List<String> examinedComponents = new ArrayList<String>();
+
for (String file : files) {
String clazzName = Util.getClassName(project, file);
@@ -147,6 +199,8 @@ public class EnhanceMojo extends Abstrac
// Do not process a class twice
if (clazz.isAnnotationPresent(EnhancedClassFile.class)) {
getLog().info("Class [" + clazzName + "] already enhanced");
+ // Remember that class was examined
+ examinedComponents.add(clazzName);
continue;
}
@@ -159,6 +213,12 @@ public class EnhanceMojo extends Abstrac
continue;
}
+ // Remember that class was examined
+ examinedComponents.add(clazzName);
+
+ // Forget any previous missing meta data report we have on the class
+ reportData.removeAll(clazzName);
+
// Get the Javassist class
CtClass ctClazz;
try {
@@ -179,10 +239,10 @@ public class EnhanceMojo extends Abstrac
JavaSource ast = parseSource(sourceFile);
// Enhance meta data
- enhanceResourceMetaData(ast, clazz, ctClazz);
+ enhanceResourceMetaData(ast, clazz, ctClazz, reportData);
// Enhance configuration parameters
- enhanceConfigurationParameter(ast, clazz, ctClazz);
+ enhanceConfigurationParameter(ast, clazz, ctClazz, reportData);
// Add the EnhancedClassFile annotation.
markAsEnhanced(ctClazz);
@@ -203,12 +263,26 @@ public class EnhanceMojo extends Abstrac
} catch (IOException e) {
throw new MojoExecutionException("Enhanced class [" + clazzName + "] cannot be written: "
+ ExceptionUtils.getRootCauseMessage(e), e);
-
} catch (CannotCompileException e) {
throw new MojoExecutionException("Enhanced class [" + clazzName + "] cannot be compiled: "
+ ExceptionUtils.getRootCauseMessage(e), e);
}
}
+
+ if (generateMissingMetaDataReport) {
+ // Remove any classes from the report that are no longer part of the build
+ List<String> deletedClasses = new ArrayList<String>(reportData.keySet());
+ deletedClasses.removeAll(examinedComponents);
+ reportData.removeAll(deletedClasses);
+
+ // Write updated report
+ writeMissingMetaDataReport(reportFile, reportData);
+
+ if (failOnMissingMetaData && !reportData.isEmpty()) {
+ throw new MojoFailureException("Component meta data missing. A report of the missing "
+ + "meta data can be found in " + reportFile);
+ }
+ }
}
/**
@@ -239,8 +313,8 @@ public class EnhanceMojo extends Abstrac
/**
* Enhance resource meta data
*/
- private void enhanceResourceMetaData(JavaSource aAST, Class<?> aClazz, CtClass aCtClazz)
- throws MojoExecutionException {
+ private void enhanceResourceMetaData(JavaSource aAST, Class<?> aClazz, CtClass aCtClazz,
+ Multimap<String, String> aReportData) throws MojoExecutionException {
ClassFile classFile = aCtClazz.getClassFile();
ConstPool constPool = classFile.getConstPool();
@@ -264,19 +338,19 @@ public class EnhanceMojo extends Abstrac
// Update description from JavaDoc
String doc = Util.getComponentDocumentation(aAST, aClazz.getName());
enhanceMemberValue(a, "description", doc, overrideComponentDescription,
- ResourceMetaDataFactory.getDefaultDescription(aClazz), constPool);
+ ResourceMetaDataFactory.getDefaultDescription(aClazz), constPool, aReportData, aClazz);
// Update version
enhanceMemberValue(a, "version", componentVersion, overrideComponentVersion,
- ResourceMetaDataFactory.getDefaultVersion(aClazz), constPool);
+ ResourceMetaDataFactory.getDefaultVersion(aClazz), constPool, aReportData, aClazz);
// Update vendor
enhanceMemberValue(a, "vendor", componentVendor, overrideComponentVendor,
- ResourceMetaDataFactory.getDefaultVendor(aClazz), constPool);
+ ResourceMetaDataFactory.getDefaultVendor(aClazz), constPool, aReportData, aClazz);
// Update copyright
enhanceMemberValue(a, "copyright", componentCopyright, overrideComponentCopyright,
- ResourceMetaDataFactory.getDefaultVendor(aClazz), constPool);
+ ResourceMetaDataFactory.getDefaultCopyright(aClazz), constPool, aReportData, aClazz);
// Replace annotation
annoAttr.addAnnotation(a);
@@ -301,7 +375,8 @@ public class EnhanceMojo extends Abstrac
* default value set by uimaFIT - if the member has this value, it is considered unset
*/
private void enhanceMemberValue(Annotation aAnnotation, String aName, String aNewValue,
- boolean aOverride, String aDefault, ConstPool aConstPool) {
+ boolean aOverride, String aDefault, ConstPool aConstPool,
+ Multimap<String, String> aReportData, Class<?> aClazz) {
String value = getStringMemberValue(aAnnotation, aName);
boolean isEmpty = value.length() == 0;
boolean isDefault = value.equals(aDefault);
@@ -311,7 +386,8 @@ public class EnhanceMojo extends Abstrac
aAnnotation.addMemberValue(aName, new StringMemberValue(aNewValue, aConstPool));
getLog().info("Enhanced component meta data [" + aName + "]");
} else {
- getLog().warn("No meta data [" + aName + "] found");
+ getLog().info("No meta data [" + aName + "] found");
+ aReportData.put(aClazz.getName(), "No meta data [" + aName + "] found");
}
} else {
getLog().info("Not overwriting component meta data [" + aName + "]");
@@ -330,7 +406,8 @@ public class EnhanceMojo extends Abstrac
/**
* Enhance descriptions in configuration parameters.
*/
- private void enhanceConfigurationParameter(JavaSource aAST, Class<?> aClazz, CtClass aCtClazz)
+ private void enhanceConfigurationParameter(JavaSource aAST, Class<?> aClazz, CtClass aCtClazz,
+ Multimap<String, String> aReportData)
throws MojoExecutionException {
// Get the parameter name constants
Map<String, String> nameFields = getParameterConstants(aClazz);
@@ -351,7 +428,9 @@ public class EnhanceMojo extends Abstrac
String pdesc = Util.getParameterDocumentation(aAST, field.getName(),
nameFields.get(p.getName()));
if (pdesc == null) {
- getLog().warn("No description found for parameter [" + p.getName() + "]");
+ String msg = "No description found for parameter [" + p.getName() + "]";
+ getLog().info(msg);
+ aReportData.put(aClazz.getName(), msg);
continue;
}
@@ -442,4 +521,87 @@ public class EnhanceMojo extends Abstrac
}
return null;
}
+
+ /**
+ * Write a report on any meta data missing from components.
+ */
+ private void writeMissingMetaDataReport(File aReportFile, Multimap<String, String> aReportData)
+ throws MojoExecutionException {
+ String[] classes = aReportData.keySet().toArray(new String[aReportData.keySet().size()]);
+ Arrays.sort(classes);
+
+ PrintWriter out = null;
+ FileUtils.mkdir(aReportFile.getParent());
+ try {
+ out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(aReportFile), encoding));
+
+ if (classes.length > 0) {
+ for (String clazz : classes) {
+ out.printf("%s %s%n", MARK_CLASS, clazz);
+ Collection<String> messages = aReportData.get(clazz);
+ if (messages.isEmpty()) {
+ out.printf(" No problems");
+ } else {
+ for (String message : messages) {
+ out.printf(" %s%n", message);
+ }
+ }
+ out.printf("%n");
+ }
+ }
+ else {
+ out.printf("%s%n", MARK_NO_MISSING_META_DATA);
+ }
+ } catch (IOException e) {
+ throw new MojoExecutionException("Unable to write missing meta data report to ["
+ + aReportFile + "]" + ExceptionUtils.getRootCauseMessage(e), e);
+ } finally {
+ IOUtils.closeQuietly(out);
+ }
+ }
+
+ /**
+ * Read the missing meta data report from a previous run.
+ */
+ private void readMissingMetaDataReport(File aReportFile, Multimap<String, String> aReportData)
+ throws MojoExecutionException {
+ if (!aReportFile.exists()) {
+ // Ignore if the file is missing
+ return;
+ }
+
+ LineIterator i = null;
+ try {
+ String clazz = null;
+ i = IOUtils.lineIterator(new FileInputStream(aReportFile), encoding);
+ while (i.hasNext()) {
+ String line = i.next();
+ // Report say there is no missing meta data
+ if (line.startsWith(MARK_NO_MISSING_META_DATA)) {
+ return;
+ }
+ // Line containing class name
+ if (line.startsWith(MARK_CLASS)) {
+ clazz = line.substring(MARK_CLASS.length()).trim();
+ }
+ else if (StringUtils.isBlank(line)) {
+ // Empty line, ignore
+ }
+ else {
+ // Line containing a missing meta data instance
+ if (clazz == null) {
+ throw new MojoExecutionException("Missing meta data report has invalid format.");
+ }
+ aReportData.put(clazz, line.trim());
+ }
+ }
+ }
+ catch (IOException e) {
+ throw new MojoExecutionException("Unable to read missing meta data report: "
+ + ExceptionUtils.getRootCauseMessage(e), e);
+ }
+ finally {
+ LineIterator.closeQuietly(i);
+ }
+ }
}