Skip to content

Commit

Permalink
improve prescan for schemaVersion attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
sboeckelmann committed Oct 31, 2023
1 parent 0942263 commit 1fed64c
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 31 deletions.
36 changes: 36 additions & 0 deletions src/main/java/io/openepcis/convert/AttributePreScanUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.openepcis.convert;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class AttributePreScanUtil {

private static final String SCHEMA_VERSION_REGEX ="schemaVersion\"?'?\\s*[=:]\\s*([\"'])?([^\"']*)";
private static final Pattern SCHEMA_VERSION_PATTERN = Pattern.compile(SCHEMA_VERSION_REGEX);
private static final int READ_LIMIT = 4096;
public static final String scanSchemaVersion(final BufferedInputStream input) throws IOException {
input.mark(READ_LIMIT);
try {
final StringBuilder sb = new StringBuilder();
final byte[] buffer = new byte[64];
int len = -1;
int bytesReceived = 0;
Matcher matcher = SCHEMA_VERSION_PATTERN.matcher(sb.toString());
while (!matcher.find(0) && bytesReceived < READ_LIMIT && (len = input.read(buffer)) != -1) {
sb.append(new String(buffer, 0, len, StandardCharsets.UTF_8));
bytesReceived += len;
matcher = SCHEMA_VERSION_PATTERN.matcher(sb.toString());
}
if (matcher.find(0)) {
return matcher.group(2);
}
return "";
} finally {
input.reset();
}
}

}
35 changes: 4 additions & 31 deletions src/main/java/io/openepcis/convert/VersionTransformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,11 @@
import io.openepcis.convert.xml.XmlToJsonConverter;
import io.openepcis.convert.xml.XmlVersionTransformer;
import io.openepcis.model.rest.ProblemResponseBody;
import io.openepcis.validation.xml.PreScanUtil;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
Expand Down Expand Up @@ -181,40 +179,15 @@ public final EPCISVersion versionDetector(final BufferedInputStream epcisDocumen
return conversion.fromVersion();
}

// TODO: optimize prescan with regex matcher
String preScanVersion = null;
if (EPCISFormat.XML.equals(conversion.fromMediaType())) {
preScanVersion = PreScanUtil.scanFirstTag(epcisDocument);
} else {
epcisDocument.mark(1024);
// pre scan 1024 bytes to detect version
final byte[] preScan = new byte[1024];
epcisDocument.read(preScan, 0, preScan.length);
epcisDocument.reset();
preScanVersion = new String(preScan, StandardCharsets.UTF_8);
}
final String preScanVersion = AttributePreScanUtil.scanSchemaVersion(epcisDocument);

if (!preScanVersion.contains(EPCIS.SCHEMA_VERSION)) {
if (preScanVersion.isEmpty()) {
throw new FormatConverterException(
"Unable to detect EPCIS schemaVersion for given document, please check the document again");
}

EPCISVersion fromVersion;

if (preScanVersion.contains(EPCIS.SCHEMA_VERSION + "=\"1.2\"")
|| preScanVersion.contains(EPCIS.SCHEMA_VERSION + "='1.2'")
|| preScanVersion.replace(" ", "").contains("\"" + EPCIS.SCHEMA_VERSION + "\":\"1.2\"")) {
fromVersion = EPCISVersion.VERSION_1_2_0;
} else if (preScanVersion.contains(EPCIS.SCHEMA_VERSION + "=\"2.0\"")
|| preScanVersion.contains(EPCIS.SCHEMA_VERSION + "='2.0'")
|| preScanVersion.replace(" ", "").contains("\"" + EPCIS.SCHEMA_VERSION + "\":\"2.0\"")) {
fromVersion = EPCISVersion.VERSION_2_0_0;
} else {
throw new FormatConverterException(
"Provided document contains unsupported EPCIS document version");
}

return fromVersion;
return EPCISVersion.fromString(preScanVersion).orElseThrow(() -> new FormatConverterException(
String.format("Provided document contains unsupported EPCIS document version %s", preScanVersion)));
}

/**
Expand Down

0 comments on commit 1fed64c

Please sign in to comment.