r1631 - in trunk/src: main/java/org/nuiton/license/header main/java/org/nuiton/license/header/generator main/resources main/resources/META-INF main/resources/META-INF/services site/rst
Author: tchemit Date: 2009-08-26 22:26:44 +0200 (Wed, 26 Aug 2009) New Revision: 1631 Added: trunk/src/main/java/org/nuiton/license/header/UpdateHeaderPlugin.java trunk/src/main/java/org/nuiton/license/header/generator/JavaHeaderGenerator.java trunk/src/main/java/org/nuiton/license/header/generator/XmlHeaderGenerator.java trunk/src/main/resources/META-INF/ trunk/src/main/resources/META-INF/services/ trunk/src/main/resources/META-INF/services/org.nuiton.license.header.generator.HeaderGenerator trunk/src/site/rst/usage.rst Log: fix bug #28, rethink the goal : now only one update-header Added: trunk/src/main/java/org/nuiton/license/header/UpdateHeaderPlugin.java =================================================================== --- trunk/src/main/java/org/nuiton/license/header/UpdateHeaderPlugin.java (rev 0) +++ trunk/src/main/java/org/nuiton/license/header/UpdateHeaderPlugin.java 2009-08-26 20:26:44 UTC (rev 1631) @@ -0,0 +1,385 @@ +/** + * *##% Plugin maven de changement de license + * Copyright (C) 2008 - 2009 CodeLutin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. ##%* + */ +package org.nuiton.license.header; + +import org.nuiton.processor.LicenseProcessor; +import org.apache.maven.plugin.MojoExecutionException; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.ServiceLoader; +import java.util.TreeMap; +import org.apache.maven.project.MavenProject; +import org.nuiton.AbstractPlugin; +import org.nuiton.license.License; +import org.nuiton.license.LicenseFactory; +import org.nuiton.license.header.generator.HeaderGenerator; +import org.nuiton.util.PluginHelper; + +/** + * The goal to update (or add) the licence header on some files. + * + * @author chemit + * @requiresProject true + * @goal update-header + * + * @since 1.0.1 + */ +public class UpdateHeaderPlugin extends AbstractPlugin { + + /** + * Dependance du projet. + * + * @parameter default-value="${project}" + * @required + * @since 1.0.0 + */ + protected MavenProject project; + /** + * Encoding a utiliser pour lire et ecrire les fichiers. + * + * @parameter expression="${license.encoding}" default-value="${project.build.sourceEncoding}" + * @required + * @since 1.0.0 + */ + protected String encoding; + /** + * Un flag pour forcer la generation. + * + * @parameter expression="${license.force}" default-value="false" + * @since 1.0.0 + */ + protected boolean force; + /** + * l'annee de creation du module (sera place dans le header) + * + * @parameter expression="${license.inceptionYear}" default-value="${project.inceptionYear}" + * @required + * @since 1.0.0 + */ + protected String inceptionYear; + /** + * le nom de l'organisation (sera place dans le header) + * + * @parameter expression="${license.organizationName}" default-value="${project.organization.name}" + * @required + * @since 1.0.0 + */ + protected String organizationName; + /** + * le nom du projet (sera place dans le header) + * + * @parameter expression="${license.projectName}" default-value="${project.name}" + * @required + * @since 1.0.0 + */ + protected String projectName; + /** + * Le type de license a appliquer. + * + * @parameter expression="${license.licenseName}" + * @required + * @since 1.0.0 + */ + protected String licenseName; + /** + * Le type de générateur a utiliser pour encapsuler le header. + * + * Par défaut, on veut utiliser le plugin sur des fichiers sources java. + * + * @parameter expression="${license.generatorName}" default-value="java" + * @required + * @since 1.0.1 + */ + protected String generatorName; + /** + * La liste des patterns de fichiers à inclure (séparés par des virgules). + * + * Exemple : <code>**\/*.java,**\/*.properties</code> + * + * On recherchera alors les fichiers respectant l'un des patterns dans + * tous les répertoires de sources et de tests. + * + * Par défaut, on veut utiliser le plugin sur des fichiers sources java. + * + * @parameter expression="${license.includes}" default-value="**\/*.java" + * @required + * @since 1.0.1 + */ + protected String includes = "**/*.java"; + /** + * La liste des patterns de fichiers à exclure (séparés par des virgules). + * + * Exemple : <code>**\/*.java,**\/*.properties</code> + * + * On recherchera alors les fichiers respectant l'un des patterns dans + * tous les répertoires de sources et de tests. + * + * Par défaut, on n'exclue rien. + * + * @parameter expression="${license.excludes}" + * @since 1.0.1 + */ + protected String excludes; + /** + * Repertoires des fichiers sources a traiter. + * + * @parameter expression="${license.compileSourceRoots}" default-value="${project.compileSourceRoots}" + * @required + * @since 1.0.0 + */ + protected List<String> compileSourceRoots; + /** + * Repertoires des fichiers sources de test a traiter. + * + * @parameter expression="${license.testCompileSourceRoots}" default-value="${project.testCompileSourceRoots}" + * @required + * @since 1.0.0 + */ + protected List<String> testCompileSourceRoots; + /** + * Un resolver externe + * + * @parameter expression="${license.licenseResolver}" + * @since 1.0.0 + */ + protected String licenseResolver; + /** + * Un flag pour conserver un backup des fichiers modifies. + * + * @parameter expression="${license.keepBackup}" default-value="false" + * @since 1.0.0 + */ + protected boolean keepBackup; + /** + * Un flag pour activer le mode verbeux. + * + * @parameter expression="${license.verbose}" default-value="${maven.verbose}" + * @since 1.0.0 + */ + protected boolean verbose; + /** le header a ajouter dans chaque fichier source java */ + protected String licenseHeaderContent; + /** la liste des chemin relatifs des sources java a traiter pour chaque repertoire contenant des sources */ + protected Map<File, String[]> filesToTreate; + /** le generateur d'en-tete a utiliser */ + protected HeaderGenerator generator; + protected long timestamp; + protected Map<String, HeaderGenerator> availableGenerators; + + public UpdateHeaderPlugin() { + super("all files are up-to-date."); + } + + @Override + public boolean isVerbose() { + return verbose; + } + + @Override + public void setVerbose(boolean verbose) { + this.verbose = verbose; + } + + @Override + public MavenProject getProject() { + return project; + } + + @Override + public void setProject(MavenProject project) { + this.project = project; + } + + @Override + public boolean ensurePackaging() { + return false; +// return "pom".equals(project.getPackaging()) || "site".equals(project.getPackaging()); + } + + @Override + public boolean init() throws IOException, MojoExecutionException { + + timestamp = System.nanoTime(); + + // obtain all generators available + availableGenerators = getGenerators(); + + if (verbose) { + getLog().info("available generators : " + availableGenerators); + } + + // check if given generator exists + if (!availableGenerators.containsKey(generatorName)) { + // the generator is unknown + throw new MojoExecutionException("the generator named '" + generatorName + "' is unknown (use list-generators goal to see all of them)"); + } + + // obtain all java source files to be treated + filesToTreate = getFilesToTreate(); + + boolean doGenerate = !filesToTreate.isEmpty(); + + if (doGenerate) { + + LicenseFactory factory = LicenseFactory.newInstance(licenseResolver); + License license = factory.revolv(licenseName); + + // obtain content of license header + licenseHeaderContent = computeHeader(license); + + generator = availableGenerators.get(generatorName); + + if (verbose) { + getLog().info("config - will use the generator " + generator); + getLog().info("config - header to use \n" + licenseHeaderContent); + } + } else { + getLog().info("no file to treate."); + } + + return doGenerate; + } + + @Override + protected void doAction() throws Exception { + // create a licence processor with given header + LicenseProcessor p = new LicenseProcessor(licenseHeaderContent); + + for (Entry<File, String[]> entry : filesToTreate.entrySet()) { + File src = entry.getKey(); + for (String javaRelativePath : entry.getValue()) { + File sourceFile = new File(src, javaRelativePath); + try { + processFile(p, sourceFile); + } catch (Exception e) { + throw new MojoExecutionException("could not treate source file " + sourceFile + " for reason : " + e.getMessage(), e); + } + } + } + } + + /** + * @param p license processor + * @param file the file to process + * @throws Exception if IO pb + */ + protected void processFile(LicenseProcessor p, File file) throws Exception { + + if (verbose) { + getLog().info("process file " + file); + } + + // file where to writeFile result + File processFile = new File(file.getAbsolutePath() + "_" + timestamp); + + try { + p.process(file, processFile); + boolean foundLicenseHeader = p.getLicenceFilter().wasTouched(); + + if (!foundLicenseHeader) { + if (p.getLicenceFilter().isDetectHeader()) { + getLog().warn("license footer tag was not find on file " + file); + } else { + // no license header found in file, add it + getLog().info("adding license header on file " + file); + String content = PluginHelper.readAsString(file, encoding); + content = generator.getHeader(licenseHeaderContent) + content; + writeFile(processFile, content, encoding); + } + } + + if (keepBackup) { + File backupFile = new File(file.getAbsolutePath() + "~"); + if (verbose) { + getLog().debug("backup original file " + file); + } + file.renameTo(backupFile); + } + processFile.renameTo(file); + + } catch (Exception e) { + getLog().error("could not process file " + file + " for reason " + e.getMessage(), e); + processFile.delete(); + throw e; + } finally { + p.getLicenceFilter().reset(); + } + } + + protected Map<String, HeaderGenerator> getGenerators() { + Map<String, HeaderGenerator> generators = new TreeMap<String, HeaderGenerator>(); + ServiceLoader<HeaderGenerator> loader = ServiceLoader.load(HeaderGenerator.class, getClass().getClassLoader()); + for (HeaderGenerator h : loader) { + generators.put(h.getName(), h); + } + return generators; + } + + protected Map<File, String[]> getFilesToTreate() { + + Map<File, String[]> files = new java.util.HashMap<File, String[]>(); + + String[] in = includes.split(","); + String[] ex = excludes == null ? null : excludes.split(","); + getFilesToTreateForRoots(in, ex, compileSourceRoots, files, null); + getFilesToTreateForRoots(in, ex, testCompileSourceRoots, files, null); + + return files; + } + + protected String computeHeader(License license) throws IOException { + + String tmpHeader = license.getHeaderContent(encoding); + + // defined inceptionYear (if year is older than now suffix with a - thisYear) + Calendar cal = Calendar.getInstance(); + cal.setTime(new Date()); + String thisYear = cal.get(Calendar.YEAR) + ""; + if (!thisYear.equals(inceptionYear)) { + inceptionYear = inceptionYear + " - " + thisYear; + } + + // format header with projet informations + tmpHeader = String.format(tmpHeader, projectName, inceptionYear, organizationName); + + // add " * " before each line + BufferedReader reader = new BufferedReader(new java.io.StringReader(tmpHeader)); + StringBuilder sb = new StringBuilder(); + + String line = reader.readLine(); + sb.append(line).append('\n'); + while ((line = reader.readLine()) != null) { + line = line.trim(); + if (line.isEmpty()) { + sb.append(" *\n"); + } else { + sb.append(" * ").append(line).append("\n"); + } + } + tmpHeader = sb.toString(); + return tmpHeader.substring(0, tmpHeader.length() - 1); + } +} Property changes on: trunk/src/main/java/org/nuiton/license/header/UpdateHeaderPlugin.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL Added: trunk/src/main/java/org/nuiton/license/header/generator/JavaHeaderGenerator.java =================================================================== --- trunk/src/main/java/org/nuiton/license/header/generator/JavaHeaderGenerator.java (rev 0) +++ trunk/src/main/java/org/nuiton/license/header/generator/JavaHeaderGenerator.java 2009-08-26 20:26:44 UTC (rev 1631) @@ -0,0 +1,44 @@ +/** + * *##% Plugin maven de changement de license + * Copyright (C) 2008 - 2009 CodeLutin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. ##%* + */ +package org.nuiton.license.header.generator; + +import org.nuiton.processor.filters.LicenseFilter; + +/** + * Le générateur de header pour les fichiers java + * maven. + * + * @author chemit + * + * @since 1.0.1 + */ +public class JavaHeaderGenerator implements HeaderGenerator { + + public static final String GENERATOR_NAME = "java"; + + @Override + public String getHeader(String licenseHeaderContent) { + return "/**\n * " + LicenseFilter.HEADER + " " + licenseHeaderContent + " " + LicenseFilter.FOOTER + "\n */\n"; + } + + @Override + public String getName() { + return GENERATOR_NAME; + } +} Property changes on: trunk/src/main/java/org/nuiton/license/header/generator/JavaHeaderGenerator.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL Added: trunk/src/main/java/org/nuiton/license/header/generator/XmlHeaderGenerator.java =================================================================== --- trunk/src/main/java/org/nuiton/license/header/generator/XmlHeaderGenerator.java (rev 0) +++ trunk/src/main/java/org/nuiton/license/header/generator/XmlHeaderGenerator.java 2009-08-26 20:26:44 UTC (rev 1631) @@ -0,0 +1,43 @@ +/** + * *##% Plugin maven de changement de license + * Copyright (C) 2008 - 2009 CodeLutin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. ##%* + */ +package org.nuiton.license.header.generator; + +import org.nuiton.processor.filters.LicenseFilter; + +/** + * Le header pour les fichiers xml. + * + * @author chemit + * + * @since 1.0.1 + */ +public class XmlHeaderGenerator implements HeaderGenerator { + + public static final String GENERATOR_NAME = "xml"; + + @Override + public String getHeader(String licenseHeaderContent) { + return "<!--\n\n/**\n * " + LicenseFilter.HEADER + " " + licenseHeaderContent + " " + LicenseFilter.FOOTER + "\n */\n\n-->\n"; + } + + @Override + public String getName() { + return GENERATOR_NAME; + } +} Property changes on: trunk/src/main/java/org/nuiton/license/header/generator/XmlHeaderGenerator.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL Added: trunk/src/main/resources/META-INF/services/org.nuiton.license.header.generator.HeaderGenerator =================================================================== --- trunk/src/main/resources/META-INF/services/org.nuiton.license.header.generator.HeaderGenerator (rev 0) +++ trunk/src/main/resources/META-INF/services/org.nuiton.license.header.generator.HeaderGenerator 2009-08-26 20:26:44 UTC (rev 1631) @@ -0,0 +1,2 @@ +org.nuiton.license.header.generator.JavaHeaderGenerator +org.nuiton.license.header.generator.XmlHeaderGenerator Added: trunk/src/site/rst/usage.rst =================================================================== --- trunk/src/site/rst/usage.rst (rev 0) +++ trunk/src/site/rst/usage.rst 2009-08-26 20:26:44 UTC (rev 1631) @@ -0,0 +1,4 @@ +Usage +----- + +To be done soon... \ No newline at end of file
participants (1)
-
tchemit@users.nuiton.org