Skip to content

Commit

Permalink
fix(plc4j/codgen): fix edge case with broken patterns.
Browse files Browse the repository at this point in the history
  • Loading branch information
sruehl committed Oct 25, 2021
1 parent ad43682 commit 9d2956d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
package org.apache.plc4x.test.migration;

import java.util.Map;

import org.apache.commons.lang3.RegExUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.plc4x.java.spi.generation.*;
import org.apache.plc4x.test.driver.exceptions.DriverTestsuiteException;
Expand All @@ -44,7 +46,7 @@ public class MessageValidatorAndMigrator {

/**
* Validates a outbound message and migrates it to the expectation if the parameter {@code autoMigrate} is set to true.
*
* <p>
* Passed options should contain a single 'package' option or 'protocolName' and 'outputFlavor'.
* In case if package is not specified then protocol name and output flavor (e.g read-write) are
* used to construct lookup package.
Expand All @@ -59,7 +61,7 @@ public class MessageValidatorAndMigrator {
* @param siteURI the file which we want to auto migrate
* @throws DriverTestsuiteException if something goes wrong
*/
@SuppressWarnings({"rawtypes", "unchecked"})
@SuppressWarnings({"rawtypes"})
public static void validateOutboundMessageAndMigrate(String testCaseName, Map<String, String> options, Element referenceXml, List<String> parserArguments, byte[] data, ByteOrder byteOrder, boolean autoMigrate, URI siteURI) throws DriverTestsuiteException {
MessageIO messageIO = MessageResolver.getMessageIO(options, referenceXml.getName());
validateOutboundMessageAndMigrate(testCaseName, messageIO, referenceXml, parserArguments, data, byteOrder, autoMigrate, siteURI);
Expand Down Expand Up @@ -140,10 +142,9 @@ public static void validateOutboundMessageAndMigrate(String testCaseName, Messag
throw new RuntimeException(ioException);
}
String indent = TestCasePatcher.determineIndent(content, referenceXmlString);
String searchString = TestCasePatcher.indent(referenceXmlString, indent);
String newXml = ((MigrationException) e).newXml;
newXml = TestCasePatcher.indent(newXml, indent);
content = StringUtils.replaceOnce(content, searchString, newXml);
content = RegExUtils.replaceFirst(content, TestCasePatcher.getPatternForFragment(referenceXmlString), newXml);
try {
Files.write(path, content.getBytes(charset));
} catch (IOException ioException) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,29 @@
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
* Small util to help with patching of testcases
*/
public class TestCasePatcher {

/**
* Indents a xml fragment with the supplied indent (every line gets ident prefixed).
*
* @param xmlDocument the document to be patched.
* @param indent the indent to be applied
* @return the indented document
*/
public static String indent(String xmlDocument, String indent) {
return Arrays.stream(xmlDocument.split("\n")).map(s -> indent + s).collect(Collectors.joining("\n"));
}

/**
* Tries to find the base indent for supplied fragment
*
* @param xmlDocument where to look for the fragment
* @param xmlFragment the fragment to look up
* @return the found indent
*/
public static String determineIndent(String xmlDocument, String xmlFragment) {
assert xmlDocument != null;
assert xmlFragment != null;
Expand All @@ -43,18 +60,24 @@ public static String determineIndent(String xmlDocument, String xmlFragment) {
return matcher.group(1);
}

private static Pattern getPatternForFragment(String xmlFragment) {
/**
* Returns a pattern for a xmlFragment which ignores leading indents
*
* @param xmlFragment the fragment where the pattern should be build for
* @return the created pattern
*/
public static Pattern getPatternForFragment(String xmlFragment) {
StringBuilder patternString = new StringBuilder();
String[] lines = xmlFragment.split("(\r)?\n");
String[] lines = xmlFragment.split("\n");
for (int i = 0; i < lines.length; i++) {
String line = lines[i];
line = StringUtils.replace(line, "\"", "\\\"");
line = StringUtils.replace(line, ".", "\\.");
if (i == 0) {
patternString.append("([ ]*)").append(line).append("(\\r)?\\n");
patternString.append("([ ]*)").append(line).append("\\n");
continue;
}
patternString.append("[ ]*").append(line).append("(\\r)?\\n");
patternString.append("[ ]*").append(line).append("\\n");
}
return Pattern.compile(patternString.toString());
}
Expand Down

0 comments on commit 9d2956d

Please sign in to comment.