Skip to content

Commit

Permalink
Merge pull request #17 from MikeEdgar/16_disable_control_codes_property
Browse files Browse the repository at this point in the history
Add EDIInputFactory property to disable control schema code values
  • Loading branch information
MikeEdgar committed May 6, 2020
2 parents 40ff6fc + abce0df commit d66aec5
Show file tree
Hide file tree
Showing 14 changed files with 160 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public String getId() {

@Override
public EDIType getReferencedType() {
return standard;
return getStandard();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class StaEDIInputFactory extends EDIInputFactory {

public StaEDIInputFactory() {
supportedProperties.add(EDI_VALIDATE_CONTROL_STRUCTURE);
supportedProperties.add(EDI_VALIDATE_CONTROL_CODE_VALUES);

supportedCharsets = new HashSet<>();
supportedCharsets.add(DEFAULT_ENCODING);
Expand Down
14 changes: 11 additions & 3 deletions src/main/java/io/xlate/edi/internal/stream/StaEDIStreamReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ public void setControlSchema(Schema schema) {
}

this.controlSchema = schema;
proxy.setControlSchema(schema);
proxy.setControlSchema(schema, validateControlCodeValues());
}

@Override
Expand Down Expand Up @@ -423,15 +423,23 @@ public InputStream getBinaryData() {

/**************************************************************************/

boolean validateControlCodeValues() {
return getBooleanProperty(EDIInputFactory.EDI_VALIDATE_CONTROL_CODE_VALUES, true);
}

boolean useInternalControlSchema() {
if (this.controlSchema != null) {
return false;
}

Object property = properties.get(EDIInputFactory.EDI_VALIDATE_CONTROL_STRUCTURE);
return getBooleanProperty(EDIInputFactory.EDI_VALIDATE_CONTROL_STRUCTURE, true);
}

boolean getBooleanProperty(String propertyName, boolean defaultValue) {
Object property = properties.get(propertyName);

if (property == null) {
return true;
return defaultValue;
}

return Boolean.parseBoolean(property.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,12 @@ public void flush() throws EDIStreamException {
public void setControlSchema(Schema controlSchema) {
ensureLevel(LEVEL_INITIAL);
this.controlSchema = controlSchema;
controlValidator = controlSchema != null ? new Validator(controlSchema, null) : null;
controlValidator = controlSchema != null ? new Validator(controlSchema, true, null) : null;
}

@Override
public void setTransactionSchema(Schema transactionSchema) {
transactionValidator = transactionSchema != null ? new Validator(transactionSchema, controlSchema) : null;
transactionValidator = transactionSchema != null ? new Validator(transactionSchema, true, controlSchema) : null;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,14 +292,9 @@ public String getElementText() throws XMLStreamException {
throw streamException("Element text only available on START_ELEMENT");
}

int eventType = next();

if (eventType != CHARACTERS) {
throw streamException("Unexpected event type: " + eventType);
}

next(); // Advance to the text/CDATA
final String text = getText();
eventType = next();
int eventType = next();

if (eventType != END_ELEMENT) {
throw streamException("Unexpected event type after text " + eventType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,27 +53,27 @@ public class ProxyEventHandler implements EventHandler {

public ProxyEventHandler(StaEDIStreamLocation location, Schema controlSchema) {
this.location = location;
setControlSchema(controlSchema);
setControlSchema(controlSchema, true);
for (int i = 0; i < 99; i++) {
events[i] = new StreamEvent();
}
}

public void setControlSchema(Schema controlSchema) {
public void setControlSchema(Schema controlSchema, boolean validateCodeValues) {
if (controlValidator != null) {
throw new IllegalStateException("control validator already created");
}

this.controlSchema = controlSchema;
controlValidator = controlSchema != null ? new Validator(controlSchema, null) : null;
controlValidator = controlSchema != null ? new Validator(controlSchema, validateCodeValues, null) : null;
}

public boolean isTransactionSchemaAllowed() {
return transactionSchemaAllowed;
}

public void setTransactionSchema(Schema transactionSchema) {
transactionValidator = transactionSchema != null ? new Validator(transactionSchema, controlSchema) : null;
transactionValidator = transactionSchema != null ? new Validator(transactionSchema, true, controlSchema) : null;
}

public void resetEvents() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public class UsageError {
this.error = error;
}

boolean isDepthGreaterThan(int depth) {
return this.depth > depth;
}

void handle(BiConsumer<String, EDIStreamValidationError> handler) {
handler.accept(code, error);
}
Expand All @@ -41,8 +45,4 @@ public String getCode() {
public EDIStreamValidationError getError() {
return error;
}

public int getDepth() {
return depth;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import io.xlate.edi.internal.stream.tokenization.Dialect;
import io.xlate.edi.schema.EDIComplexType;
Expand Down Expand Up @@ -137,7 +138,7 @@ String getCode() {
return referencedNode.getId();
}

void validate(Dialect dialect, CharSequence value, List<EDIStreamValidationError> errors) {
void validate(Dialect dialect, CharSequence value, boolean validateCodeValues, List<EDIStreamValidationError> errors) {
if (validator == null) {
throw new UnsupportedOperationException("simple type only");
}
Expand All @@ -150,7 +151,11 @@ void validate(Dialect dialect, CharSequence value, List<EDIStreamValidationError
element = (EDISimpleType) link.getReferencedType();
}

validator.validate(dialect, element, value, errors);
if (validateCodeValues) {
validator.validate(dialect, element, value, errors);
} else {
validator.validate(dialect, UnenumeratedElement.from(element), value, errors);
}
}

List<EDISyntaxRule> getSyntaxRules() {
Expand Down Expand Up @@ -236,4 +241,46 @@ UsageNode getChildById(CharSequence id) {
UsageNode getSiblingById(CharSequence id) {
return parent != null ? parent.getChildById(id) : null;
}

private static class UnenumeratedElement implements EDISimpleType {
final EDISimpleType target;

static EDISimpleType from(EDISimpleType target) {
return new UnenumeratedElement(target);
}

private UnenumeratedElement(EDISimpleType target) {
this.target = target;
}

@Override
public String getId() {
return target.getId();
}

@Override
public Base getBase() {
return target.getBase();
}

@Override
public int getNumber() {
return target.getNumber();
}

@Override
public long getMinLength() {
return target.getMinLength();
}

@Override
public long getMaxLength() {
return target.getMaxLength();
}

@Override
public Set<String> getValueSet() {
return Collections.emptySet();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class Validator {

private Schema containerSchema;
private Schema schema;
private final boolean validateCodeValues;

private final UsageNode root;
private final UsageNode implRoot;
Expand Down Expand Up @@ -96,8 +97,9 @@ void reset(UsageNode root, UsageNode implRoot) {
}
}

public Validator(Schema schema, Schema containerSchema) {
public Validator(Schema schema, boolean validateCodeValues, Schema containerSchema) {
this.schema = schema;
this.validateCodeValues = validateCodeValues;
this.containerSchema = containerSchema;

root = buildTree(schema.getStandard());
Expand Down Expand Up @@ -562,7 +564,7 @@ private void handleMissingMandatory(ValidationEventHandler handler, int depth) {

while (errors.hasNext()) {
UsageError e = errors.next();
if (e.depth > depth) {
if (e.isDepthGreaterThan(depth)) {
e.handle(handler::segmentError);
errors.remove();
}
Expand Down Expand Up @@ -868,14 +870,14 @@ void validateElementValue(Dialect dialect, CharSequence value) {
}

List<EDIStreamValidationError> errors = new ArrayList<>();
this.element.validate(dialect, value, errors);
this.element.validate(dialect, value, this.validateCodeValues, errors);

for (EDIStreamValidationError error : errors) {
elementErrors.add(new UsageError(this.element, error));
}

if (errors.isEmpty() && implSegmentSelected && implElement != null) {
this.implElement.validate(dialect, value, errors);
this.implElement.validate(dialect, value, this.validateCodeValues, errors);

for (EDIStreamValidationError error : errors) {
if (error == INVALID_CODE_VALUE) {
Expand Down
1 change: 1 addition & 0 deletions src/main/java/io/xlate/edi/stream/EDIInputFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
public abstract class EDIInputFactory extends PropertySupport {

public static final String EDI_VALIDATE_CONTROL_STRUCTURE = "io.xlate.edi.stream.EDI_VALIDATE_CONTROL_STRUCTURE";
public static final String EDI_VALIDATE_CONTROL_CODE_VALUES = "io.xlate.edi.stream.EDI_VALIDATE_CONTROL_CODE_VALUES";

/**
* Create a new instance of the factory. This static method creates a new
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -944,9 +944,11 @@ public void testGetBinaryDataValid()
public void testEmptySegmentValidation() throws Exception {

EDIInputFactory factory = EDIInputFactory.newFactory();
factory.setProperty(EDIInputFactory.EDI_VALIDATE_CONTROL_STRUCTURE, true);
factory.setProperty(EDIInputFactory.EDI_VALIDATE_CONTROL_CODE_VALUES, false);

Schema transSchema = SchemaFactory.newFactory()
.createSchema(getClass().getResourceAsStream("/EDIFACT/empty-segment-schema.xml"));
factory.setProperty(EDIInputFactory.EDI_VALIDATE_CONTROL_STRUCTURE, true);

EDIStreamReader reader = factory.createEDIStreamReader(getClass().getResourceAsStream("/EDIFACT/empty-segment-example.edi"));
String segmentName = null;
Expand Down Expand Up @@ -979,24 +981,10 @@ public void testEmptySegmentValidation() throws Exception {
break;
}
case ELEMENT_DATA_ERROR:
// TODO Change "control schema", because it does not recognise "IATA" (UNB), "PNRGOV:11" (UNH)
if ("DE0001".equals(reader.getReferenceCode()) && "IATA".equals(reader.getText())) {
break;
}
if ("DE0065".equals(reader.getReferenceCode()) && "PNRGOV".equals(reader.getText())) {
break;
}
if ("DE0052".equals(reader.getReferenceCode())) {
break;
}

break;

case ELEMENT_OCCURRENCE_ERROR: {
Location loc = reader.getLocation();
EDIStreamValidationError error = reader.getErrorType();

// FIXME when the empty segment is reached, TOO_MANY_DATA_ELEMENTS is returned
fail(String.format("%s: %s (seg=%s, elemPos=%d, compoPos=%d, textOnError=%s)",
error.getCategory(),
error,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,16 @@ public int read() throws IOException {
writer.writeBinaryData(reader.getBinaryData());
writer.endElement();
break;
case START_TRANSACTION:
case START_GROUP:
case START_LOOP:
case END_LOOP:
case END_GROUP:
case END_TRANSACTION:
// Ignored
break;
default:
fail("Unexpected event type: " + event);
break;
}
}
Expand Down Expand Up @@ -620,7 +629,16 @@ public int read() throws IOException {
writer.writeBinaryData(reader.getBinaryData());
writer.endElement();
break;
case START_TRANSACTION:
case START_GROUP:
case START_LOOP:
case END_LOOP:
case END_GROUP:
case END_TRANSACTION:
// Ignored
break;
default:
fail("Unexpected event type: " + event);
break;
}
}
Expand All @@ -634,6 +652,7 @@ public int read() throws IOException {
@Test
public void testInputEquivalenceEDIFACT_IATA_PNRGOV() throws Exception {
EDIInputFactory inputFactory = EDIInputFactory.newFactory();
inputFactory.setProperty(EDIInputFactory.EDI_VALIDATE_CONTROL_CODE_VALUES, false);
final ByteArrayOutputStream expected = new ByteArrayOutputStream(16384);

InputStream source = new InputStream() {
Expand Down Expand Up @@ -721,7 +740,16 @@ public int read() throws IOException {
writer.writeBinaryData(reader.getBinaryData());
writer.endElement();
break;
case START_TRANSACTION:
case START_GROUP:
case START_LOOP:
case END_LOOP:
case END_GROUP:
case END_TRANSACTION:
// Ignored
break;
default:
fail("Unexpected event type: " + event);
break;
}
}
Expand Down Expand Up @@ -814,7 +842,16 @@ public int read() throws IOException {
writer.writeBinaryData(reader.getBinaryData());
writer.endElement();
break;
case START_TRANSACTION:
case START_GROUP:
case START_LOOP:
case END_LOOP:
case END_GROUP:
case END_TRANSACTION:
// Ignored
break;
default:
fail("Unexpected event type: " + event);
break;
}
}
Expand Down
Loading

0 comments on commit d66aec5

Please sign in to comment.