/******************************************************************************* * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 *******************************************************************************/ package org.ebayopensource.turmeric.plugins.maven; import java.io.File; import java.util.ArrayList; import java.util.List; import org.apache.maven.model.Resource; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.codehaus.plexus.util.StringUtils; import org.ebayopensource.turmeric.plugins.maven.resources.ResourceLocator; import org.ebayopensource.turmeric.plugins.maven.resources.ResourceLocator.Location; import org.ebayopensource.turmeric.plugins.maven.utils.CodegenCommands; import org.ebayopensource.turmeric.plugins.maven.utils.LegacyProperties; import org.ebayopensource.turmeric.tools.codegen.InputOptions; import org.ebayopensource.turmeric.tools.errorlibrary.ErrorLibraryInputOptions; import org.jdom.Document; import org.jdom.Element; /** * Perform codegen of the error library classes. * Typically provided as a set of XML files. * * @goal gen-errorlibrary * @phase generate-sources * @requiresDependencyResolution compile * @requiresProject true */ public class GenErrorLibraryMojo extends AbstractTurmericCodegenMojo { private static final String LEGACY_PROP_REF = "${project.basedir}/error_library_project.properties"; /** * CodeGen Type. * * @parameter expression="${codegen.generator.type}" * default-value="genTypeCommandLineAll" * @required */ protected String genType = "genTypeCommandLineAll"; /** * Error Library Name. * * @parameter expression="${codegen.errorlibrary.name}" * default-value="${project.artifactId}" * @required */ protected String errorLibraryName = "${project.artifactId}"; /** * Comma separated list of domains for this error library. * <p> * If unspecified, the list of domains will be identified by * looking for any ErrorData.xml files within the project * resources directories, and reading the domain value out of them. * Looks for a path pattern of "META-INF/errorlibrary/([^/]+)/ErrorData.xml" * <p> * <b>[LEGACY] Value ignored when in legacy mode, the value * present in error_library_project.properties is used</b> * * @parameter expression="${codegen.domains}" * @optional */ protected String domains; /** * [LEGACY] Domain List Properties Path Reference for this project. * <p> * Use syntax similar to how {@link ClassLoader#getResource(String)} expects. * <p> * Actual Domain List File location is looked up via {@link ResourceLocator#findResource(String)} * * @parameter expression="${codegen.wsdl.path}" * default-value="META-INF/errorlibrary/$${mojo.errorLibraryName}/domain_list.properties" * @optional */ protected String domainListPropPathRef = "META-INF/errorlibrary/${mojo.errorLibraryName}/domain_list.properties"; @Override protected String getGoalName() { return "gen-errorlibrary"; } @Override protected void addCodegenCommands(CodegenCommands commands) throws MojoExecutionException, MojoFailureException { // Remove these unused, defaulted, commands to support legacy Error Library codegen commands.removeOptionPair(InputOptions.OPT_META_SRC_GEN_DIR); commands.removeOptionPair(InputOptions.OPT_JAVA_SRC_GEN_DIR); commands.removeOptionPair(InputOptions.OPT_BIN_DIR); commands.removeOptionPair(InputOptions.OPT_SRC_DIR); // Legacy mode is the only one that can use project root if(isLegacyMode()) { commands.add(ErrorLibraryInputOptions.OPT_PROJECT_ROOT, project.getBasedir().getAbsolutePath()); } commands.add(ErrorLibraryInputOptions.OPT_DEST_LOCATION, outputDirectory.getAbsolutePath()); commands.add(ErrorLibraryInputOptions.OPT_LIST_OF_DOMAIN, domains); commands.add(ErrorLibraryInputOptions.OPT_ERRORLIBRARY_NAME, errorLibraryName); if(isStandardsMode()) { @SuppressWarnings("unchecked") List<Resource> resources = project.getBuild().getResources(); Resource firstResource = resources.get(0); commands.add(ErrorLibraryInputOptions.OPT_META_SRC_DIR, firstResource.getDirectory()); } } @Override protected void onAttachGeneratedDirectories() { // HACK to get around CodeGen adding extra path information, even // though we specify the full path to generate into. File genSrcDir = new File(outputDirectory, "gen-src"); if (genSrcDir.exists()) { super.outputDirectory = genSrcDir; } super.onAttachGeneratedDirectories(); } @Override protected void onValidateParameters() throws MojoExecutionException, MojoFailureException { super.onValidateParameters(); errorLibraryName = expandParameter(errorLibraryName); domains = expandParameter(domains); if (isStandardsMode()) { if(StringUtils.isBlank(domains)) { domains = findDomains(); } } else if (isLegacyMode()) { domainListPropPathRef = expandParameter(domainListPropPathRef); ResourceLocator locator = new ResourceLocator(getLog(), getProject()); Location domainListPropLocation = locator.findResource(domainListPropPathRef); LegacyProperties props = getLegacyProperties(LEGACY_PROP_REF); if(!props.exists()) { if(domainListPropLocation == null) { StringBuilder err = new StringBuilder(); err.append("Unable to find LEGACY mode properties files "); err.append(" that contain the listOfDomains needed for "); err.append(" successful LEGACY mode operations.\n"); err.append("\n NOT FOUND: ").append(LEGACY_PROP_REF); err.append("\n NOT FOUND: ${project.resources}/"); err.append(domainListPropPathRef); err.append("\n NOT FOUND: ${project.build.outputDirectory}/"); err.append(domainListPropPathRef); err.append("\n NOT FOUND: ${project.dependencies}/"); err.append(domainListPropPathRef); err.append("\n"); throw new MojoFailureException(err.toString()); } props = getLegacyProperties(domainListPropLocation); } domains = props.getProperty("listOfDomains", domains); } } /** * Attempt to find any "META-INF/errorlibrary/([^/]+)/ErrorData.xml" files * in the project resource directories, and read the domain out of them. * * @return * @throws MojoExecutionException */ private String findDomains() throws MojoExecutionException { List<String> domains = new ArrayList<String>(); List<File> errordatas = findProjectResourceFiles("META-INF/errorlibrary/([^/]+)/ErrorData.xml"); for(File file: errordatas) { domains.add(readDomainFromErrorData(file)); } if(domains.isEmpty()) { throw new MojoExecutionException("Unable to find list of domain " + "names via ErrorData.xml lookup. You'll likely have to " + "specify the domain names yourself in the plugin " + "configuration, or add the missing ErrorData.xml files"); } return StringUtils.join(domains.iterator(), ","); } private String readDomainFromErrorData(File errorDataXml) throws MojoExecutionException { Document doc = parseXml(errorDataXml); Element root = doc.getRootElement(); return root.getAttributeValue("domain"); } /** * {@inheritDoc} * @see org.ebayopensource.turmeric.plugins.maven.AbstractTurmericCodegenMojo#getGenType() */ @Override public String getGenType() { return this.genType; } public String getErrorLibraryName() { return errorLibraryName; } /** * {@inheritDoc} * @see org.ebayopensource.turmeric.plugins.maven.AbstractTurmericCodegenMojo#needsGeneration() */ @Override public boolean needsGeneration() throws MojoExecutionException { // Always needs generation return true; } }