From aeba3fff47aa8242bee2a2aa816fc1672cfb8b49 Mon Sep 17 00:00:00 2001 From: Levon Saldamli Date: Fri, 8 Jan 2016 13:02:57 +0100 Subject: [PATCH 1/5] Changes to support input stream instead of file so that input can be read from classpath resources. --- maven-config-processor-plugin/.gitignore | 4 + maven-config-processor-plugin/pom.xml | 2 +- .../code/configprocessor/ConfigProcessor.java | 668 +++++++++--------- .../io/ClasspathFileResolver.java | 19 +- .../io/DefaultFileResolver.java | 20 +- .../code/configprocessor/io/FileResolver.java | 2 +- .../maven/MavenFileResolver.java | 55 +- .../properties/PropertiesActionProcessor.java | 364 +++++----- .../processing/xml/XmlActionProcessor.java | 156 ++-- .../configprocessor/ConfigProcessorTest.java | 180 +++-- ...PropertiesActionProcessingAdvisorTest.java | 88 +-- 11 files changed, 836 insertions(+), 722 deletions(-) create mode 100644 maven-config-processor-plugin/.gitignore diff --git a/maven-config-processor-plugin/.gitignore b/maven-config-processor-plugin/.gitignore new file mode 100644 index 0000000..bc5fc18 --- /dev/null +++ b/maven-config-processor-plugin/.gitignore @@ -0,0 +1,4 @@ +.classpath +/target/ +.project +.settings/ diff --git a/maven-config-processor-plugin/pom.xml b/maven-config-processor-plugin/pom.xml index 7c8e469..c17bfbf 100644 --- a/maven-config-processor-plugin/pom.xml +++ b/maven-config-processor-plugin/pom.xml @@ -110,7 +110,7 @@ junit junit - 4.5 + 4.12 test diff --git a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/ConfigProcessor.java b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/ConfigProcessor.java index b6b9bc1..1fe9adc 100644 --- a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/ConfigProcessor.java +++ b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/ConfigProcessor.java @@ -16,6 +16,7 @@ package com.google.code.configprocessor; import static com.google.code.configprocessor.util.IOUtils.*; + import static org.apache.commons.lang.StringUtils.*; import java.io.*; @@ -32,339 +33,342 @@ import com.google.code.configprocessor.processing.*; import com.google.code.configprocessor.processing.properties.*; import com.google.code.configprocessor.processing.xml.*; +import com.google.code.configprocessor.util.IOUtils; public class ConfigProcessor { - private static final String DEFAULT_ENCODING = "UTF-8"; - - private String encoding; - private int lineWidth; - private int indentSize; - private Map namespaceContexts; - private boolean useOutputDirectory; - private File baseDir; - private File outputDirectory; - private LogAdapter log; - private FileResolver fileResolver; - private List parserFeatures; - private boolean failOnMissingXpath; - - private File actualOutputDirectory; - - public ConfigProcessor(String encoding, - int indentSize, - int lineWidth, - Map namespaceContexts, - File baseDir, - File outputDirectory, - boolean useOutputDirectory, - LogAdapter log, - FileResolver fileResolver, - List parserFeatures, - boolean failOnMissingXpath) { - this.encoding = encoding; - this.indentSize = indentSize; - this.lineWidth = lineWidth; - this.namespaceContexts = namespaceContexts; - this.baseDir = baseDir; - this.outputDirectory = outputDirectory; - this.useOutputDirectory = useOutputDirectory; - this.log = log; - this.fileResolver = fileResolver; - this.parserFeatures = parserFeatures; - this.failOnMissingXpath = failOnMissingXpath; - } - - public void init() throws IOException { - if (useOutputDirectory) { - if (!outputDirectory.exists() && !outputDirectory.mkdirs()) { - throw new IOException("Could not create outputDirectory [" + outputDirectory + "]"); - } - actualOutputDirectory = outputDirectory; - } - if (encoding == null) { - getLog().warn("Encoding has not been set, using default [" + DEFAULT_ENCODING + "]."); - encoding = DEFAULT_ENCODING; - } - - getLog().debug("Using output directory [" + actualOutputDirectory + "]"); - getLog().debug("File encodig is [" + encoding + "]"); - } - - public void execute(ExpressionResolver resolver, Transformation transformation) throws ConfigProcessorException, IOException { - String input = transformation.getInput(); - Action action = getAction(transformation); - String configIdentifier = getConfigIdentifier(transformation); - - if (input != null && input.contains("*")) { - // input parameter specifies a wildcard pattern - if (!StringUtils.isBlank(transformation.getOutput())) { - throw new ConfigProcessorException("Cannot specify output file if wildcard pattern based input is given"); - } - getLog().info("Using wildcard pattern based input [" + input + "]"); - List inputFiles = getMatchingFiles(input); - for (File inputFile : inputFiles) { - String type = getInputType(transformation, inputFile); - File outputFile; - if (actualOutputDirectory != null) { - // calculate a relative path below the output directory based on the input file - outputFile = new File(actualOutputDirectory, baseDir.toURI().relativize(inputFile.toURI()).getPath()); - createOutputFile(outputFile); - } else { - outputFile = inputFile; - } - process(resolver, inputFile.getPath(), inputFile, outputFile, configIdentifier, action, type); - } - } else { - File inputFile = fileResolver.resolve(transformation.getInput()); - if (!inputFile.exists()) { - throw new ConfigProcessorException("Input file [" + inputFile + "] does not exist"); - } - // use input file as output file if output is not set - File output; - if (StringUtils.isBlank(transformation.getOutput())) { - output = inputFile; - } else { - output = new File(actualOutputDirectory, transformation.getOutput()); - createOutputFile(output); - } - String type = getInputType(transformation, inputFile); - process(resolver, transformation.getInput(), inputFile, output, configIdentifier, action, type); - } - } - - protected Action getAction(Transformation transformation) throws ConfigProcessorException, IOException { - if (transformation.getConfig() == null && transformation.getRules() == null) { - throw new ConfigProcessorException("Transformation config file or rules must be set"); - } else if (transformation.getConfig() != null && transformation.getRules() != null) { - throw new ConfigProcessorException("Cannot specify transformation config file and rules at the same time"); - } - - Action action; - Reader configReader; - if (transformation.getConfig() == null) { - StringWriter writer = new StringWriter(); - AntrunXmlPlexusConfigurationWriter xmlWriter = new AntrunXmlPlexusConfigurationWriter(); - xmlWriter.write(transformation.getRules(), writer); - String configContent = trimToNull(writer.toString()); - configContent = removeStart(configContent, ""); - configContent = removeEnd(configContent, ""); - StringBuilder sb = new StringBuilder(configContent.length() + XmlHelper.ROOT_PROCESSOR_START.length() + XmlHelper.ROOT_PROCESSOR_END.length()); - sb.append(XmlHelper.ROOT_PROCESSOR_START); - sb.append(configContent); - sb.append(XmlHelper.ROOT_PROCESSOR_END); - configReader = new StringReader(sb.toString()); - } else { - File config = fileResolver.resolve(transformation.getConfig()); - - if (!config.exists()) { - throw new ConfigProcessorException("Configuration file [" + config + "] does not exist"); - } - - configReader = new InputStreamReader(new FileInputStream(config), encoding); - } - - try { - ProcessingConfigurationParser parser = new ProcessingConfigurationParser(); - action = parser.parse(configReader); - } catch (ParsingException e) { - throw new ConfigProcessorException("Error parsing transformation config [" + getConfigIdentifier(transformation) + "]", e); - } finally { - close(configReader, getLog()); - } - action.validate(); - - return action; - } - - protected String getConfigIdentifier(Transformation transformation) throws ConfigProcessorException { - if (transformation.getConfig() == null) { - StringWriter writer = new StringWriter(); - AntrunXmlPlexusConfigurationWriter xmlWriter = new AntrunXmlPlexusConfigurationWriter(); - try { - xmlWriter.write(transformation.getRules(), writer); - } catch (IOException e) { - throw new ConfigProcessorException("Shouldn't happen because there is no I/O here", e); - } - return abbreviate(trimToNull(removeStart(writer.toString(), "")), 100); - } - return transformation.getConfig(); - } - - /** - * Scans all files below the given baseDirectory using the supplied pattern. - * All files matching the pattern are returned. - * The implementation is utilizing {@link DirectoryScanner} for pattern matching, e.g. - * it allows to use single ("*") and double wildcards ("**") for matching - * arbitrary characters or directories. - * - * Examples: - * - * - * - * - * - * - * - * - * - *
- * - *
-	 * *.xml
-	 * 
- * - *
matches all XML files in the base directory
- * - *
-	 * **\/*.xml
-	 * 
- * - *
matches all XML files in any subfolder
- * - * @param pattern the directory and file name pattern that files shall match - * @return the {@link List} of {@link File}s that match the given pattern - * @throws ConfigProcessorException - */ - protected List getMatchingFiles(String pattern) throws ConfigProcessorException { - if (pattern == null || pattern.length() == 0) { - throw new ConfigProcessorException("Invalid pattern [" + pattern + "]"); - } - DirectoryScanner scanner = new DirectoryScanner(); - scanner.setBasedir(baseDir); - scanner.setIncludes(new String[] { pattern }); - scanner.setCaseSensitive(false); - scanner.scan(); - String[] fileNames = scanner.getIncludedFiles(); - List files = new ArrayList(); - for (String fileName : fileNames) { - files.add(new File(baseDir, fileName)); - } - return files; - } - - /** - * Detects input file type. - * If {@link com.google.code.configprocessor.Transformation#getType()} is not null, - * this type is used, otherwise it is tried to guess the type from the given - * input File based on the file extension (.properties or .xml). - * If no type could be found or guessed, {@link Transformation#XML_TYPE} is used. - * - * @param transformation which can have an explicit type set - * @param input file from which the type can be guessed if transformation parameter does not - * contain a type - * @return Input file type. - */ - protected String getInputType(Transformation transformation, File input) { - String type; - - if (transformation.getType() == null) { - if (input.getName().endsWith(".properties")) { - type = Transformation.PROPERTIES_TYPE; - } else if (input.getName().endsWith(".xml")) { - type = Transformation.XML_TYPE; - } else { - if (getLog() != null) { - getLog().warn( - "Could not auto-detect type of input [" + input - + "], assuming it is XML. It is recommended that you configure it in your pom.xml (tag: transformations/transformation/type) to avoid errors"); - } - type = Transformation.XML_TYPE; - } - } else { - type = transformation.getType(); - } - - return type; - } - - /** - * Processes a file. - * - * @param resolver - * @param inputName Symbolic name of the input file to read from. - * @param input Input file to read from. - * @param output Output file to write to. - * @param configName Symbolic name of the file containing rules to process the input. - * @param action Action to be performed on the input file. - * @param type Type of the input file. Properties, XML or null if it is to be auto-detected. - * @throws ConfigProcessorException If processing cannot be performed. - */ - protected void process(ExpressionResolver resolver, String inputName, File input, File output, String configName, Action action, String type) throws ConfigProcessorException { - getLog().info("Processing file [" + inputName + "] using config [" + configName + "], outputing to [" + output + "]"); - - InputStream inputStream = null; - ByteArrayOutputStream outputStream = null; - - InputStreamReader inputStreamReader = null; - OutputStreamWriter outputStreamWriter = null; - try { - inputStream = new FileInputStream(input); - outputStream = new ByteArrayOutputStream(); - - inputStreamReader = new InputStreamReader(inputStream, encoding); - outputStreamWriter = new OutputStreamWriter(outputStream, encoding); - - ActionProcessor processor = getActionProcessor(resolver, type); - processor.process(inputStreamReader, outputStreamWriter, action); - } catch (ParsingException e) { - throw new ConfigProcessorException("Error processing file [" + inputName + "] using configuration [" + configName + "]", e); - } catch (IOException e) { - throw new ConfigProcessorException("Error reading/writing files. Input is [" + inputName + "], configuration is [" + configName + "]", e); - } finally { - close(inputStreamReader, getLog()); - } - FileOutputStream fileOut = null; - try { - fileOut = new FileOutputStream(output); - outputStream.writeTo(fileOut); - } catch (FileNotFoundException e) { - getLog().error("Error opening file [" + output + "]", e); - } catch (IOException e) { - getLog().error("Error writing file [" + output + "]", e); - } finally { - close(outputStreamWriter, getLog()); - close(fileOut, getLog()); - } - } - - /** - * Obtain the action processor for the input. - * - * @param expressionResolver - * @param type Type of the input file. Properties or XML. - * @return ActionProcessor for the input file. - * @throws ConfigProcessorException If processing cannot be performed. - */ - protected ActionProcessor getActionProcessor(ExpressionResolver expressionResolver, String type) throws ConfigProcessorException { - if (Transformation.XML_TYPE.equals(type)) { - return new XmlActionProcessor(encoding, lineWidth, indentSize, fileResolver, expressionResolver, namespaceContexts, parserFeatures, failOnMissingXpath); - } else if (Transformation.PROPERTIES_TYPE.equals(type)) { - return new PropertiesActionProcessor(encoding, fileResolver, expressionResolver); - } else { - throw new ConfigProcessorException("Unknown file type [" + type + "]"); - } - } - - /** - * Creates output file and required directories. - * - * @param output Output file to create. - * @throws ConfigProcessorException If processing cannot be performed. - */ - protected void createOutputFile(File output) throws ConfigProcessorException { - try { - File directory = output.getParentFile(); - getLog().debug(output.toString()); - if (!directory.exists()) { - forceMkdirs(output.getParentFile()); - } - } catch (IOException e) { - throw new ConfigProcessorException(e.getMessage(), e); - } - } - - public LogAdapter getLog() { - return log; - } + private static final String DEFAULT_ENCODING = "UTF-8"; + + private String encoding; + private int lineWidth; + private int indentSize; + private Map namespaceContexts; + private boolean useOutputDirectory; + private File baseDir; + private File outputDirectory; + private LogAdapter log; + private FileResolver fileResolver; + private List parserFeatures; + private boolean failOnMissingXpath; + + private File actualOutputDirectory; + + public ConfigProcessor(String encoding, + int indentSize, + int lineWidth, + Map namespaceContexts, + File baseDir, + File outputDirectory, + boolean useOutputDirectory, + LogAdapter log, + FileResolver fileResolver, + List parserFeatures, + boolean failOnMissingXpath) { + this.encoding = encoding; + this.indentSize = indentSize; + this.lineWidth = lineWidth; + this.namespaceContexts = namespaceContexts; + this.baseDir = baseDir; + this.outputDirectory = outputDirectory; + this.useOutputDirectory = useOutputDirectory; + this.log = log; + this.fileResolver = fileResolver; + this.parserFeatures = parserFeatures; + this.failOnMissingXpath = failOnMissingXpath; + } + + public void init() throws IOException { + if (useOutputDirectory) { + if (!outputDirectory.exists() && !outputDirectory.mkdirs()) { + throw new IOException("Could not create outputDirectory [" + outputDirectory + "]"); + } + actualOutputDirectory = outputDirectory; + } + if (encoding == null) { + getLog().warn("Encoding has not been set, using default [" + DEFAULT_ENCODING + "]."); + encoding = DEFAULT_ENCODING; + } + + getLog().debug("Using output directory [" + actualOutputDirectory + "]"); + getLog().debug("File encodig is [" + encoding + "]"); + } + + public void execute(ExpressionResolver resolver, Transformation transformation) throws ConfigProcessorException, IOException { + String input = transformation.getInput(); + Action action = getAction(transformation); + String configIdentifier = getConfigIdentifier(transformation); + + if (input != null && input.contains("*")) { + // input parameter specifies a wildcard pattern + if (!StringUtils.isBlank(transformation.getOutput())) { + throw new ConfigProcessorException("Cannot specify output file if wildcard pattern based input is given"); + } + getLog().info("Using wildcard pattern based input [" + input + "]"); + List inputFiles = getMatchingFiles(input); + for (File inputFile : inputFiles) { + String type = getInputType(transformation); + if (actualOutputDirectory == null) { + throw new ConfigProcessorException("Output directory must be set"); + } + // calculate a relative path below the output directory based on the input file + File outputFile = new File(actualOutputDirectory, baseDir.toURI().relativize(inputFile.toURI()).getPath()); + createOutputFile(outputFile); + if (!inputFile.exists()) { + throw new ConfigProcessorException("File not found: " + inputFile); + } + InputStream inputStream = new FileInputStream(inputFile); + process(resolver, inputFile.getPath(), inputStream, outputFile, configIdentifier, action, type); + } + } else { + InputStream inputStream; + try { + inputStream = fileResolver.resolve(transformation.getInput()); + } catch (Exception e) { + throw new ConfigProcessorException("Input file [" + transformation.getInput() + "] does not exist"); + } + // use input file as output file if output is not set + File output; + if (StringUtils.isBlank(transformation.getOutput())) { + throw new ConfigProcessorException("Output must be set"); + } else { + output = new File(actualOutputDirectory, transformation.getOutput()); + createOutputFile(output); + } + String type = getInputType(transformation); + process(resolver, transformation.getInput(), inputStream, output, configIdentifier, action, type); + } + } + + protected Action getAction(Transformation transformation) throws ConfigProcessorException, IOException { + if (transformation.getConfig() == null && transformation.getRules() == null) { + throw new ConfigProcessorException("Transformation config file or rules must be set"); + } else if (transformation.getConfig() != null && transformation.getRules() != null) { + throw new ConfigProcessorException("Cannot specify transformation config file and rules at the same time"); + } + + Action action; + Reader configReader; + if (transformation.getConfig() == null) { + StringWriter writer = new StringWriter(); + AntrunXmlPlexusConfigurationWriter xmlWriter = new AntrunXmlPlexusConfigurationWriter(); + xmlWriter.write(transformation.getRules(), writer); + String configContent = trimToNull(writer.toString()); + configContent = removeStart(configContent, ""); + configContent = removeEnd(configContent, ""); + StringBuilder sb = new StringBuilder(configContent.length() + XmlHelper.ROOT_PROCESSOR_START.length() + XmlHelper.ROOT_PROCESSOR_END.length()); + sb.append(XmlHelper.ROOT_PROCESSOR_START); + sb.append(configContent); + sb.append(XmlHelper.ROOT_PROCESSOR_END); + configReader = new StringReader(sb.toString()); + } else { + InputStream config = fileResolver.resolve(transformation.getConfig()); + + if (config == null) { + throw new ConfigProcessorException("Configuration file [" + config + "] does not exist"); + } + + configReader = new InputStreamReader(config, encoding); + } + + try { + ProcessingConfigurationParser parser = new ProcessingConfigurationParser(); + action = parser.parse(configReader); + } catch (ParsingException e) { + throw new ConfigProcessorException("Error parsing transformation config [" + getConfigIdentifier(transformation) + "]", e); + } finally { + close(configReader, getLog()); + } + action.validate(); + + return action; + } + + protected String getConfigIdentifier(Transformation transformation) throws ConfigProcessorException { + if (transformation.getConfig() == null) { + StringWriter writer = new StringWriter(); + AntrunXmlPlexusConfigurationWriter xmlWriter = new AntrunXmlPlexusConfigurationWriter(); + try { + xmlWriter.write(transformation.getRules(), writer); + } catch (IOException e) { + throw new ConfigProcessorException("Shouldn't happen because there is no I/O here", e); + } + return abbreviate(trimToNull(removeStart(writer.toString(), "")), 100); + } + return transformation.getConfig(); + } + + /** + * Scans all files below the given baseDirectory using the supplied pattern. + * All files matching the pattern are returned. + * The implementation is utilizing {@link DirectoryScanner} for pattern matching, e.g. + * it allows to use single ("*") and double wildcards ("**") for matching + * arbitrary characters or directories. + * + * Examples: + * + * + * + * + * + * + * + * + * + *
+ * + *
+     * *.xml
+     * 
+ * + *
matches all XML files in the base directory
+ * + *
+     * **\/*.xml
+     * 
+ * + *
matches all XML files in any subfolder
+ * + * @param pattern the directory and file name pattern that files shall match + * @return the {@link List} of {@link File}s that match the given pattern + * @throws ConfigProcessorException + */ + protected List getMatchingFiles(String pattern) throws ConfigProcessorException { + if (pattern == null || pattern.length() == 0) { + throw new ConfigProcessorException("Invalid pattern [" + pattern + "]"); + } + DirectoryScanner scanner = new DirectoryScanner(); + scanner.setBasedir(baseDir); + scanner.setIncludes(new String[] { pattern }); + scanner.setCaseSensitive(false); + scanner.scan(); + String[] fileNames = scanner.getIncludedFiles(); + List files = new ArrayList(); + for (String fileName : fileNames) { + files.add(new File(baseDir, fileName)); + } + return files; + } + + /** + * Detects input file type. + * If {@link com.google.code.configprocessor.Transformation#getType()} is not null, + * this type is used, otherwise it is tried to guess the type from the given + * input File based on the file extension (.properties or .xml). + * If no type could be found or guessed, {@link Transformation#XML_TYPE} is used. + * + * @param transformation which can have an explicit type set + * @param input file from which the type can be guessed if transformation parameter does not + * contain a type + * @return Input file type. + */ + protected String getInputType(Transformation transformation) { + String type; + String input = transformation.getInput(); + if (transformation.getType() == null) { + if (input.endsWith(".properties")) { + type = Transformation.PROPERTIES_TYPE; + } else if (input.endsWith(".xml")) { + type = Transformation.XML_TYPE; + } else { + if (getLog() != null) { + getLog().warn( + "Could not auto-detect type of input [" + input + + "], assuming it is XML. It is recommended that you configure it in your pom.xml (tag: transformations/transformation/type) to avoid errors"); + } + type = Transformation.XML_TYPE; + } + } else { + type = transformation.getType(); + } + + return type; + } + + /** + * Processes a file. + * + * @param resolver + * @param inputName Symbolic name of the input file to read from. + * @param inputStream2 Input file to read from. + * @param output Output file to write to. + * @param configName Symbolic name of the file containing rules to process the input. + * @param action Action to be performed on the input file. + * @param type Type of the input file. Properties, XML or null if it is to be auto-detected. + * @throws ConfigProcessorException If processing cannot be performed. + */ + protected void process(ExpressionResolver resolver, String inputName, InputStream inputStream, File output, String configName, Action action, String type) throws ConfigProcessorException { + getLog().info("Processing file [" + inputName + "] using config [" + configName + "], outputing to [" + output + "]"); + + ByteArrayOutputStream outputStream = null; + + InputStreamReader inputStreamReader = null; + OutputStreamWriter outputStreamWriter = null; + try { + outputStream = new ByteArrayOutputStream(); + + inputStreamReader = new InputStreamReader(inputStream, encoding); + outputStreamWriter = new OutputStreamWriter(outputStream, encoding); + + ActionProcessor processor = getActionProcessor(resolver, type); + processor.process(inputStreamReader, outputStreamWriter, action); + } catch (ParsingException e) { + throw new ConfigProcessorException("Error processing file [" + inputName + "] using configuration [" + configName + "]", e); + } catch (IOException e) { + throw new ConfigProcessorException("Error reading/writing files. Input is [" + inputName + "], configuration is [" + configName + "]", e); + } finally { + close(inputStreamReader, getLog()); + } + FileOutputStream fileOut = null; + try { + fileOut = new FileOutputStream(output); + outputStream.writeTo(fileOut); + } catch (FileNotFoundException e) { + getLog().error("Error opening file [" + output + "]", e); + } catch (IOException e) { + getLog().error("Error writing file [" + output + "]", e); + } finally { + close(outputStreamWriter, getLog()); + close(fileOut, getLog()); + } + } + + /** + * Obtain the action processor for the input. + * + * @param expressionResolver + * @param type Type of the input file. Properties or XML. + * @return ActionProcessor for the input file. + * @throws ConfigProcessorException If processing cannot be performed. + */ + protected ActionProcessor getActionProcessor(ExpressionResolver expressionResolver, String type) throws ConfigProcessorException { + if (Transformation.XML_TYPE.equals(type)) { + return new XmlActionProcessor(encoding, lineWidth, indentSize, fileResolver, expressionResolver, namespaceContexts, parserFeatures, failOnMissingXpath); + } else if (Transformation.PROPERTIES_TYPE.equals(type)) { + return new PropertiesActionProcessor(encoding, fileResolver, expressionResolver); + } else { + throw new ConfigProcessorException("Unknown file type [" + type + "]"); + } + } + + /** + * Creates output file and required directories. + * + * @param output Output file to create. + * @throws ConfigProcessorException If processing cannot be performed. + */ + protected void createOutputFile(File output) throws ConfigProcessorException { + try { + File directory = output.getParentFile(); + getLog().debug(output.toString()); + if (!directory.exists()) { + forceMkdirs(output.getParentFile()); + } + } catch (IOException e) { + throw new ConfigProcessorException(e.getMessage(), e); + } + } + + public LogAdapter getLog() { + return log; + } } diff --git a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/ClasspathFileResolver.java b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/ClasspathFileResolver.java index d016120..4248b3c 100644 --- a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/ClasspathFileResolver.java +++ b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/ClasspathFileResolver.java @@ -15,17 +15,18 @@ */ package com.google.code.configprocessor.io; -import java.io.*; -import java.net.*; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; public class ClasspathFileResolver implements FileResolver { - public File resolve(String name) throws IOException { - URL url = getClass().getResource(name); - if (url == null) { - throw new FileNotFoundException("Classpath resource [" + name + "] not found"); - } - return new File(url.getPath()); - } + public InputStream resolve(String name) throws IOException { + InputStream inputStream = getClass().getResourceAsStream(name); + if (inputStream == null) { + throw new FileNotFoundException("Classpath resource [" + name + "] not found"); + } + return inputStream; + } } diff --git a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/DefaultFileResolver.java b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/DefaultFileResolver.java index c264255..933d265 100644 --- a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/DefaultFileResolver.java +++ b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/DefaultFileResolver.java @@ -19,12 +19,18 @@ public class DefaultFileResolver implements FileResolver { - public File resolve(String name) throws IOException { - File file = new File(name); - if (!file.exists()) { - throw new FileNotFoundException("File [" + name + "] does not exist"); - } - return file; - } + ClasspathFileResolver classpathFileResolver = new ClasspathFileResolver(); + + public InputStream resolve(String name) throws IOException { + if (name.startsWith("classpath:")) { + String resourcePath = name.replace("classpath:", ""); + return classpathFileResolver.resolve(resourcePath); + } + File file = new File(name); + if (!file.exists()) { + throw new FileNotFoundException("File [" + name + "] does not exist"); + } + return new FileInputStream(file); + } } diff --git a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/FileResolver.java b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/FileResolver.java index 7406cf9..60ae7d5 100644 --- a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/FileResolver.java +++ b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/FileResolver.java @@ -19,6 +19,6 @@ public interface FileResolver { - File resolve(String name) throws IOException; + InputStream resolve(String name) throws IOException; } diff --git a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/maven/MavenFileResolver.java b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/maven/MavenFileResolver.java index 3f62312..34848ff 100644 --- a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/maven/MavenFileResolver.java +++ b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/maven/MavenFileResolver.java @@ -29,33 +29,32 @@ public class MavenFileResolver implements FileResolver { - private Locator locator; - private LogAdapter logAdapter; - - public MavenFileResolver(MavenProject mavenProject, ArtifactFactory artifactFactory, ArtifactResolver artifactResolver, ArtifactRepository localRepository, List remoteRepositories, LogAdapter logAdapter) { - this.logAdapter = logAdapter; - locator = new Locator(); - List strategies = new ArrayList(); - strategies.add(new RelativeFileLocatorStrategy(mavenProject)); - strategies.add(new ClasspathResourceLocatorStrategy()); - strategies.add(new ArtifactLocatorStrategy(artifactFactory, artifactResolver, localRepository, remoteRepositories)); - strategies.add(new URLLocatorStrategy()); - locator.setStrategies(strategies); - } - - public File resolve(String name) throws IOException { - Location location = locator.resolve(name); - if (location == null) { - throw new IOException("File not found [" + name + "]\n" + locator.getMessageHolder().render()); - } - - try { - File file = location.getFile(); - logAdapter.debug("Resolved [" + name + "] to file [" + file + "]"); - return file; - } catch (IOException e) { - throw new IOException("Failed to load file [" + name + "]\n" + locator.getMessageHolder().render()); - } - } + private Locator locator; + private LogAdapter logAdapter; + + public MavenFileResolver(MavenProject mavenProject, ArtifactFactory artifactFactory, ArtifactResolver artifactResolver, ArtifactRepository localRepository, List remoteRepositories, LogAdapter logAdapter) { + this.logAdapter = logAdapter; + locator = new Locator(); + List strategies = new ArrayList(); + strategies.add(new RelativeFileLocatorStrategy(mavenProject)); + strategies.add(new ClasspathResourceLocatorStrategy()); + strategies.add(new ArtifactLocatorStrategy(artifactFactory, artifactResolver, localRepository, remoteRepositories)); + strategies.add(new URLLocatorStrategy()); + locator.setStrategies(strategies); + } + + public InputStream resolve(String name) throws IOException { + Location location = locator.resolve(name); + if (location == null) { + throw new IOException("File not found [" + name + "]\n" + locator.getMessageHolder().render()); + } + + InputStream inputStream = location.getInputStream(); + if (inputStream != null) { + logAdapter.debug("Resolved [" + name + "] to an inputStream [" + location + "]"); + return inputStream; + } + throw new IOException("Failed to load file [" + name + "]\n" + locator.getMessageHolder().render()); + } } diff --git a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/processing/properties/PropertiesActionProcessor.java b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/processing/properties/PropertiesActionProcessor.java index e2d5447..560572c 100644 --- a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/processing/properties/PropertiesActionProcessor.java +++ b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/processing/properties/PropertiesActionProcessor.java @@ -27,187 +27,187 @@ public class PropertiesActionProcessor implements ActionProcessor { - public static final String LINE_SEPARATOR = System.getProperty("line.separator"); - private static final int READ_AHEAD_BUFFER_SIZE = 1024 * 10; - - private String encoding; - private FileResolver fileResolver; - private ExpressionResolver expressionResolver; - - private Set appendedFiles; - - public PropertiesActionProcessor(String encoding, FileResolver fileResolver, ExpressionResolver expressionResolver) { - this.encoding = encoding; - this.fileResolver = fileResolver; - this.expressionResolver = expressionResolver; - this.appendedFiles = new HashSet(); - } - - public void process(Reader input, Writer output, Action action) throws ParsingException, IOException { - BufferedReader reader = new BufferedReader(input); - BufferedWriter writer = new BufferedWriter(output); - process(reader, writer, action); - } - - protected void process(BufferedReader reader, BufferedWriter writer, Action action) throws ParsingException, IOException { - PropertiesActionProcessingAdvisor advisor = getAdvisorFor(action); - - // Start - PropertiesFileItemAdvice advice = advisor.onStartProcessing(); - processAdvice(advice, null, writer, action); - - // Process - PropertiesFileItem currentItem = null; - String line; - while ((line = reader.readLine()) != null) { - if (isBlankLine(line)) { - writer.append(LINE_SEPARATOR); - } else { - if (isComment(line)) { - currentItem = readComment(reader, line); - } else { - currentItem = readPropertyMapping(reader, line); - } - - advice = advisor.process(currentItem); - processAdvice(advice, currentItem, writer, action); - } - } - - // End - advice = advisor.onEndProcessing(); - processAdvice(advice, null, writer, action); - - writer.flush(); - } - - protected Comment readComment(BufferedReader reader, String line) throws IOException { - if (line == null) { - return new Comment(""); - } - - boolean shouldContinue = true; - StringBuilder sb = new StringBuilder(line); - - String aux = line; - while (shouldContinue && (aux != null) && aux.endsWith(PropertyMapping.PROPERTY_VALUE_LINE_SEPARATOR)) { - reader.mark(READ_AHEAD_BUFFER_SIZE); - aux = reader.readLine(); - - if (aux == null) { - shouldContinue = false; - } else { - if (isComment(aux)) { - sb.append(LINE_SEPARATOR); - sb.append(aux); - } else { - shouldContinue = false; - reader.reset(); - } - } - } - - return new Comment(sb.toString()); - } - - protected PropertyMapping readPropertyMapping(BufferedReader reader, String line) throws IOException { - StringBuilder sb = new StringBuilder(line); - String aux = line; - while (aux.endsWith(PropertyMapping.PROPERTY_VALUE_LINE_SEPARATOR)) { - aux = reader.readLine(); - if (aux == null) { - break; - } - sb.append(LINE_SEPARATOR); - sb.append(aux); - } - - PropertyMapping propertyMapping = new PropertyMapping(); - propertyMapping.parse(sb.toString(), false); - - return propertyMapping; - } - - protected void processAdvice(PropertiesFileItemAdvice advice, PropertiesFileItem currentItem, BufferedWriter writer, Action action) throws ParsingException, IOException { - switch (advice.getType()) { - case DO_NOTHING: - append(currentItem, writer); - break; - case REMOVE: - break; - case MODIFY: - append(advice.getItem(), writer); - break; - case ADD_AFTER: - append(currentItem, writer); - append(advice.getItem(), writer); - break; - case ADD_BEFORE: - append(advice.getItem(), writer); - append(currentItem, writer); - break; - case APPEND_FILE_AFTER: - append(currentItem, writer); - appendFile(advice.getItem(), writer, action); - break; - case APPEND_FILE_BEFORE: - appendFile(advice.getItem(), writer, action); - append(currentItem, writer); - break; - default: - throw new IllegalArgumentException("Unknown advice type: " + advice.getType()); - } - } - - protected void append(PropertiesFileItem item, BufferedWriter writer) throws IOException { - if (item != null) { - writer.append(item.getAsText()); - writer.append(LINE_SEPARATOR); - } - } - - protected void appendFile(PropertiesFileItem item, BufferedWriter writer, Action action) throws ParsingException, IOException { - FilePropertiesFileItem aux = (FilePropertiesFileItem)item; - File file = fileResolver.resolve(aux.getFile()); - if (appendedFiles.add(file)) { // Prevent adding the same file twice - InputStreamReader reader = new InputStreamReader(new FileInputStream(file), encoding); - try { - process(reader, writer, action); - } finally { - IOUtils.close(reader, null); - } - } - } - - protected PropertiesActionProcessingAdvisor getAdvisorFor(Action action) { - if (action instanceof AddAction) { - return new PropertiesAddActionProcessingAdvisor((AddAction) action, expressionResolver); - } else if (action instanceof ModifyAction) { - return new PropertiesModifyActionProcessingAdvisor((ModifyAction) action, expressionResolver); - } else if (action instanceof RemoveAction) { - return new PropertiesRemoveActionProcessingAdvisor((RemoveAction) action, expressionResolver); - } else if (action instanceof CommentAction) { - return new PropertiesCommentActionProcessingAdvisor((CommentAction) action, expressionResolver); - } else if (action instanceof UncommentAction) { - return new PropertiesUncommentActionProcessingAdvisor((UncommentAction) action, expressionResolver); - } else if (action instanceof NestedAction) { - List advisors = new ArrayList(); - NestedAction nestedAction = (NestedAction) action; - for (Action nested : nestedAction.getActions()) { - advisors.add(getAdvisorFor(nested)); - } - return new NestedPropertiesActionProcessingAdvisor(advisors); - } - throw new IllegalArgumentException("Unknown action: " + action); - } - - protected boolean isBlankLine(String line) { - return line.trim().length() == 0; - } - - protected boolean isComment(String line) { - String trimmedLine = line.trim(); - return trimmedLine.startsWith(Comment.PREFIX_1) || trimmedLine.startsWith(Comment.PREFIX_2); - } + public static final String LINE_SEPARATOR = System.getProperty("line.separator"); + private static final int READ_AHEAD_BUFFER_SIZE = 1024 * 10; + + private String encoding; + private FileResolver fileResolver; + private ExpressionResolver expressionResolver; + + private Set appendedFiles; + + public PropertiesActionProcessor(String encoding, FileResolver fileResolver, ExpressionResolver expressionResolver) { + this.encoding = encoding; + this.fileResolver = fileResolver; + this.expressionResolver = expressionResolver; + this.appendedFiles = new HashSet(); + } + + public void process(Reader input, Writer output, Action action) throws ParsingException, IOException { + BufferedReader reader = new BufferedReader(input); + BufferedWriter writer = new BufferedWriter(output); + process(reader, writer, action); + } + + protected void process(BufferedReader reader, BufferedWriter writer, Action action) throws ParsingException, IOException { + PropertiesActionProcessingAdvisor advisor = getAdvisorFor(action); + + // Start + PropertiesFileItemAdvice advice = advisor.onStartProcessing(); + processAdvice(advice, null, writer, action); + + // Process + PropertiesFileItem currentItem = null; + String line; + while ((line = reader.readLine()) != null) { + if (isBlankLine(line)) { + writer.append(LINE_SEPARATOR); + } else { + if (isComment(line)) { + currentItem = readComment(reader, line); + } else { + currentItem = readPropertyMapping(reader, line); + } + + advice = advisor.process(currentItem); + processAdvice(advice, currentItem, writer, action); + } + } + + // End + advice = advisor.onEndProcessing(); + processAdvice(advice, null, writer, action); + + writer.flush(); + } + + protected Comment readComment(BufferedReader reader, String line) throws IOException { + if (line == null) { + return new Comment(""); + } + + boolean shouldContinue = true; + StringBuilder sb = new StringBuilder(line); + + String aux = line; + while (shouldContinue && (aux != null) && aux.endsWith(PropertyMapping.PROPERTY_VALUE_LINE_SEPARATOR)) { + reader.mark(READ_AHEAD_BUFFER_SIZE); + aux = reader.readLine(); + + if (aux == null) { + shouldContinue = false; + } else { + if (isComment(aux)) { + sb.append(LINE_SEPARATOR); + sb.append(aux); + } else { + shouldContinue = false; + reader.reset(); + } + } + } + + return new Comment(sb.toString()); + } + + protected PropertyMapping readPropertyMapping(BufferedReader reader, String line) throws IOException { + StringBuilder sb = new StringBuilder(line); + String aux = line; + while (aux.endsWith(PropertyMapping.PROPERTY_VALUE_LINE_SEPARATOR)) { + aux = reader.readLine(); + if (aux == null) { + break; + } + sb.append(LINE_SEPARATOR); + sb.append(aux); + } + + PropertyMapping propertyMapping = new PropertyMapping(); + propertyMapping.parse(sb.toString(), false); + + return propertyMapping; + } + + protected void processAdvice(PropertiesFileItemAdvice advice, PropertiesFileItem currentItem, BufferedWriter writer, Action action) throws ParsingException, IOException { + switch (advice.getType()) { + case DO_NOTHING: + append(currentItem, writer); + break; + case REMOVE: + break; + case MODIFY: + append(advice.getItem(), writer); + break; + case ADD_AFTER: + append(currentItem, writer); + append(advice.getItem(), writer); + break; + case ADD_BEFORE: + append(advice.getItem(), writer); + append(currentItem, writer); + break; + case APPEND_FILE_AFTER: + append(currentItem, writer); + appendFile(advice.getItem(), writer, action); + break; + case APPEND_FILE_BEFORE: + appendFile(advice.getItem(), writer, action); + append(currentItem, writer); + break; + default: + throw new IllegalArgumentException("Unknown advice type: " + advice.getType()); + } + } + + protected void append(PropertiesFileItem item, BufferedWriter writer) throws IOException { + if (item != null) { + writer.append(item.getAsText()); + writer.append(LINE_SEPARATOR); + } + } + + protected void appendFile(PropertiesFileItem item, BufferedWriter writer, Action action) throws ParsingException, IOException { + FilePropertiesFileItem aux = (FilePropertiesFileItem)item; + InputStream inputStream = fileResolver.resolve(aux.getFile()); + if (appendedFiles.add(aux.getFile())) { // Prevent adding the same file twice + InputStreamReader reader = new InputStreamReader(inputStream, encoding); + try { + process(reader, writer, action); + } finally { + IOUtils.close(reader, null); + } + } + } + + protected PropertiesActionProcessingAdvisor getAdvisorFor(Action action) { + if (action instanceof AddAction) { + return new PropertiesAddActionProcessingAdvisor((AddAction) action, expressionResolver); + } else if (action instanceof ModifyAction) { + return new PropertiesModifyActionProcessingAdvisor((ModifyAction) action, expressionResolver); + } else if (action instanceof RemoveAction) { + return new PropertiesRemoveActionProcessingAdvisor((RemoveAction) action, expressionResolver); + } else if (action instanceof CommentAction) { + return new PropertiesCommentActionProcessingAdvisor((CommentAction) action, expressionResolver); + } else if (action instanceof UncommentAction) { + return new PropertiesUncommentActionProcessingAdvisor((UncommentAction) action, expressionResolver); + } else if (action instanceof NestedAction) { + List advisors = new ArrayList(); + NestedAction nestedAction = (NestedAction) action; + for (Action nested : nestedAction.getActions()) { + advisors.add(getAdvisorFor(nested)); + } + return new NestedPropertiesActionProcessingAdvisor(advisors); + } + throw new IllegalArgumentException("Unknown action: " + action); + } + + protected boolean isBlankLine(String line) { + return line.trim().length() == 0; + } + + protected boolean isComment(String line) { + String trimmedLine = line.trim(); + return trimmedLine.startsWith(Comment.PREFIX_1) || trimmedLine.startsWith(Comment.PREFIX_2); + } } diff --git a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/processing/xml/XmlActionProcessor.java b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/processing/xml/XmlActionProcessor.java index 1df93e2..3ded5f1 100644 --- a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/processing/xml/XmlActionProcessor.java +++ b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/processing/xml/XmlActionProcessor.java @@ -31,91 +31,91 @@ public class XmlActionProcessor implements ActionProcessor { - public static final String LINE_SEPARATOR = System.getProperty("line.separator"); + public static final String LINE_SEPARATOR = System.getProperty("line.separator"); - private String encoding; - private int lineWidth; - private int indentSize; - private FileResolver fileResolver; - private ExpressionResolver expressionResolver; - private MapBasedNamespaceContext namespaceContext; - private List parserFeatures; + private String encoding; + private int lineWidth; + private int indentSize; + private FileResolver fileResolver; + private ExpressionResolver expressionResolver; + private MapBasedNamespaceContext namespaceContext; + private List parserFeatures; private boolean failOnMissingXpath; public XmlActionProcessor(String encoding, int lineWidth, int indentSize, FileResolver fileResolver, ExpressionResolver expressionResolver, Map contextMappings, - List parserFeatures, boolean failOnMissingXpath) { - this.encoding = encoding; - this.lineWidth = lineWidth; - this.indentSize = indentSize; - this.fileResolver = fileResolver; - this.expressionResolver = expressionResolver; - this.namespaceContext = new MapBasedNamespaceContext(contextMappings); - this.parserFeatures = parserFeatures; + List parserFeatures, boolean failOnMissingXpath) { + this.encoding = encoding; + this.lineWidth = lineWidth; + this.indentSize = indentSize; + this.fileResolver = fileResolver; + this.expressionResolver = expressionResolver; + this.namespaceContext = new MapBasedNamespaceContext(contextMappings); + this.parserFeatures = parserFeatures; this.failOnMissingXpath = failOnMissingXpath; - } + } - public void process(Reader input, Writer output, Action action) throws ParsingException, IOException { - try { - Document document = XmlHelper.parse(input, parserFeatures); - // While processing add-include actions that don't contain nested - // actions, - // we ended up calling getAdvisorFor with nulls, resulting in an - // exception. - if (action != null) { - XmlActionProcessingAdvisor advisor = getAdvisorFor(action, action); - advisor.process(document); - } - XmlHelper.write(output, document, encoding, lineWidth, indentSize); - } catch (SAXException e) { - throw new ParsingException(e); - } catch (ParserConfigurationException e) { - throw new ParsingException(e); - } - } + public void process(Reader input, Writer output, Action action) throws ParsingException, IOException { + try { + Document document = XmlHelper.parse(input, parserFeatures); + // While processing add-include actions that don't contain nested + // actions, + // we ended up calling getAdvisorFor with nulls, resulting in an + // exception. + if (action != null) { + XmlActionProcessingAdvisor advisor = getAdvisorFor(action, action); + advisor.process(document); + } + XmlHelper.write(output, document, encoding, lineWidth, indentSize); + } catch (SAXException e) { + throw new ParsingException(e); + } catch (ParserConfigurationException e) { + throw new ParsingException(e); + } + } - protected XmlActionProcessingAdvisor getAdvisorFor(Action rootAction, Action action) throws ParsingException, IOException { - if (action instanceof AddAction) { - // Processes the file applying all sub-transformations before - // passing it over to the advisor - AddAction addAction = (AddAction) action; - String fileName = expressionResolver.resolve(addAction.getFile(), false); - String fileContent = null; - if (fileName != null) { - fileContent = getProcessedFile(fileName, addAction.getNestedAction()); + protected XmlActionProcessingAdvisor getAdvisorFor(Action rootAction, Action action) throws ParsingException, IOException { + if (action instanceof AddAction) { + // Processes the file applying all sub-transformations before + // passing it over to the advisor + AddAction addAction = (AddAction) action; + String fileName = expressionResolver.resolve(addAction.getFile(), false); + String fileContent = null; + if (fileName != null) { + fileContent = getProcessedFile(fileName, addAction.getNestedAction()); - // Not having managed to get fileContent here is going to lead - // to a null pointer exception in - // XmlAddActionProcessingAdvisor's constructor. - // Putting in a more explicit exception message. - if (fileContent == null) { - throw new ParsingException(String.format("Processing file \"%s\" yielded null content.", addAction.getFile())); - } - } - return new XmlAddActionProcessingAdvisor((AddAction) action, fileContent, expressionResolver, namespaceContext, parserFeatures, failOnMissingXpath); - } else if (action instanceof ModifyAction) { - return new XmlModifyActionProcessingAdvisor((ModifyAction) action, expressionResolver, namespaceContext, parserFeatures, failOnMissingXpath); - } else if (action instanceof RemoveAction) { - return new XmlRemoveActionProcessingAdvisor((RemoveAction) action, expressionResolver, namespaceContext, parserFeatures, failOnMissingXpath); - } else if (action instanceof NestedAction) { - List advisors = new ArrayList(); - NestedAction nestedAction = (NestedAction) action; - for (Action nested : nestedAction.getActions()) { - advisors.add(getAdvisorFor(rootAction, nested)); - } - return new NestedXmlActionProcessingAdvisor(advisors, nestedAction); - } - throw new IllegalArgumentException("Unknown action: " + action); - } + // Not having managed to get fileContent here is going to lead + // to a null pointer exception in + // XmlAddActionProcessingAdvisor's constructor. + // Putting in a more explicit exception message. + if (fileContent == null) { + throw new ParsingException(String.format("Processing file \"%s\" yielded null content.", addAction.getFile())); + } + } + return new XmlAddActionProcessingAdvisor((AddAction) action, fileContent, expressionResolver, namespaceContext, parserFeatures, failOnMissingXpath); + } else if (action instanceof ModifyAction) { + return new XmlModifyActionProcessingAdvisor((ModifyAction) action, expressionResolver, namespaceContext, parserFeatures, failOnMissingXpath); + } else if (action instanceof RemoveAction) { + return new XmlRemoveActionProcessingAdvisor((RemoveAction) action, expressionResolver, namespaceContext, parserFeatures, failOnMissingXpath); + } else if (action instanceof NestedAction) { + List advisors = new ArrayList(); + NestedAction nestedAction = (NestedAction) action; + for (Action nested : nestedAction.getActions()) { + advisors.add(getAdvisorFor(rootAction, nested)); + } + return new NestedXmlActionProcessingAdvisor(advisors, nestedAction); + } + throw new IllegalArgumentException("Unknown action: " + action); + } - protected String getProcessedFile(String name, Action action) throws ParsingException, IOException { - File file = fileResolver.resolve(name); - InputStreamReader reader = new InputStreamReader(new FileInputStream(file), encoding); - StringWriter writer = new StringWriter(); - try { - process(reader, writer, action); - return writer.toString(); - } finally { - IOUtils.close(reader, null); - } - } + protected String getProcessedFile(String name, Action action) throws ParsingException, IOException { + InputStream inputStream = fileResolver.resolve(name); + InputStreamReader reader = new InputStreamReader(inputStream, encoding); + StringWriter writer = new StringWriter(); + try { + process(reader, writer, action); + return writer.toString(); + } finally { + IOUtils.close(reader, null); + } + } } diff --git a/maven-config-processor-plugin/src/test/java/com/google/code/configprocessor/ConfigProcessorTest.java b/maven-config-processor-plugin/src/test/java/com/google/code/configprocessor/ConfigProcessorTest.java index 7a9a3ba..09745d6 100644 --- a/maven-config-processor-plugin/src/test/java/com/google/code/configprocessor/ConfigProcessorTest.java +++ b/maven-config-processor-plugin/src/test/java/com/google/code/configprocessor/ConfigProcessorTest.java @@ -15,51 +15,151 @@ */ package com.google.code.configprocessor; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.PrintWriter; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.codehaus.plexus.util.IOUtil; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + import static org.easymock.EasyMock.*; import static org.easymock.classextension.EasyMock.*; import static org.junit.Assert.*; -import java.io.*; - -import org.junit.*; +import com.google.code.configprocessor.expression.ExpressionResolver; +import com.google.code.configprocessor.io.DefaultFileResolver; +import com.google.code.configprocessor.io.FileResolver; +import com.google.code.configprocessor.log.LogAdapter; +import com.google.code.configprocessor.processing.properties.AbstractPropertiesActionProcessingAdvisorTest; +import com.google.code.configprocessor.processing.properties.PropertiesActionProcessorTest; public class ConfigProcessorTest { - private ConfigProcessor configProcessor; - - @Before - public void setup() throws Exception { - configProcessor = new ConfigProcessor("UTF-8", 80, 4, null, null, null, false, null, null, null, true); - } - - @Test(expected = ConfigProcessorException.class) - public void testNullPattern() throws Exception { - File baseDir = createStrictMock(File.class); - expect(baseDir.isDirectory()).andReturn(true); - expect(baseDir.exists()).andReturn(true); - configProcessor.getMatchingFiles(null); - } - - @Test(expected = ConfigProcessorException.class) - public void testEmptyPattern() throws Exception { - File baseDir = createStrictMock(File.class); - expect(baseDir.isDirectory()).andReturn(true); - expect(baseDir.exists()).andReturn(true); - configProcessor.getMatchingFiles(""); - } - - @Test - public void testGetTypeFromTransformation() throws Exception { - Transformation transformation = new Transformation(); - transformation.setType(Transformation.PROPERTIES_TYPE); - assertEquals(Transformation.PROPERTIES_TYPE, configProcessor.getInputType(transformation, null)); - } - - @Test - public void testGuessTypeFromInputFile() throws Exception { - Transformation transformation = new Transformation(); - assertEquals(Transformation.PROPERTIES_TYPE, configProcessor.getInputType(transformation, new File("test.properties"))); - assertEquals(Transformation.XML_TYPE, configProcessor.getInputType(transformation, new File("test.xml"))); - assertEquals(Transformation.XML_TYPE, configProcessor.getInputType(transformation, new File("test.something"))); - } + private ConfigProcessor configProcessor; + @Rule + public TemporaryFolder folder= new TemporaryFolder(); + + + @Before + public void setup() throws Exception { + configProcessor = createConfigProcessor(null, false, null); + } + + @Test(expected = ConfigProcessorException.class) + public void testNullPattern() throws Exception { + File baseDir = createStrictMock(File.class); + expect(baseDir.isDirectory()).andReturn(true); + expect(baseDir.exists()).andReturn(true); + configProcessor.getMatchingFiles(null); + } + + @Test(expected = ConfigProcessorException.class) + public void testEmptyPattern() throws Exception { + File baseDir = createStrictMock(File.class); + expect(baseDir.isDirectory()).andReturn(true); + expect(baseDir.exists()).andReturn(true); + configProcessor.getMatchingFiles(""); + } + + @Test + public void testGetTypeFromTransformation() throws Exception { + Transformation transformation = new Transformation(); + transformation.setType(Transformation.PROPERTIES_TYPE); + assertEquals(Transformation.PROPERTIES_TYPE, configProcessor.getInputType(transformation)); + } + + @Test + public void testGuessTypeFromInputFile() throws Exception { + assertEquals(Transformation.PROPERTIES_TYPE, configProcessor.getInputType(transformationWithInput("test.properties"))); + assertEquals(Transformation.XML_TYPE, configProcessor.getInputType(transformationWithInput("test.xml"))); + assertEquals(Transformation.XML_TYPE, configProcessor.getInputType(transformationWithInput("test.something"))); + } + + private Transformation transformationWithInput(String input) { + Transformation transformation = new Transformation(); + transformation.setInput(input); + return transformation; + } + + @Test + public void testTransformationFromClasspathResource() throws Exception + { + File configFile = folder.newFile(); + PrintWriter writer = new PrintWriter(new FileOutputStream(configFile)); + writer.println(""); + writer.println(""); + writer.println(""); + writer.println("property1.value"); + writer.println("NEWTESTVALUE"); + writer.println(""); + writer.println(""); + writer.close(); + File outputDirectory = null; + File output = folder.newFile(); + boolean useOutputDirectory = false; + FileResolver fileResolver = new DefaultFileResolver(); + configProcessor = createConfigProcessor(outputDirectory, useOutputDirectory, fileResolver); + configProcessor.init(); + Transformation transformation = new Transformation(); + transformation.setInput("classpath:" + PropertiesActionProcessorTest.PROPERTIES_PATH); + transformation.setOutput(output.getAbsolutePath()); + transformation.setConfig(configFile.getAbsolutePath()); + ExpressionResolver resolver = getExpressionResolver(); + configProcessor.execute(resolver, transformation); + Properties properties = new Properties(); + properties.load(new FileInputStream(output.getAbsolutePath())); + assertEquals("NEWTESTVALUE", properties.getProperty("property1.value")); + } + + protected ExpressionResolver getExpressionResolver() { + return new AbstractPropertiesActionProcessingAdvisorTest.TestExpressionResolver(); + } + + private ConfigProcessor createConfigProcessor(File outputDirectory, + boolean useOutputDirectory, + FileResolver fileResolver) + { + Map namespaceContexts = null; + File baseDir = null; + LogAdapter log = new TestLogAdapter(); + List parserFeatures = null; + boolean failOnMissingXPath = true; + int indentSize = 4; + int lineWidth = 80; + return new ConfigProcessor("UTF-8", indentSize, lineWidth, namespaceContexts, baseDir, + outputDirectory, useOutputDirectory, log, fileResolver, parserFeatures, + failOnMissingXPath); + } + + public static class TestLogAdapter implements LogAdapter { + + public void info(String msg) { + System.out.println(msg); + } + + public void debug(String msg) { + System.out.println(msg); + } + + public void warn(String msg) { + System.out.println(msg); + } + + public void error(String msg, Throwable t) { + System.out.println(msg); + t.printStackTrace(System.out); + } + + public void verbose(String msg) { + System.out.println(msg); + } + + } } diff --git a/maven-config-processor-plugin/src/test/java/com/google/code/configprocessor/processing/properties/AbstractPropertiesActionProcessingAdvisorTest.java b/maven-config-processor-plugin/src/test/java/com/google/code/configprocessor/processing/properties/AbstractPropertiesActionProcessingAdvisorTest.java index 6464772..4ca2e39 100644 --- a/maven-config-processor-plugin/src/test/java/com/google/code/configprocessor/processing/properties/AbstractPropertiesActionProcessingAdvisorTest.java +++ b/maven-config-processor-plugin/src/test/java/com/google/code/configprocessor/processing/properties/AbstractPropertiesActionProcessingAdvisorTest.java @@ -32,53 +32,53 @@ public class AbstractPropertiesActionProcessingAdvisorTest { - private static final String ENCODING = "ISO-8859-1"; - - protected InputStream input; - protected ByteArrayOutputStream output; - protected ActionProcessor processor; - - public void setup() { - processor = new PropertiesActionProcessor(ENCODING, new ClasspathFileResolver(), new MavenExpressionResolver(new DefaultExpressionEvaluator())); - input = getClass().getResourceAsStream(PropertiesActionProcessorTest.PROPERTIES_PATH); - output = new ByteArrayOutputStream(); - } + private static final String ENCODING = "ISO-8859-1"; - @Test - public void testCreatePropertyMapping() throws Exception { - TestExpressionResolver resolver = new TestExpressionResolver(); - PropertiesAddActionProcessingAdvisor advisor = new PropertiesAddActionProcessingAdvisor(new AddAction(), resolver); - advisor.createPropertyMapping("name", "value"); - assertEquals(2, resolver.getResolvedValues().size()); - assertEquals(Arrays.asList("name", "value"), resolver.getResolvedValues()); - } + protected InputStream input; + protected ByteArrayOutputStream output; + protected ActionProcessor processor; - protected void executeTest(Action action, String expected) throws Exception { - setup(); - processor.process(new InputStreamReader(input), new OutputStreamWriter(output), action); - assertEquals(expected, getOutput()); - - setup(); - NestedAction nestedAction = new NestedAction(); - nestedAction.addAction(action); - processor.process(new InputStreamReader(input), new OutputStreamWriter(output), nestedAction); - assertEquals(expected, getOutput()); - } - - protected String getOutput() { - return new String(output.toByteArray()); - } + public void setup() { + processor = new PropertiesActionProcessor(ENCODING, new ClasspathFileResolver(), new MavenExpressionResolver(new DefaultExpressionEvaluator())); + input = getClass().getResourceAsStream(PropertiesActionProcessorTest.PROPERTIES_PATH); + output = new ByteArrayOutputStream(); + } - private static class TestExpressionResolver implements ExpressionResolver { - private List resolvedValues = new ArrayList(); + @Test + public void testCreatePropertyMapping() throws Exception { + TestExpressionResolver resolver = new TestExpressionResolver(); + PropertiesAddActionProcessingAdvisor advisor = new PropertiesAddActionProcessingAdvisor(new AddAction(), resolver); + advisor.createPropertyMapping("name", "value"); + assertEquals(2, resolver.getResolvedValues().size()); + assertEquals(Arrays.asList("name", "value"), resolver.getResolvedValues()); + } - public String resolve(String value, boolean isPropertiesValue) { - resolvedValues.add(value); - return value; - } + protected void executeTest(Action action, String expected) throws Exception { + setup(); + processor.process(new InputStreamReader(input), new OutputStreamWriter(output), action); + assertEquals(expected, getOutput()); - public List getResolvedValues() { - return resolvedValues; - } - } + setup(); + NestedAction nestedAction = new NestedAction(); + nestedAction.addAction(action); + processor.process(new InputStreamReader(input), new OutputStreamWriter(output), nestedAction); + assertEquals(expected, getOutput()); + } + + protected String getOutput() { + return new String(output.toByteArray()); + } + + public static class TestExpressionResolver implements ExpressionResolver { + private List resolvedValues = new ArrayList(); + + public String resolve(String value, boolean isPropertiesValue) { + resolvedValues.add(value); + return value; + } + + public List getResolvedValues() { + return resolvedValues; + } + } } From 18b6d474dd1c08e8755daa427ae1a46abf3f501c Mon Sep 17 00:00:00 2001 From: Levon Saldamli Date: Fri, 8 Jan 2016 13:46:47 +0100 Subject: [PATCH 2/5] Ida publishing --- maven-config-processor-plugin/pom.xml | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/maven-config-processor-plugin/pom.xml b/maven-config-processor-plugin/pom.xml index c17bfbf..4e7b88a 100644 --- a/maven-config-processor-plugin/pom.xml +++ b/maven-config-processor-plugin/pom.xml @@ -3,9 +3,9 @@ 4.0.0 - org.sonatype.oss - oss-parent - 7 + se.idainfront + ida-base-pom + 2.2 com.google.code.maven-config-processor-plugin @@ -13,6 +13,25 @@ 2.8-SNAPSHOT maven-plugin + + + internal-snapshots + internal-snapshots + http://repo.idainfront.se/content/groups/internal-snapshots + + + + + + + false + + central + internal + http://repo.idainfront.se/content/groups/internal + + + Config Processor Maven Plugin Generates configuration files modified according to a ruleset to prepare them for different environments http://code.google.com/p/maven-config-processor-plugin @@ -367,4 +386,5 @@ + From 6f08ede16e05aa7a15d82efd1443aae7cd5c4807 Mon Sep 17 00:00:00 2001 From: Levon Saldamli Date: Fri, 8 Jan 2016 13:46:57 +0100 Subject: [PATCH 3/5] Forward caught exception --- .../java/com/google/code/configprocessor/ConfigProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/ConfigProcessor.java b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/ConfigProcessor.java index 1fe9adc..d215f71 100644 --- a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/ConfigProcessor.java +++ b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/ConfigProcessor.java @@ -124,7 +124,7 @@ public void execute(ExpressionResolver resolver, Transformation transformation) try { inputStream = fileResolver.resolve(transformation.getInput()); } catch (Exception e) { - throw new ConfigProcessorException("Input file [" + transformation.getInput() + "] does not exist"); + throw new ConfigProcessorException("Input file [" + transformation.getInput() + "] does not exist", e); } // use input file as output file if output is not set File output; From 039bbe4e1e4b7fe76d689b085841ac1a0c5a7089 Mon Sep 17 00:00:00 2001 From: Levon Saldamli Date: Fri, 8 Jan 2016 14:27:33 +0100 Subject: [PATCH 4/5] Corrected snapshot upload repo --- maven-config-processor-plugin/pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/maven-config-processor-plugin/pom.xml b/maven-config-processor-plugin/pom.xml index 4e7b88a..be53521 100644 --- a/maven-config-processor-plugin/pom.xml +++ b/maven-config-processor-plugin/pom.xml @@ -15,9 +15,9 @@ - internal-snapshots - internal-snapshots - http://repo.idainfront.se/content/groups/internal-snapshots + iipax-snapshots + iipax-snapshots + http://repo.idainfront.se/content/repositories/iipax-snapshots @@ -27,8 +27,8 @@ false central - internal - http://repo.idainfront.se/content/groups/internal + internal-snapshots + http://repo.idainfront.se/content/groups/internal-snapshots From 1127d39df015241847053146d8761625c430ca69 Mon Sep 17 00:00:00 2001 From: Levon Saldamli Date: Fri, 8 Jan 2016 15:45:44 +0100 Subject: [PATCH 5/5] Converted spaces back to tabs. --- .../code/configprocessor/ConfigProcessor.java | 668 +++++++++--------- .../io/ClasspathFileResolver.java | 14 +- .../io/DefaultFileResolver.java | 24 +- .../code/configprocessor/io/FileResolver.java | 2 +- .../maven/MavenFileResolver.java | 54 +- .../properties/PropertiesActionProcessor.java | 364 +++++----- .../processing/xml/XmlActionProcessor.java | 162 ++--- .../configprocessor/ConfigProcessorTest.java | 240 +++---- ...PropertiesActionProcessingAdvisorTest.java | 80 +-- 9 files changed, 804 insertions(+), 804 deletions(-) diff --git a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/ConfigProcessor.java b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/ConfigProcessor.java index d215f71..015dbb9 100644 --- a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/ConfigProcessor.java +++ b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/ConfigProcessor.java @@ -37,338 +37,338 @@ public class ConfigProcessor { - private static final String DEFAULT_ENCODING = "UTF-8"; - - private String encoding; - private int lineWidth; - private int indentSize; - private Map namespaceContexts; - private boolean useOutputDirectory; - private File baseDir; - private File outputDirectory; - private LogAdapter log; - private FileResolver fileResolver; - private List parserFeatures; - private boolean failOnMissingXpath; - - private File actualOutputDirectory; - - public ConfigProcessor(String encoding, - int indentSize, - int lineWidth, - Map namespaceContexts, - File baseDir, - File outputDirectory, - boolean useOutputDirectory, - LogAdapter log, - FileResolver fileResolver, - List parserFeatures, - boolean failOnMissingXpath) { - this.encoding = encoding; - this.indentSize = indentSize; - this.lineWidth = lineWidth; - this.namespaceContexts = namespaceContexts; - this.baseDir = baseDir; - this.outputDirectory = outputDirectory; - this.useOutputDirectory = useOutputDirectory; - this.log = log; - this.fileResolver = fileResolver; - this.parserFeatures = parserFeatures; - this.failOnMissingXpath = failOnMissingXpath; - } - - public void init() throws IOException { - if (useOutputDirectory) { - if (!outputDirectory.exists() && !outputDirectory.mkdirs()) { - throw new IOException("Could not create outputDirectory [" + outputDirectory + "]"); - } - actualOutputDirectory = outputDirectory; - } - if (encoding == null) { - getLog().warn("Encoding has not been set, using default [" + DEFAULT_ENCODING + "]."); - encoding = DEFAULT_ENCODING; - } - - getLog().debug("Using output directory [" + actualOutputDirectory + "]"); - getLog().debug("File encodig is [" + encoding + "]"); - } - - public void execute(ExpressionResolver resolver, Transformation transformation) throws ConfigProcessorException, IOException { - String input = transformation.getInput(); - Action action = getAction(transformation); - String configIdentifier = getConfigIdentifier(transformation); - - if (input != null && input.contains("*")) { - // input parameter specifies a wildcard pattern - if (!StringUtils.isBlank(transformation.getOutput())) { - throw new ConfigProcessorException("Cannot specify output file if wildcard pattern based input is given"); - } - getLog().info("Using wildcard pattern based input [" + input + "]"); - List inputFiles = getMatchingFiles(input); - for (File inputFile : inputFiles) { - String type = getInputType(transformation); - if (actualOutputDirectory == null) { - throw new ConfigProcessorException("Output directory must be set"); - } - // calculate a relative path below the output directory based on the input file - File outputFile = new File(actualOutputDirectory, baseDir.toURI().relativize(inputFile.toURI()).getPath()); - createOutputFile(outputFile); - if (!inputFile.exists()) { - throw new ConfigProcessorException("File not found: " + inputFile); - } - InputStream inputStream = new FileInputStream(inputFile); - process(resolver, inputFile.getPath(), inputStream, outputFile, configIdentifier, action, type); - } - } else { - InputStream inputStream; - try { - inputStream = fileResolver.resolve(transformation.getInput()); - } catch (Exception e) { - throw new ConfigProcessorException("Input file [" + transformation.getInput() + "] does not exist", e); - } - // use input file as output file if output is not set - File output; - if (StringUtils.isBlank(transformation.getOutput())) { - throw new ConfigProcessorException("Output must be set"); - } else { - output = new File(actualOutputDirectory, transformation.getOutput()); - createOutputFile(output); - } - String type = getInputType(transformation); - process(resolver, transformation.getInput(), inputStream, output, configIdentifier, action, type); - } - } - - protected Action getAction(Transformation transformation) throws ConfigProcessorException, IOException { - if (transformation.getConfig() == null && transformation.getRules() == null) { - throw new ConfigProcessorException("Transformation config file or rules must be set"); - } else if (transformation.getConfig() != null && transformation.getRules() != null) { - throw new ConfigProcessorException("Cannot specify transformation config file and rules at the same time"); - } - - Action action; - Reader configReader; - if (transformation.getConfig() == null) { - StringWriter writer = new StringWriter(); - AntrunXmlPlexusConfigurationWriter xmlWriter = new AntrunXmlPlexusConfigurationWriter(); - xmlWriter.write(transformation.getRules(), writer); - String configContent = trimToNull(writer.toString()); - configContent = removeStart(configContent, ""); - configContent = removeEnd(configContent, ""); - StringBuilder sb = new StringBuilder(configContent.length() + XmlHelper.ROOT_PROCESSOR_START.length() + XmlHelper.ROOT_PROCESSOR_END.length()); - sb.append(XmlHelper.ROOT_PROCESSOR_START); - sb.append(configContent); - sb.append(XmlHelper.ROOT_PROCESSOR_END); - configReader = new StringReader(sb.toString()); - } else { - InputStream config = fileResolver.resolve(transformation.getConfig()); - - if (config == null) { - throw new ConfigProcessorException("Configuration file [" + config + "] does not exist"); - } - - configReader = new InputStreamReader(config, encoding); - } - - try { - ProcessingConfigurationParser parser = new ProcessingConfigurationParser(); - action = parser.parse(configReader); - } catch (ParsingException e) { - throw new ConfigProcessorException("Error parsing transformation config [" + getConfigIdentifier(transformation) + "]", e); - } finally { - close(configReader, getLog()); - } - action.validate(); - - return action; - } - - protected String getConfigIdentifier(Transformation transformation) throws ConfigProcessorException { - if (transformation.getConfig() == null) { - StringWriter writer = new StringWriter(); - AntrunXmlPlexusConfigurationWriter xmlWriter = new AntrunXmlPlexusConfigurationWriter(); - try { - xmlWriter.write(transformation.getRules(), writer); - } catch (IOException e) { - throw new ConfigProcessorException("Shouldn't happen because there is no I/O here", e); - } - return abbreviate(trimToNull(removeStart(writer.toString(), "")), 100); - } - return transformation.getConfig(); - } - - /** - * Scans all files below the given baseDirectory using the supplied pattern. - * All files matching the pattern are returned. - * The implementation is utilizing {@link DirectoryScanner} for pattern matching, e.g. - * it allows to use single ("*") and double wildcards ("**") for matching - * arbitrary characters or directories. - * - * Examples: - * - * - * - * - * - * - * - * - * - *
- * - *
-     * *.xml
-     * 
- * - *
matches all XML files in the base directory
- * - *
-     * **\/*.xml
-     * 
- * - *
matches all XML files in any subfolder
- * - * @param pattern the directory and file name pattern that files shall match - * @return the {@link List} of {@link File}s that match the given pattern - * @throws ConfigProcessorException - */ - protected List getMatchingFiles(String pattern) throws ConfigProcessorException { - if (pattern == null || pattern.length() == 0) { - throw new ConfigProcessorException("Invalid pattern [" + pattern + "]"); - } - DirectoryScanner scanner = new DirectoryScanner(); - scanner.setBasedir(baseDir); - scanner.setIncludes(new String[] { pattern }); - scanner.setCaseSensitive(false); - scanner.scan(); - String[] fileNames = scanner.getIncludedFiles(); - List files = new ArrayList(); - for (String fileName : fileNames) { - files.add(new File(baseDir, fileName)); - } - return files; - } - - /** - * Detects input file type. - * If {@link com.google.code.configprocessor.Transformation#getType()} is not null, - * this type is used, otherwise it is tried to guess the type from the given - * input File based on the file extension (.properties or .xml). - * If no type could be found or guessed, {@link Transformation#XML_TYPE} is used. - * - * @param transformation which can have an explicit type set - * @param input file from which the type can be guessed if transformation parameter does not - * contain a type - * @return Input file type. - */ - protected String getInputType(Transformation transformation) { - String type; - String input = transformation.getInput(); - if (transformation.getType() == null) { - if (input.endsWith(".properties")) { - type = Transformation.PROPERTIES_TYPE; - } else if (input.endsWith(".xml")) { - type = Transformation.XML_TYPE; - } else { - if (getLog() != null) { - getLog().warn( - "Could not auto-detect type of input [" + input - + "], assuming it is XML. It is recommended that you configure it in your pom.xml (tag: transformations/transformation/type) to avoid errors"); - } - type = Transformation.XML_TYPE; - } - } else { - type = transformation.getType(); - } - - return type; - } - - /** - * Processes a file. - * - * @param resolver - * @param inputName Symbolic name of the input file to read from. - * @param inputStream2 Input file to read from. - * @param output Output file to write to. - * @param configName Symbolic name of the file containing rules to process the input. - * @param action Action to be performed on the input file. - * @param type Type of the input file. Properties, XML or null if it is to be auto-detected. - * @throws ConfigProcessorException If processing cannot be performed. - */ - protected void process(ExpressionResolver resolver, String inputName, InputStream inputStream, File output, String configName, Action action, String type) throws ConfigProcessorException { - getLog().info("Processing file [" + inputName + "] using config [" + configName + "], outputing to [" + output + "]"); - - ByteArrayOutputStream outputStream = null; - - InputStreamReader inputStreamReader = null; - OutputStreamWriter outputStreamWriter = null; - try { - outputStream = new ByteArrayOutputStream(); - - inputStreamReader = new InputStreamReader(inputStream, encoding); - outputStreamWriter = new OutputStreamWriter(outputStream, encoding); - - ActionProcessor processor = getActionProcessor(resolver, type); - processor.process(inputStreamReader, outputStreamWriter, action); - } catch (ParsingException e) { - throw new ConfigProcessorException("Error processing file [" + inputName + "] using configuration [" + configName + "]", e); - } catch (IOException e) { - throw new ConfigProcessorException("Error reading/writing files. Input is [" + inputName + "], configuration is [" + configName + "]", e); - } finally { - close(inputStreamReader, getLog()); - } - FileOutputStream fileOut = null; - try { - fileOut = new FileOutputStream(output); - outputStream.writeTo(fileOut); - } catch (FileNotFoundException e) { - getLog().error("Error opening file [" + output + "]", e); - } catch (IOException e) { - getLog().error("Error writing file [" + output + "]", e); - } finally { - close(outputStreamWriter, getLog()); - close(fileOut, getLog()); - } - } - - /** - * Obtain the action processor for the input. - * - * @param expressionResolver - * @param type Type of the input file. Properties or XML. - * @return ActionProcessor for the input file. - * @throws ConfigProcessorException If processing cannot be performed. - */ - protected ActionProcessor getActionProcessor(ExpressionResolver expressionResolver, String type) throws ConfigProcessorException { - if (Transformation.XML_TYPE.equals(type)) { - return new XmlActionProcessor(encoding, lineWidth, indentSize, fileResolver, expressionResolver, namespaceContexts, parserFeatures, failOnMissingXpath); - } else if (Transformation.PROPERTIES_TYPE.equals(type)) { - return new PropertiesActionProcessor(encoding, fileResolver, expressionResolver); - } else { - throw new ConfigProcessorException("Unknown file type [" + type + "]"); - } - } - - /** - * Creates output file and required directories. - * - * @param output Output file to create. - * @throws ConfigProcessorException If processing cannot be performed. - */ - protected void createOutputFile(File output) throws ConfigProcessorException { - try { - File directory = output.getParentFile(); - getLog().debug(output.toString()); - if (!directory.exists()) { - forceMkdirs(output.getParentFile()); - } - } catch (IOException e) { - throw new ConfigProcessorException(e.getMessage(), e); - } - } - - public LogAdapter getLog() { - return log; - } + private static final String DEFAULT_ENCODING = "UTF-8"; + + private String encoding; + private int lineWidth; + private int indentSize; + private Map namespaceContexts; + private boolean useOutputDirectory; + private File baseDir; + private File outputDirectory; + private LogAdapter log; + private FileResolver fileResolver; + private List parserFeatures; + private boolean failOnMissingXpath; + + private File actualOutputDirectory; + + public ConfigProcessor(String encoding, + int indentSize, + int lineWidth, + Map namespaceContexts, + File baseDir, + File outputDirectory, + boolean useOutputDirectory, + LogAdapter log, + FileResolver fileResolver, + List parserFeatures, + boolean failOnMissingXpath) { + this.encoding = encoding; + this.indentSize = indentSize; + this.lineWidth = lineWidth; + this.namespaceContexts = namespaceContexts; + this.baseDir = baseDir; + this.outputDirectory = outputDirectory; + this.useOutputDirectory = useOutputDirectory; + this.log = log; + this.fileResolver = fileResolver; + this.parserFeatures = parserFeatures; + this.failOnMissingXpath = failOnMissingXpath; + } + + public void init() throws IOException { + if (useOutputDirectory) { + if (!outputDirectory.exists() && !outputDirectory.mkdirs()) { + throw new IOException("Could not create outputDirectory [" + outputDirectory + "]"); + } + actualOutputDirectory = outputDirectory; + } + if (encoding == null) { + getLog().warn("Encoding has not been set, using default [" + DEFAULT_ENCODING + "]."); + encoding = DEFAULT_ENCODING; + } + + getLog().debug("Using output directory [" + actualOutputDirectory + "]"); + getLog().debug("File encodig is [" + encoding + "]"); + } + + public void execute(ExpressionResolver resolver, Transformation transformation) throws ConfigProcessorException, IOException { + String input = transformation.getInput(); + Action action = getAction(transformation); + String configIdentifier = getConfigIdentifier(transformation); + + if (input != null && input.contains("*")) { + // input parameter specifies a wildcard pattern + if (!StringUtils.isBlank(transformation.getOutput())) { + throw new ConfigProcessorException("Cannot specify output file if wildcard pattern based input is given"); + } + getLog().info("Using wildcard pattern based input [" + input + "]"); + List inputFiles = getMatchingFiles(input); + for (File inputFile : inputFiles) { + String type = getInputType(transformation); + if (actualOutputDirectory == null) { + throw new ConfigProcessorException("Output directory must be set"); + } + // calculate a relative path below the output directory based on the input file + File outputFile = new File(actualOutputDirectory, baseDir.toURI().relativize(inputFile.toURI()).getPath()); + createOutputFile(outputFile); + if (!inputFile.exists()) { + throw new ConfigProcessorException("File not found: " + inputFile); + } + InputStream inputStream = new FileInputStream(inputFile); + process(resolver, inputFile.getPath(), inputStream, outputFile, configIdentifier, action, type); + } + } else { + InputStream inputStream; + try { + inputStream = fileResolver.resolve(transformation.getInput()); + } catch (Exception e) { + throw new ConfigProcessorException("Input file [" + transformation.getInput() + "] does not exist", e); + } + // use input file as output file if output is not set + File output; + if (StringUtils.isBlank(transformation.getOutput())) { + throw new ConfigProcessorException("Output must be set"); + } else { + output = new File(actualOutputDirectory, transformation.getOutput()); + createOutputFile(output); + } + String type = getInputType(transformation); + process(resolver, transformation.getInput(), inputStream, output, configIdentifier, action, type); + } + } + + protected Action getAction(Transformation transformation) throws ConfigProcessorException, IOException { + if (transformation.getConfig() == null && transformation.getRules() == null) { + throw new ConfigProcessorException("Transformation config file or rules must be set"); + } else if (transformation.getConfig() != null && transformation.getRules() != null) { + throw new ConfigProcessorException("Cannot specify transformation config file and rules at the same time"); + } + + Action action; + Reader configReader; + if (transformation.getConfig() == null) { + StringWriter writer = new StringWriter(); + AntrunXmlPlexusConfigurationWriter xmlWriter = new AntrunXmlPlexusConfigurationWriter(); + xmlWriter.write(transformation.getRules(), writer); + String configContent = trimToNull(writer.toString()); + configContent = removeStart(configContent, ""); + configContent = removeEnd(configContent, ""); + StringBuilder sb = new StringBuilder(configContent.length() + XmlHelper.ROOT_PROCESSOR_START.length() + XmlHelper.ROOT_PROCESSOR_END.length()); + sb.append(XmlHelper.ROOT_PROCESSOR_START); + sb.append(configContent); + sb.append(XmlHelper.ROOT_PROCESSOR_END); + configReader = new StringReader(sb.toString()); + } else { + InputStream config = fileResolver.resolve(transformation.getConfig()); + + if (config == null) { + throw new ConfigProcessorException("Configuration file [" + config + "] does not exist"); + } + + configReader = new InputStreamReader(config, encoding); + } + + try { + ProcessingConfigurationParser parser = new ProcessingConfigurationParser(); + action = parser.parse(configReader); + } catch (ParsingException e) { + throw new ConfigProcessorException("Error parsing transformation config [" + getConfigIdentifier(transformation) + "]", e); + } finally { + close(configReader, getLog()); + } + action.validate(); + + return action; + } + + protected String getConfigIdentifier(Transformation transformation) throws ConfigProcessorException { + if (transformation.getConfig() == null) { + StringWriter writer = new StringWriter(); + AntrunXmlPlexusConfigurationWriter xmlWriter = new AntrunXmlPlexusConfigurationWriter(); + try { + xmlWriter.write(transformation.getRules(), writer); + } catch (IOException e) { + throw new ConfigProcessorException("Shouldn't happen because there is no I/O here", e); + } + return abbreviate(trimToNull(removeStart(writer.toString(), "")), 100); + } + return transformation.getConfig(); + } + + /** + * Scans all files below the given baseDirectory using the supplied pattern. + * All files matching the pattern are returned. + * The implementation is utilizing {@link DirectoryScanner} for pattern matching, e.g. + * it allows to use single ("*") and double wildcards ("**") for matching + * arbitrary characters or directories. + * + * Examples: + * + * + * + * + * + * + * + * + * + *
+ * + *
+	 * *.xml
+	 * 
+ * + *
matches all XML files in the base directory
+ * + *
+	 * **\/*.xml
+	 * 
+ * + *
matches all XML files in any subfolder
+ * + * @param pattern the directory and file name pattern that files shall match + * @return the {@link List} of {@link File}s that match the given pattern + * @throws ConfigProcessorException + */ + protected List getMatchingFiles(String pattern) throws ConfigProcessorException { + if (pattern == null || pattern.length() == 0) { + throw new ConfigProcessorException("Invalid pattern [" + pattern + "]"); + } + DirectoryScanner scanner = new DirectoryScanner(); + scanner.setBasedir(baseDir); + scanner.setIncludes(new String[] { pattern }); + scanner.setCaseSensitive(false); + scanner.scan(); + String[] fileNames = scanner.getIncludedFiles(); + List files = new ArrayList(); + for (String fileName : fileNames) { + files.add(new File(baseDir, fileName)); + } + return files; + } + + /** + * Detects input file type. + * If {@link com.google.code.configprocessor.Transformation#getType()} is not null, + * this type is used, otherwise it is tried to guess the type from the given + * input File based on the file extension (.properties or .xml). + * If no type could be found or guessed, {@link Transformation#XML_TYPE} is used. + * + * @param transformation which can have an explicit type set + * @param input file from which the type can be guessed if transformation parameter does not + * contain a type + * @return Input file type. + */ + protected String getInputType(Transformation transformation) { + String type; + String input = transformation.getInput(); + if (transformation.getType() == null) { + if (input.endsWith(".properties")) { + type = Transformation.PROPERTIES_TYPE; + } else if (input.endsWith(".xml")) { + type = Transformation.XML_TYPE; + } else { + if (getLog() != null) { + getLog().warn( + "Could not auto-detect type of input [" + input + + "], assuming it is XML. It is recommended that you configure it in your pom.xml (tag: transformations/transformation/type) to avoid errors"); + } + type = Transformation.XML_TYPE; + } + } else { + type = transformation.getType(); + } + + return type; + } + + /** + * Processes a file. + * + * @param resolver + * @param inputName Symbolic name of the input file to read from. + * @param inputStream2 Input file to read from. + * @param output Output file to write to. + * @param configName Symbolic name of the file containing rules to process the input. + * @param action Action to be performed on the input file. + * @param type Type of the input file. Properties, XML or null if it is to be auto-detected. + * @throws ConfigProcessorException If processing cannot be performed. + */ + protected void process(ExpressionResolver resolver, String inputName, InputStream inputStream, File output, String configName, Action action, String type) throws ConfigProcessorException { + getLog().info("Processing file [" + inputName + "] using config [" + configName + "], outputing to [" + output + "]"); + + ByteArrayOutputStream outputStream = null; + + InputStreamReader inputStreamReader = null; + OutputStreamWriter outputStreamWriter = null; + try { + outputStream = new ByteArrayOutputStream(); + + inputStreamReader = new InputStreamReader(inputStream, encoding); + outputStreamWriter = new OutputStreamWriter(outputStream, encoding); + + ActionProcessor processor = getActionProcessor(resolver, type); + processor.process(inputStreamReader, outputStreamWriter, action); + } catch (ParsingException e) { + throw new ConfigProcessorException("Error processing file [" + inputName + "] using configuration [" + configName + "]", e); + } catch (IOException e) { + throw new ConfigProcessorException("Error reading/writing files. Input is [" + inputName + "], configuration is [" + configName + "]", e); + } finally { + close(inputStreamReader, getLog()); + } + FileOutputStream fileOut = null; + try { + fileOut = new FileOutputStream(output); + outputStream.writeTo(fileOut); + } catch (FileNotFoundException e) { + getLog().error("Error opening file [" + output + "]", e); + } catch (IOException e) { + getLog().error("Error writing file [" + output + "]", e); + } finally { + close(outputStreamWriter, getLog()); + close(fileOut, getLog()); + } + } + + /** + * Obtain the action processor for the input. + * + * @param expressionResolver + * @param type Type of the input file. Properties or XML. + * @return ActionProcessor for the input file. + * @throws ConfigProcessorException If processing cannot be performed. + */ + protected ActionProcessor getActionProcessor(ExpressionResolver expressionResolver, String type) throws ConfigProcessorException { + if (Transformation.XML_TYPE.equals(type)) { + return new XmlActionProcessor(encoding, lineWidth, indentSize, fileResolver, expressionResolver, namespaceContexts, parserFeatures, failOnMissingXpath); + } else if (Transformation.PROPERTIES_TYPE.equals(type)) { + return new PropertiesActionProcessor(encoding, fileResolver, expressionResolver); + } else { + throw new ConfigProcessorException("Unknown file type [" + type + "]"); + } + } + + /** + * Creates output file and required directories. + * + * @param output Output file to create. + * @throws ConfigProcessorException If processing cannot be performed. + */ + protected void createOutputFile(File output) throws ConfigProcessorException { + try { + File directory = output.getParentFile(); + getLog().debug(output.toString()); + if (!directory.exists()) { + forceMkdirs(output.getParentFile()); + } + } catch (IOException e) { + throw new ConfigProcessorException(e.getMessage(), e); + } + } + + public LogAdapter getLog() { + return log; + } } diff --git a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/ClasspathFileResolver.java b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/ClasspathFileResolver.java index 4248b3c..235a27f 100644 --- a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/ClasspathFileResolver.java +++ b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/ClasspathFileResolver.java @@ -21,12 +21,12 @@ public class ClasspathFileResolver implements FileResolver { - public InputStream resolve(String name) throws IOException { - InputStream inputStream = getClass().getResourceAsStream(name); - if (inputStream == null) { - throw new FileNotFoundException("Classpath resource [" + name + "] not found"); - } - return inputStream; - } + public InputStream resolve(String name) throws IOException { + InputStream inputStream = getClass().getResourceAsStream(name); + if (inputStream == null) { + throw new FileNotFoundException("Classpath resource [" + name + "] not found"); + } + return inputStream; + } } diff --git a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/DefaultFileResolver.java b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/DefaultFileResolver.java index 933d265..b16372a 100644 --- a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/DefaultFileResolver.java +++ b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/DefaultFileResolver.java @@ -19,18 +19,18 @@ public class DefaultFileResolver implements FileResolver { - ClasspathFileResolver classpathFileResolver = new ClasspathFileResolver(); + ClasspathFileResolver classpathFileResolver = new ClasspathFileResolver(); - public InputStream resolve(String name) throws IOException { - if (name.startsWith("classpath:")) { - String resourcePath = name.replace("classpath:", ""); - return classpathFileResolver.resolve(resourcePath); - } - File file = new File(name); - if (!file.exists()) { - throw new FileNotFoundException("File [" + name + "] does not exist"); - } - return new FileInputStream(file); - } + public InputStream resolve(String name) throws IOException { + if (name.startsWith("classpath:")) { + String resourcePath = name.replace("classpath:", ""); + return classpathFileResolver.resolve(resourcePath); + } + File file = new File(name); + if (!file.exists()) { + throw new FileNotFoundException("File [" + name + "] does not exist"); + } + return new FileInputStream(file); + } } diff --git a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/FileResolver.java b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/FileResolver.java index 60ae7d5..25f4f12 100644 --- a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/FileResolver.java +++ b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/io/FileResolver.java @@ -19,6 +19,6 @@ public interface FileResolver { - InputStream resolve(String name) throws IOException; + InputStream resolve(String name) throws IOException; } diff --git a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/maven/MavenFileResolver.java b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/maven/MavenFileResolver.java index 34848ff..58c4698 100644 --- a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/maven/MavenFileResolver.java +++ b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/maven/MavenFileResolver.java @@ -29,32 +29,32 @@ public class MavenFileResolver implements FileResolver { - private Locator locator; - private LogAdapter logAdapter; - - public MavenFileResolver(MavenProject mavenProject, ArtifactFactory artifactFactory, ArtifactResolver artifactResolver, ArtifactRepository localRepository, List remoteRepositories, LogAdapter logAdapter) { - this.logAdapter = logAdapter; - locator = new Locator(); - List strategies = new ArrayList(); - strategies.add(new RelativeFileLocatorStrategy(mavenProject)); - strategies.add(new ClasspathResourceLocatorStrategy()); - strategies.add(new ArtifactLocatorStrategy(artifactFactory, artifactResolver, localRepository, remoteRepositories)); - strategies.add(new URLLocatorStrategy()); - locator.setStrategies(strategies); - } - - public InputStream resolve(String name) throws IOException { - Location location = locator.resolve(name); - if (location == null) { - throw new IOException("File not found [" + name + "]\n" + locator.getMessageHolder().render()); - } - - InputStream inputStream = location.getInputStream(); - if (inputStream != null) { - logAdapter.debug("Resolved [" + name + "] to an inputStream [" + location + "]"); - return inputStream; - } - throw new IOException("Failed to load file [" + name + "]\n" + locator.getMessageHolder().render()); - } + private Locator locator; + private LogAdapter logAdapter; + + public MavenFileResolver(MavenProject mavenProject, ArtifactFactory artifactFactory, ArtifactResolver artifactResolver, ArtifactRepository localRepository, List remoteRepositories, LogAdapter logAdapter) { + this.logAdapter = logAdapter; + locator = new Locator(); + List strategies = new ArrayList(); + strategies.add(new RelativeFileLocatorStrategy(mavenProject)); + strategies.add(new ClasspathResourceLocatorStrategy()); + strategies.add(new ArtifactLocatorStrategy(artifactFactory, artifactResolver, localRepository, remoteRepositories)); + strategies.add(new URLLocatorStrategy()); + locator.setStrategies(strategies); + } + + public InputStream resolve(String name) throws IOException { + Location location = locator.resolve(name); + if (location == null) { + throw new IOException("File not found [" + name + "]\n" + locator.getMessageHolder().render()); + } + + InputStream inputStream = location.getInputStream(); + if (inputStream != null) { + logAdapter.debug("Resolved [" + name + "] to an inputStream [" + location + "]"); + return inputStream; + } + throw new IOException("Failed to load file [" + name + "]\n" + locator.getMessageHolder().render()); + } } diff --git a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/processing/properties/PropertiesActionProcessor.java b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/processing/properties/PropertiesActionProcessor.java index 560572c..211e951 100644 --- a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/processing/properties/PropertiesActionProcessor.java +++ b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/processing/properties/PropertiesActionProcessor.java @@ -27,187 +27,187 @@ public class PropertiesActionProcessor implements ActionProcessor { - public static final String LINE_SEPARATOR = System.getProperty("line.separator"); - private static final int READ_AHEAD_BUFFER_SIZE = 1024 * 10; - - private String encoding; - private FileResolver fileResolver; - private ExpressionResolver expressionResolver; - - private Set appendedFiles; - - public PropertiesActionProcessor(String encoding, FileResolver fileResolver, ExpressionResolver expressionResolver) { - this.encoding = encoding; - this.fileResolver = fileResolver; - this.expressionResolver = expressionResolver; - this.appendedFiles = new HashSet(); - } - - public void process(Reader input, Writer output, Action action) throws ParsingException, IOException { - BufferedReader reader = new BufferedReader(input); - BufferedWriter writer = new BufferedWriter(output); - process(reader, writer, action); - } - - protected void process(BufferedReader reader, BufferedWriter writer, Action action) throws ParsingException, IOException { - PropertiesActionProcessingAdvisor advisor = getAdvisorFor(action); - - // Start - PropertiesFileItemAdvice advice = advisor.onStartProcessing(); - processAdvice(advice, null, writer, action); - - // Process - PropertiesFileItem currentItem = null; - String line; - while ((line = reader.readLine()) != null) { - if (isBlankLine(line)) { - writer.append(LINE_SEPARATOR); - } else { - if (isComment(line)) { - currentItem = readComment(reader, line); - } else { - currentItem = readPropertyMapping(reader, line); - } - - advice = advisor.process(currentItem); - processAdvice(advice, currentItem, writer, action); - } - } - - // End - advice = advisor.onEndProcessing(); - processAdvice(advice, null, writer, action); - - writer.flush(); - } - - protected Comment readComment(BufferedReader reader, String line) throws IOException { - if (line == null) { - return new Comment(""); - } - - boolean shouldContinue = true; - StringBuilder sb = new StringBuilder(line); - - String aux = line; - while (shouldContinue && (aux != null) && aux.endsWith(PropertyMapping.PROPERTY_VALUE_LINE_SEPARATOR)) { - reader.mark(READ_AHEAD_BUFFER_SIZE); - aux = reader.readLine(); - - if (aux == null) { - shouldContinue = false; - } else { - if (isComment(aux)) { - sb.append(LINE_SEPARATOR); - sb.append(aux); - } else { - shouldContinue = false; - reader.reset(); - } - } - } - - return new Comment(sb.toString()); - } - - protected PropertyMapping readPropertyMapping(BufferedReader reader, String line) throws IOException { - StringBuilder sb = new StringBuilder(line); - String aux = line; - while (aux.endsWith(PropertyMapping.PROPERTY_VALUE_LINE_SEPARATOR)) { - aux = reader.readLine(); - if (aux == null) { - break; - } - sb.append(LINE_SEPARATOR); - sb.append(aux); - } - - PropertyMapping propertyMapping = new PropertyMapping(); - propertyMapping.parse(sb.toString(), false); - - return propertyMapping; - } - - protected void processAdvice(PropertiesFileItemAdvice advice, PropertiesFileItem currentItem, BufferedWriter writer, Action action) throws ParsingException, IOException { - switch (advice.getType()) { - case DO_NOTHING: - append(currentItem, writer); - break; - case REMOVE: - break; - case MODIFY: - append(advice.getItem(), writer); - break; - case ADD_AFTER: - append(currentItem, writer); - append(advice.getItem(), writer); - break; - case ADD_BEFORE: - append(advice.getItem(), writer); - append(currentItem, writer); - break; - case APPEND_FILE_AFTER: - append(currentItem, writer); - appendFile(advice.getItem(), writer, action); - break; - case APPEND_FILE_BEFORE: - appendFile(advice.getItem(), writer, action); - append(currentItem, writer); - break; - default: - throw new IllegalArgumentException("Unknown advice type: " + advice.getType()); - } - } - - protected void append(PropertiesFileItem item, BufferedWriter writer) throws IOException { - if (item != null) { - writer.append(item.getAsText()); - writer.append(LINE_SEPARATOR); - } - } - - protected void appendFile(PropertiesFileItem item, BufferedWriter writer, Action action) throws ParsingException, IOException { - FilePropertiesFileItem aux = (FilePropertiesFileItem)item; - InputStream inputStream = fileResolver.resolve(aux.getFile()); - if (appendedFiles.add(aux.getFile())) { // Prevent adding the same file twice - InputStreamReader reader = new InputStreamReader(inputStream, encoding); - try { - process(reader, writer, action); - } finally { - IOUtils.close(reader, null); - } - } - } - - protected PropertiesActionProcessingAdvisor getAdvisorFor(Action action) { - if (action instanceof AddAction) { - return new PropertiesAddActionProcessingAdvisor((AddAction) action, expressionResolver); - } else if (action instanceof ModifyAction) { - return new PropertiesModifyActionProcessingAdvisor((ModifyAction) action, expressionResolver); - } else if (action instanceof RemoveAction) { - return new PropertiesRemoveActionProcessingAdvisor((RemoveAction) action, expressionResolver); - } else if (action instanceof CommentAction) { - return new PropertiesCommentActionProcessingAdvisor((CommentAction) action, expressionResolver); - } else if (action instanceof UncommentAction) { - return new PropertiesUncommentActionProcessingAdvisor((UncommentAction) action, expressionResolver); - } else if (action instanceof NestedAction) { - List advisors = new ArrayList(); - NestedAction nestedAction = (NestedAction) action; - for (Action nested : nestedAction.getActions()) { - advisors.add(getAdvisorFor(nested)); - } - return new NestedPropertiesActionProcessingAdvisor(advisors); - } - throw new IllegalArgumentException("Unknown action: " + action); - } - - protected boolean isBlankLine(String line) { - return line.trim().length() == 0; - } - - protected boolean isComment(String line) { - String trimmedLine = line.trim(); - return trimmedLine.startsWith(Comment.PREFIX_1) || trimmedLine.startsWith(Comment.PREFIX_2); - } + public static final String LINE_SEPARATOR = System.getProperty("line.separator"); + private static final int READ_AHEAD_BUFFER_SIZE = 1024 * 10; + + private String encoding; + private FileResolver fileResolver; + private ExpressionResolver expressionResolver; + + private Set appendedFiles; + + public PropertiesActionProcessor(String encoding, FileResolver fileResolver, ExpressionResolver expressionResolver) { + this.encoding = encoding; + this.fileResolver = fileResolver; + this.expressionResolver = expressionResolver; + this.appendedFiles = new HashSet(); + } + + public void process(Reader input, Writer output, Action action) throws ParsingException, IOException { + BufferedReader reader = new BufferedReader(input); + BufferedWriter writer = new BufferedWriter(output); + process(reader, writer, action); + } + + protected void process(BufferedReader reader, BufferedWriter writer, Action action) throws ParsingException, IOException { + PropertiesActionProcessingAdvisor advisor = getAdvisorFor(action); + + // Start + PropertiesFileItemAdvice advice = advisor.onStartProcessing(); + processAdvice(advice, null, writer, action); + + // Process + PropertiesFileItem currentItem = null; + String line; + while ((line = reader.readLine()) != null) { + if (isBlankLine(line)) { + writer.append(LINE_SEPARATOR); + } else { + if (isComment(line)) { + currentItem = readComment(reader, line); + } else { + currentItem = readPropertyMapping(reader, line); + } + + advice = advisor.process(currentItem); + processAdvice(advice, currentItem, writer, action); + } + } + + // End + advice = advisor.onEndProcessing(); + processAdvice(advice, null, writer, action); + + writer.flush(); + } + + protected Comment readComment(BufferedReader reader, String line) throws IOException { + if (line == null) { + return new Comment(""); + } + + boolean shouldContinue = true; + StringBuilder sb = new StringBuilder(line); + + String aux = line; + while (shouldContinue && (aux != null) && aux.endsWith(PropertyMapping.PROPERTY_VALUE_LINE_SEPARATOR)) { + reader.mark(READ_AHEAD_BUFFER_SIZE); + aux = reader.readLine(); + + if (aux == null) { + shouldContinue = false; + } else { + if (isComment(aux)) { + sb.append(LINE_SEPARATOR); + sb.append(aux); + } else { + shouldContinue = false; + reader.reset(); + } + } + } + + return new Comment(sb.toString()); + } + + protected PropertyMapping readPropertyMapping(BufferedReader reader, String line) throws IOException { + StringBuilder sb = new StringBuilder(line); + String aux = line; + while (aux.endsWith(PropertyMapping.PROPERTY_VALUE_LINE_SEPARATOR)) { + aux = reader.readLine(); + if (aux == null) { + break; + } + sb.append(LINE_SEPARATOR); + sb.append(aux); + } + + PropertyMapping propertyMapping = new PropertyMapping(); + propertyMapping.parse(sb.toString(), false); + + return propertyMapping; + } + + protected void processAdvice(PropertiesFileItemAdvice advice, PropertiesFileItem currentItem, BufferedWriter writer, Action action) throws ParsingException, IOException { + switch (advice.getType()) { + case DO_NOTHING: + append(currentItem, writer); + break; + case REMOVE: + break; + case MODIFY: + append(advice.getItem(), writer); + break; + case ADD_AFTER: + append(currentItem, writer); + append(advice.getItem(), writer); + break; + case ADD_BEFORE: + append(advice.getItem(), writer); + append(currentItem, writer); + break; + case APPEND_FILE_AFTER: + append(currentItem, writer); + appendFile(advice.getItem(), writer, action); + break; + case APPEND_FILE_BEFORE: + appendFile(advice.getItem(), writer, action); + append(currentItem, writer); + break; + default: + throw new IllegalArgumentException("Unknown advice type: " + advice.getType()); + } + } + + protected void append(PropertiesFileItem item, BufferedWriter writer) throws IOException { + if (item != null) { + writer.append(item.getAsText()); + writer.append(LINE_SEPARATOR); + } + } + + protected void appendFile(PropertiesFileItem item, BufferedWriter writer, Action action) throws ParsingException, IOException { + FilePropertiesFileItem aux = (FilePropertiesFileItem)item; + InputStream inputStream = fileResolver.resolve(aux.getFile()); + if (appendedFiles.add(aux.getFile())) { // Prevent adding the same file twice + InputStreamReader reader = new InputStreamReader(inputStream, encoding); + try { + process(reader, writer, action); + } finally { + IOUtils.close(reader, null); + } + } + } + + protected PropertiesActionProcessingAdvisor getAdvisorFor(Action action) { + if (action instanceof AddAction) { + return new PropertiesAddActionProcessingAdvisor((AddAction) action, expressionResolver); + } else if (action instanceof ModifyAction) { + return new PropertiesModifyActionProcessingAdvisor((ModifyAction) action, expressionResolver); + } else if (action instanceof RemoveAction) { + return new PropertiesRemoveActionProcessingAdvisor((RemoveAction) action, expressionResolver); + } else if (action instanceof CommentAction) { + return new PropertiesCommentActionProcessingAdvisor((CommentAction) action, expressionResolver); + } else if (action instanceof UncommentAction) { + return new PropertiesUncommentActionProcessingAdvisor((UncommentAction) action, expressionResolver); + } else if (action instanceof NestedAction) { + List advisors = new ArrayList(); + NestedAction nestedAction = (NestedAction) action; + for (Action nested : nestedAction.getActions()) { + advisors.add(getAdvisorFor(nested)); + } + return new NestedPropertiesActionProcessingAdvisor(advisors); + } + throw new IllegalArgumentException("Unknown action: " + action); + } + + protected boolean isBlankLine(String line) { + return line.trim().length() == 0; + } + + protected boolean isComment(String line) { + String trimmedLine = line.trim(); + return trimmedLine.startsWith(Comment.PREFIX_1) || trimmedLine.startsWith(Comment.PREFIX_2); + } } diff --git a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/processing/xml/XmlActionProcessor.java b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/processing/xml/XmlActionProcessor.java index 3ded5f1..4c3479b 100644 --- a/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/processing/xml/XmlActionProcessor.java +++ b/maven-config-processor-plugin/src/main/java/com/google/code/configprocessor/processing/xml/XmlActionProcessor.java @@ -31,91 +31,91 @@ public class XmlActionProcessor implements ActionProcessor { - public static final String LINE_SEPARATOR = System.getProperty("line.separator"); + public static final String LINE_SEPARATOR = System.getProperty("line.separator"); - private String encoding; - private int lineWidth; - private int indentSize; - private FileResolver fileResolver; - private ExpressionResolver expressionResolver; - private MapBasedNamespaceContext namespaceContext; - private List parserFeatures; - private boolean failOnMissingXpath; + private String encoding; + private int lineWidth; + private int indentSize; + private FileResolver fileResolver; + private ExpressionResolver expressionResolver; + private MapBasedNamespaceContext namespaceContext; + private List parserFeatures; + private boolean failOnMissingXpath; - public XmlActionProcessor(String encoding, int lineWidth, int indentSize, FileResolver fileResolver, ExpressionResolver expressionResolver, Map contextMappings, - List parserFeatures, boolean failOnMissingXpath) { - this.encoding = encoding; - this.lineWidth = lineWidth; - this.indentSize = indentSize; - this.fileResolver = fileResolver; - this.expressionResolver = expressionResolver; - this.namespaceContext = new MapBasedNamespaceContext(contextMappings); - this.parserFeatures = parserFeatures; - this.failOnMissingXpath = failOnMissingXpath; - } + public XmlActionProcessor(String encoding, int lineWidth, int indentSize, FileResolver fileResolver, ExpressionResolver expressionResolver, Map contextMappings, + List parserFeatures, boolean failOnMissingXpath) { + this.encoding = encoding; + this.lineWidth = lineWidth; + this.indentSize = indentSize; + this.fileResolver = fileResolver; + this.expressionResolver = expressionResolver; + this.namespaceContext = new MapBasedNamespaceContext(contextMappings); + this.parserFeatures = parserFeatures; + this.failOnMissingXpath = failOnMissingXpath; + } - public void process(Reader input, Writer output, Action action) throws ParsingException, IOException { - try { - Document document = XmlHelper.parse(input, parserFeatures); - // While processing add-include actions that don't contain nested - // actions, - // we ended up calling getAdvisorFor with nulls, resulting in an - // exception. - if (action != null) { - XmlActionProcessingAdvisor advisor = getAdvisorFor(action, action); - advisor.process(document); - } - XmlHelper.write(output, document, encoding, lineWidth, indentSize); - } catch (SAXException e) { - throw new ParsingException(e); - } catch (ParserConfigurationException e) { - throw new ParsingException(e); - } - } + public void process(Reader input, Writer output, Action action) throws ParsingException, IOException { + try { + Document document = XmlHelper.parse(input, parserFeatures); + // While processing add-include actions that don't contain nested + // actions, + // we ended up calling getAdvisorFor with nulls, resulting in an + // exception. + if (action != null) { + XmlActionProcessingAdvisor advisor = getAdvisorFor(action, action); + advisor.process(document); + } + XmlHelper.write(output, document, encoding, lineWidth, indentSize); + } catch (SAXException e) { + throw new ParsingException(e); + } catch (ParserConfigurationException e) { + throw new ParsingException(e); + } + } - protected XmlActionProcessingAdvisor getAdvisorFor(Action rootAction, Action action) throws ParsingException, IOException { - if (action instanceof AddAction) { - // Processes the file applying all sub-transformations before - // passing it over to the advisor - AddAction addAction = (AddAction) action; - String fileName = expressionResolver.resolve(addAction.getFile(), false); - String fileContent = null; - if (fileName != null) { - fileContent = getProcessedFile(fileName, addAction.getNestedAction()); + protected XmlActionProcessingAdvisor getAdvisorFor(Action rootAction, Action action) throws ParsingException, IOException { + if (action instanceof AddAction) { + // Processes the file applying all sub-transformations before + // passing it over to the advisor + AddAction addAction = (AddAction) action; + String fileName = expressionResolver.resolve(addAction.getFile(), false); + String fileContent = null; + if (fileName != null) { + fileContent = getProcessedFile(fileName, addAction.getNestedAction()); - // Not having managed to get fileContent here is going to lead - // to a null pointer exception in - // XmlAddActionProcessingAdvisor's constructor. - // Putting in a more explicit exception message. - if (fileContent == null) { - throw new ParsingException(String.format("Processing file \"%s\" yielded null content.", addAction.getFile())); - } - } - return new XmlAddActionProcessingAdvisor((AddAction) action, fileContent, expressionResolver, namespaceContext, parserFeatures, failOnMissingXpath); - } else if (action instanceof ModifyAction) { - return new XmlModifyActionProcessingAdvisor((ModifyAction) action, expressionResolver, namespaceContext, parserFeatures, failOnMissingXpath); - } else if (action instanceof RemoveAction) { - return new XmlRemoveActionProcessingAdvisor((RemoveAction) action, expressionResolver, namespaceContext, parserFeatures, failOnMissingXpath); - } else if (action instanceof NestedAction) { - List advisors = new ArrayList(); - NestedAction nestedAction = (NestedAction) action; - for (Action nested : nestedAction.getActions()) { - advisors.add(getAdvisorFor(rootAction, nested)); - } - return new NestedXmlActionProcessingAdvisor(advisors, nestedAction); - } - throw new IllegalArgumentException("Unknown action: " + action); - } + // Not having managed to get fileContent here is going to lead + // to a null pointer exception in + // XmlAddActionProcessingAdvisor's constructor. + // Putting in a more explicit exception message. + if (fileContent == null) { + throw new ParsingException(String.format("Processing file \"%s\" yielded null content.", addAction.getFile())); + } + } + return new XmlAddActionProcessingAdvisor((AddAction) action, fileContent, expressionResolver, namespaceContext, parserFeatures, failOnMissingXpath); + } else if (action instanceof ModifyAction) { + return new XmlModifyActionProcessingAdvisor((ModifyAction) action, expressionResolver, namespaceContext, parserFeatures, failOnMissingXpath); + } else if (action instanceof RemoveAction) { + return new XmlRemoveActionProcessingAdvisor((RemoveAction) action, expressionResolver, namespaceContext, parserFeatures, failOnMissingXpath); + } else if (action instanceof NestedAction) { + List advisors = new ArrayList(); + NestedAction nestedAction = (NestedAction) action; + for (Action nested : nestedAction.getActions()) { + advisors.add(getAdvisorFor(rootAction, nested)); + } + return new NestedXmlActionProcessingAdvisor(advisors, nestedAction); + } + throw new IllegalArgumentException("Unknown action: " + action); + } - protected String getProcessedFile(String name, Action action) throws ParsingException, IOException { - InputStream inputStream = fileResolver.resolve(name); - InputStreamReader reader = new InputStreamReader(inputStream, encoding); - StringWriter writer = new StringWriter(); - try { - process(reader, writer, action); - return writer.toString(); - } finally { - IOUtils.close(reader, null); - } - } + protected String getProcessedFile(String name, Action action) throws ParsingException, IOException { + InputStream inputStream = fileResolver.resolve(name); + InputStreamReader reader = new InputStreamReader(inputStream, encoding); + StringWriter writer = new StringWriter(); + try { + process(reader, writer, action); + return writer.toString(); + } finally { + IOUtils.close(reader, null); + } + } } diff --git a/maven-config-processor-plugin/src/test/java/com/google/code/configprocessor/ConfigProcessorTest.java b/maven-config-processor-plugin/src/test/java/com/google/code/configprocessor/ConfigProcessorTest.java index 09745d6..1f36422 100644 --- a/maven-config-processor-plugin/src/test/java/com/google/code/configprocessor/ConfigProcessorTest.java +++ b/maven-config-processor-plugin/src/test/java/com/google/code/configprocessor/ConfigProcessorTest.java @@ -42,124 +42,124 @@ public class ConfigProcessorTest { - private ConfigProcessor configProcessor; - @Rule - public TemporaryFolder folder= new TemporaryFolder(); - - - @Before - public void setup() throws Exception { - configProcessor = createConfigProcessor(null, false, null); - } - - @Test(expected = ConfigProcessorException.class) - public void testNullPattern() throws Exception { - File baseDir = createStrictMock(File.class); - expect(baseDir.isDirectory()).andReturn(true); - expect(baseDir.exists()).andReturn(true); - configProcessor.getMatchingFiles(null); - } - - @Test(expected = ConfigProcessorException.class) - public void testEmptyPattern() throws Exception { - File baseDir = createStrictMock(File.class); - expect(baseDir.isDirectory()).andReturn(true); - expect(baseDir.exists()).andReturn(true); - configProcessor.getMatchingFiles(""); - } - - @Test - public void testGetTypeFromTransformation() throws Exception { - Transformation transformation = new Transformation(); - transformation.setType(Transformation.PROPERTIES_TYPE); - assertEquals(Transformation.PROPERTIES_TYPE, configProcessor.getInputType(transformation)); - } - - @Test - public void testGuessTypeFromInputFile() throws Exception { - assertEquals(Transformation.PROPERTIES_TYPE, configProcessor.getInputType(transformationWithInput("test.properties"))); - assertEquals(Transformation.XML_TYPE, configProcessor.getInputType(transformationWithInput("test.xml"))); - assertEquals(Transformation.XML_TYPE, configProcessor.getInputType(transformationWithInput("test.something"))); - } - - private Transformation transformationWithInput(String input) { - Transformation transformation = new Transformation(); - transformation.setInput(input); - return transformation; - } - - @Test - public void testTransformationFromClasspathResource() throws Exception - { - File configFile = folder.newFile(); - PrintWriter writer = new PrintWriter(new FileOutputStream(configFile)); - writer.println(""); - writer.println(""); - writer.println(""); - writer.println("property1.value"); - writer.println("NEWTESTVALUE"); - writer.println(""); - writer.println(""); - writer.close(); - File outputDirectory = null; - File output = folder.newFile(); - boolean useOutputDirectory = false; - FileResolver fileResolver = new DefaultFileResolver(); - configProcessor = createConfigProcessor(outputDirectory, useOutputDirectory, fileResolver); - configProcessor.init(); - Transformation transformation = new Transformation(); - transformation.setInput("classpath:" + PropertiesActionProcessorTest.PROPERTIES_PATH); - transformation.setOutput(output.getAbsolutePath()); - transformation.setConfig(configFile.getAbsolutePath()); - ExpressionResolver resolver = getExpressionResolver(); - configProcessor.execute(resolver, transformation); - Properties properties = new Properties(); - properties.load(new FileInputStream(output.getAbsolutePath())); - assertEquals("NEWTESTVALUE", properties.getProperty("property1.value")); - } - - protected ExpressionResolver getExpressionResolver() { - return new AbstractPropertiesActionProcessingAdvisorTest.TestExpressionResolver(); - } - - private ConfigProcessor createConfigProcessor(File outputDirectory, - boolean useOutputDirectory, - FileResolver fileResolver) - { - Map namespaceContexts = null; - File baseDir = null; - LogAdapter log = new TestLogAdapter(); - List parserFeatures = null; - boolean failOnMissingXPath = true; - int indentSize = 4; - int lineWidth = 80; - return new ConfigProcessor("UTF-8", indentSize, lineWidth, namespaceContexts, baseDir, - outputDirectory, useOutputDirectory, log, fileResolver, parserFeatures, - failOnMissingXPath); - } - - public static class TestLogAdapter implements LogAdapter { - - public void info(String msg) { - System.out.println(msg); - } - - public void debug(String msg) { - System.out.println(msg); - } - - public void warn(String msg) { - System.out.println(msg); - } - - public void error(String msg, Throwable t) { - System.out.println(msg); - t.printStackTrace(System.out); - } - - public void verbose(String msg) { - System.out.println(msg); - } - - } + private ConfigProcessor configProcessor; + @Rule + public TemporaryFolder folder= new TemporaryFolder(); + + + @Before + public void setup() throws Exception { + configProcessor = createConfigProcessor(null, false, null); + } + + @Test(expected = ConfigProcessorException.class) + public void testNullPattern() throws Exception { + File baseDir = createStrictMock(File.class); + expect(baseDir.isDirectory()).andReturn(true); + expect(baseDir.exists()).andReturn(true); + configProcessor.getMatchingFiles(null); + } + + @Test(expected = ConfigProcessorException.class) + public void testEmptyPattern() throws Exception { + File baseDir = createStrictMock(File.class); + expect(baseDir.isDirectory()).andReturn(true); + expect(baseDir.exists()).andReturn(true); + configProcessor.getMatchingFiles(""); + } + + @Test + public void testGetTypeFromTransformation() throws Exception { + Transformation transformation = new Transformation(); + transformation.setType(Transformation.PROPERTIES_TYPE); + assertEquals(Transformation.PROPERTIES_TYPE, configProcessor.getInputType(transformation)); + } + + @Test + public void testGuessTypeFromInputFile() throws Exception { + assertEquals(Transformation.PROPERTIES_TYPE, configProcessor.getInputType(transformationWithInput("test.properties"))); + assertEquals(Transformation.XML_TYPE, configProcessor.getInputType(transformationWithInput("test.xml"))); + assertEquals(Transformation.XML_TYPE, configProcessor.getInputType(transformationWithInput("test.something"))); + } + + private Transformation transformationWithInput(String input) { + Transformation transformation = new Transformation(); + transformation.setInput(input); + return transformation; + } + + @Test + public void testTransformationFromClasspathResource() throws Exception + { + File configFile = folder.newFile(); + PrintWriter writer = new PrintWriter(new FileOutputStream(configFile)); + writer.println(""); + writer.println(""); + writer.println(""); + writer.println("property1.value"); + writer.println("NEWTESTVALUE"); + writer.println(""); + writer.println(""); + writer.close(); + File outputDirectory = null; + File output = folder.newFile(); + boolean useOutputDirectory = false; + FileResolver fileResolver = new DefaultFileResolver(); + configProcessor = createConfigProcessor(outputDirectory, useOutputDirectory, fileResolver); + configProcessor.init(); + Transformation transformation = new Transformation(); + transformation.setInput("classpath:" + PropertiesActionProcessorTest.PROPERTIES_PATH); + transformation.setOutput(output.getAbsolutePath()); + transformation.setConfig(configFile.getAbsolutePath()); + ExpressionResolver resolver = getExpressionResolver(); + configProcessor.execute(resolver, transformation); + Properties properties = new Properties(); + properties.load(new FileInputStream(output.getAbsolutePath())); + assertEquals("NEWTESTVALUE", properties.getProperty("property1.value")); + } + + protected ExpressionResolver getExpressionResolver() { + return new AbstractPropertiesActionProcessingAdvisorTest.TestExpressionResolver(); + } + + private ConfigProcessor createConfigProcessor(File outputDirectory, + boolean useOutputDirectory, + FileResolver fileResolver) + { + Map namespaceContexts = null; + File baseDir = null; + LogAdapter log = new TestLogAdapter(); + List parserFeatures = null; + boolean failOnMissingXPath = true; + int indentSize = 4; + int lineWidth = 80; + return new ConfigProcessor("UTF-8", indentSize, lineWidth, namespaceContexts, baseDir, + outputDirectory, useOutputDirectory, log, fileResolver, parserFeatures, + failOnMissingXPath); + } + + public static class TestLogAdapter implements LogAdapter { + + public void info(String msg) { + System.out.println(msg); + } + + public void debug(String msg) { + System.out.println(msg); + } + + public void warn(String msg) { + System.out.println(msg); + } + + public void error(String msg, Throwable t) { + System.out.println(msg); + t.printStackTrace(System.out); + } + + public void verbose(String msg) { + System.out.println(msg); + } + + } } diff --git a/maven-config-processor-plugin/src/test/java/com/google/code/configprocessor/processing/properties/AbstractPropertiesActionProcessingAdvisorTest.java b/maven-config-processor-plugin/src/test/java/com/google/code/configprocessor/processing/properties/AbstractPropertiesActionProcessingAdvisorTest.java index 4ca2e39..c248334 100644 --- a/maven-config-processor-plugin/src/test/java/com/google/code/configprocessor/processing/properties/AbstractPropertiesActionProcessingAdvisorTest.java +++ b/maven-config-processor-plugin/src/test/java/com/google/code/configprocessor/processing/properties/AbstractPropertiesActionProcessingAdvisorTest.java @@ -32,53 +32,53 @@ public class AbstractPropertiesActionProcessingAdvisorTest { - private static final String ENCODING = "ISO-8859-1"; + private static final String ENCODING = "ISO-8859-1"; - protected InputStream input; - protected ByteArrayOutputStream output; - protected ActionProcessor processor; + protected InputStream input; + protected ByteArrayOutputStream output; + protected ActionProcessor processor; - public void setup() { - processor = new PropertiesActionProcessor(ENCODING, new ClasspathFileResolver(), new MavenExpressionResolver(new DefaultExpressionEvaluator())); - input = getClass().getResourceAsStream(PropertiesActionProcessorTest.PROPERTIES_PATH); - output = new ByteArrayOutputStream(); - } + public void setup() { + processor = new PropertiesActionProcessor(ENCODING, new ClasspathFileResolver(), new MavenExpressionResolver(new DefaultExpressionEvaluator())); + input = getClass().getResourceAsStream(PropertiesActionProcessorTest.PROPERTIES_PATH); + output = new ByteArrayOutputStream(); + } - @Test - public void testCreatePropertyMapping() throws Exception { - TestExpressionResolver resolver = new TestExpressionResolver(); - PropertiesAddActionProcessingAdvisor advisor = new PropertiesAddActionProcessingAdvisor(new AddAction(), resolver); - advisor.createPropertyMapping("name", "value"); - assertEquals(2, resolver.getResolvedValues().size()); - assertEquals(Arrays.asList("name", "value"), resolver.getResolvedValues()); - } + @Test + public void testCreatePropertyMapping() throws Exception { + TestExpressionResolver resolver = new TestExpressionResolver(); + PropertiesAddActionProcessingAdvisor advisor = new PropertiesAddActionProcessingAdvisor(new AddAction(), resolver); + advisor.createPropertyMapping("name", "value"); + assertEquals(2, resolver.getResolvedValues().size()); + assertEquals(Arrays.asList("name", "value"), resolver.getResolvedValues()); + } - protected void executeTest(Action action, String expected) throws Exception { - setup(); - processor.process(new InputStreamReader(input), new OutputStreamWriter(output), action); - assertEquals(expected, getOutput()); + protected void executeTest(Action action, String expected) throws Exception { + setup(); + processor.process(new InputStreamReader(input), new OutputStreamWriter(output), action); + assertEquals(expected, getOutput()); - setup(); - NestedAction nestedAction = new NestedAction(); - nestedAction.addAction(action); - processor.process(new InputStreamReader(input), new OutputStreamWriter(output), nestedAction); - assertEquals(expected, getOutput()); - } + setup(); + NestedAction nestedAction = new NestedAction(); + nestedAction.addAction(action); + processor.process(new InputStreamReader(input), new OutputStreamWriter(output), nestedAction); + assertEquals(expected, getOutput()); + } - protected String getOutput() { - return new String(output.toByteArray()); - } + protected String getOutput() { + return new String(output.toByteArray()); + } - public static class TestExpressionResolver implements ExpressionResolver { - private List resolvedValues = new ArrayList(); + public static class TestExpressionResolver implements ExpressionResolver { + private List resolvedValues = new ArrayList(); - public String resolve(String value, boolean isPropertiesValue) { - resolvedValues.add(value); - return value; - } + public String resolve(String value, boolean isPropertiesValue) { + resolvedValues.add(value); + return value; + } - public List getResolvedValues() { - return resolvedValues; - } - } + public List getResolvedValues() { + return resolvedValues; + } + } }