package net.jhorstmann.i18n.mojo; import net.jhorstmann.i18n.tools.MessageBundle; import net.jhorstmann.i18n.tools.xgettext.MessageExtractor; import net.jhorstmann.i18n.tools.xgettext.MessageExtractorException; import net.jhorstmann.i18n.tools.xgettext.MessageFunction; import net.jhorstmann.i18n.xgettext.asm.AsmMessageExtractor; import net.jhorstmann.i18n.xgettext.web.WebMessageExtractor; import org.apache.commons.lang.StringUtils; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.codehaus.plexus.util.DirectoryScanner; import org.fedorahosted.tennera.jgettext.HeaderFields; import org.fedorahosted.tennera.jgettext.HeaderUtil; import org.fedorahosted.tennera.jgettext.Message; import org.sonatype.plexus.build.incremental.BuildContext; import java.io.File; import java.io.IOException; import java.text.MessageFormat; import java.util.Arrays; import java.util.List; import net.jhorstmann.i18n.tools.MessageBundle; import net.jhorstmann.i18n.tools.xgettext.MessageExtractor; import net.jhorstmann.i18n.tools.xgettext.MessageExtractorException; import net.jhorstmann.i18n.tools.xgettext.MessageFunction; abstract class AbstractGettextMojo extends AbstractMojo { /** * @parameter default-value="${project.build.sourceDirectory}" */ File sourceDirectory; /** * @parameter default-value="${project.build.outputDirectory}" */ File classesDirectory; /** * @parameter default-value="${project.basedir}/src/main/webapp" */ File webappDirectory; /** * @parameter */ String[] webappIncludes; /** * @parameter */ String[] webappExcludes; /** * @parameter default-value="${project.basedir}/src/main/po" */ File poDirectory; /** * @parameter */ String[] poIncludes; /** * @parameter */ String[] poExcludes; /** * @parameter default-value="${project.basedir}/src/main/po/keys.pot" */ File keysFile; /** * @parameter default-value="${false}" expression="${gettext.update}" */ boolean update; /** * @parameter */ String[] javaFunctions; /** * @parameter */ String[] elFunctions; /** * Report source-references * * @parameter expression="${srcRefPaths}" default-value="true" */ protected boolean srcRefPaths; /** * Skip this mojo. * * @parameter expression="${skip}" default-value="false" */ protected boolean skip; /** * @description E-Mail-address for message-bugs * @parameter expression="${msgidBugsAddress}" */ protected String msgidBugsAddress; /** * @description Name of the project/package * @parameter expression="${pkgName}" default-value="${project.artifactId}" */ protected String pkgName; /** * @description Version of the project/package * @parameter expression="${pkgVersion}" default-value="${project.version}" */ protected String pkgVersion; /** @parameter default-value="${project}" */ protected org.apache.maven.project.MavenProject mavenProject; /** * @parameter default-value="${basedir}" */ protected File projectRoot; // Injection of the eclipse-buildcontext for m2e-compatibility /** @component */ protected BuildContext buildContext; AbstractGettextMojo() { this.srcRefPaths = true; } String[] getWebappIncludes() { return webappIncludes != null ? webappIncludes : new String[]{ "**/*.xhtml", "**/*.jspx" }; } String[] getWebappExcludes() { return webappExcludes != null ? webappExcludes : new String[] {}; } String[] getPoIncludes() { return poIncludes != null ? poIncludes : new String[] { "**/*.po" }; } String[] getPoExcludes() { return poExcludes != null ? poExcludes : new String[] {}; } List<MessageFunction> getJavaFunctions() { if (javaFunctions == null) { return AsmMessageExtractor.DEFAULT_MESSAGE_FUNCTIONS; } else { int len = javaFunctions.length; MessageFunction[] functions = new MessageFunction[len]; for (int i=0; i<len; i++) { functions[i] = MessageFunction.fromJava(javaFunctions[i]); } return Arrays.asList(functions); } } List<MessageFunction> getELFunctions() { if (elFunctions == null) { return WebMessageExtractor.DEFAULT_MESSAGE_FUNCTIONS; } else { int len = elFunctions.length; MessageFunction[] functions = new MessageFunction[len]; for (int i=0; i<len; i++) { functions[i] = MessageFunction.fromEL(elFunctions[i]); } return Arrays.asList(functions); } } private MessageBundle loadMessageBundleImpl() throws IOException { if (update && keysFile.exists()) { getLog().info("Loading existing keys from " + keysFile); return MessageBundle.loadCatalog(keysFile); } else { getLog().info("Creating new message-bundle"); return new MessageBundle(); } } MessageBundle loadMessageBundle() throws MojoExecutionException { try { return loadMessageBundleImpl(); } catch (IOException ex) { throw new MojoExecutionException("Could not load message bundle", ex); } } private void saveMessageBundleImpl(MessageBundle bundle) throws IOException { File dir = keysFile.getParentFile(); if (!dir.exists()) { getLog().debug("Creating directory for keys file"); boolean res = dir.mkdirs(); if (!res) { throw new IOException("Could not create directory for keys file"); } } if (getLog().isDebugEnabled()) { getLog().debug(MessageFormat.format("Saving keys to {0} <{1}>", bundle.isTemplate() ? "po-template" : "po-catalog", keysFile)); } bundle.storeCatalog(keysFile); if (buildContext != null) { buildContext.refresh(keysFile); } } protected void saveMessageBundle(MessageBundle bundle) throws MojoExecutionException { fillBundleHeader(bundle); try { saveMessageBundleImpl(bundle); } catch (IOException ex) { throw new MojoExecutionException("Could not save message bundle", ex); } } protected void fillBundleHeader(MessageBundle bundle) { Message header = bundle.getHeaderMessage(); if (header == null) { getLog().debug("Create new default-header..."); header = HeaderUtil.generateDefaultHeader(); } HeaderFields fields = HeaderFields.wrap(header); if (StringUtils.isNotEmpty(msgidBugsAddress)) { getLog().debug(MessageFormat.format("Inserting defined value <{0}>=<{1}>", HeaderFields.KEY_ReportMsgidBugsTo, msgidBugsAddress)); fields.setValue(HeaderFields.KEY_ReportMsgidBugsTo, msgidBugsAddress); } if (StringUtils.isNotEmpty(pkgName) || StringUtils.isNotEmpty(pkgVersion)) fields.setValue(HeaderFields.KEY_ProjectIdVersion, MessageFormat.format("{0} {1}", pkgName, pkgVersion)); fields.unwrap(header); bundle.addMessage(header); } int extractMessages(MessageExtractor extractor, File basedir, String[] includes, String[] excludes) throws MojoExecutionException { getLog().debug( "Creating DirectoryScanner with basedir " + basedir + " including " + Arrays.toString(includes) + " and excluding " + Arrays.toString(excludes)); DirectoryScanner scanner = new DirectoryScanner(); scanner.setBasedir(basedir); if (includes != null) { scanner.setIncludes(includes); } if (excludes != null) { scanner.setExcludes(excludes); } getLog().debug("Scanning directory " + basedir); scanner.scan(); int errorCount = 0; for (String name : scanner.getIncludedFiles()) { getLog().debug("Processing " + name); File file = new File(basedir, name); try { extractor.extractMessages(file); } catch (MessageExtractorException ex) { errorCount++; getLog().error(ex); } catch (IOException ex) { errorCount++; getLog().error(ex); } } return errorCount; } }