Skip to content

Commit

Permalink
Support dynamic decimal mark (EDIFACT only)
Browse files Browse the repository at this point in the history
Pass dialect to event handler and element validation
Update delimiter tests
SchemaFactory to interface
Fix handling of invalid binary length
  • Loading branch information
MikeEdgar committed Oct 22, 2019
1 parent 1305f90 commit 1d41ee8
Show file tree
Hide file tree
Showing 28 changed files with 293 additions and 139 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
import io.xlate.edi.schema.Schema;
import io.xlate.edi.schema.SchemaFactory;

public class StaEDISchemaFactory extends SchemaFactory {
public class StaEDISchemaFactory implements SchemaFactory {

private static XMLInputFactory factory = XMLInputFactory.newFactory();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public StaEDIOutputFactory() {
supportedProperties.add(EDIStreamConstants.Delimiters.DATA_ELEMENT);
supportedProperties.add(EDIStreamConstants.Delimiters.COMPONENT_ELEMENT);
supportedProperties.add(EDIStreamConstants.Delimiters.REPETITION);
supportedProperties.add(EDIStreamConstants.Delimiters.DECIMAL);
supportedProperties.add(EDIStreamConstants.Delimiters.RELEASE);

supportedProperties.add(PRETTY_PRINT);
Expand Down
28 changes: 14 additions & 14 deletions src/main/java/io/xlate/edi/internal/stream/StaEDIStreamReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ public Map<String, Character> getDelimiters() {
delimiters.put(Delimiters.SEGMENT, dialect.getSegmentTerminator());
delimiters.put(Delimiters.DATA_ELEMENT, dialect.getDataElementSeparator());
delimiters.put(Delimiters.COMPONENT_ELEMENT, dialect.getComponentElementSeparator());
delimiters.put(Delimiters.DECIMAL, dialect.getDecimalMark());

if (dialect.getRepetitionSeparator() != '\0') {
delimiters.put(Delimiters.REPETITION, dialect.getRepetitionSeparator());
Expand Down Expand Up @@ -140,16 +141,15 @@ public EDIStreamEvent next() throws EDIStreamException {
}
}

if (proxy.nextEvent()) {
return proxy.getEvent();
}
proxy.resetEvents();
if (!proxy.nextEvent()) {
proxy.resetEvents();

try {
lexer.parse();
} catch (IOException e) {
Location where = getLocation();
throw new EDIStreamException("Error parsing input", where, e);
try {
lexer.parse();
} catch (IOException e) {
Location where = getLocation();
throw new EDIStreamException("Error parsing input", where, e);
}
}

final EDIStreamEvent event = proxy.getEvent();
Expand All @@ -159,11 +159,11 @@ public EDIStreamEvent next() throws EDIStreamException {
}

if (event == EDIStreamEvent.ELEMENT_DATA && proxy.isBinaryElementLength()) {
try {
this.setBinaryDataLength(Long.parseLong(getText()));
} catch (NumberFormatException e) {
// TODO: log it
}
try {
this.setBinaryDataLength(Long.parseLong(getText()));
} catch (NumberFormatException e) {
throw new EDIStreamException("Failed to parse binary element length", location, e);
}
}

return event;
Expand Down
14 changes: 11 additions & 3 deletions src/main/java/io/xlate/edi/internal/stream/StaEDIStreamWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import io.xlate.edi.internal.stream.tokenization.State;
import io.xlate.edi.stream.EDIStreamException;
import io.xlate.edi.stream.EDIStreamWriter;
import io.xlate.edi.stream.EDIOutputFactory;
import io.xlate.edi.stream.EDIStreamConstants.Delimiters;

import java.io.IOException;
Expand Down Expand Up @@ -56,8 +57,9 @@ public class StaEDIStreamWriter implements EDIStreamWriter {
private char segmentTerminator;
private char dataElementSeparator;
private char componentElementSeparator;
private char releaseIndicator;
private char repetitionSeparator;
private char decimalMark;
private char releaseIndicator;

private final boolean prettyPrint;
private final String lineSeparator;
Expand All @@ -66,7 +68,7 @@ public StaEDIStreamWriter(OutputStream stream, String encoding, Map<String, Obje
this.stream = stream;
this.encoding = encoding;
this.properties = new HashMap<>(properties);
this.prettyPrint = property(StaEDIOutputFactory.PRETTY_PRINT);
this.prettyPrint = property(EDIOutputFactory.PRETTY_PRINT);

if (prettyPrint) {
lineSeparator = System.getProperty("line.separator");
Expand Down Expand Up @@ -105,6 +107,12 @@ private void setupDelimiters() {
repetitionSeparator = dialect.getRepetitionSeparator();
}

if (properties.containsKey(Delimiters.DECIMAL)) {
decimalMark = property(Delimiters.DECIMAL);
} else {
decimalMark = dialect.getDecimalMark();
}

if (properties.containsKey(Delimiters.RELEASE)) {
releaseIndicator = property(Delimiters.RELEASE);
} else {
Expand Down Expand Up @@ -264,7 +272,7 @@ public EDIStreamWriter writeStartSegment(String name) throws EDIStreamException
if (dialect instanceof EDIFACTDialect && "UNA".equals(name)) {
write(this.componentElementSeparator);
write(this.dataElementSeparator);
write('.'); //TODO make dynamic
write(this.decimalMark);
write(this.releaseIndicator);
write(this.repetitionSeparator);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,6 @@ public int getTextLength() {

@Override
public String getEncoding() {
// TODO Auto-generated method stub
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

public interface EventHandler {

void interchangeBegin();
void interchangeBegin(Dialect dialect);

void interchangeEnd();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public Lexer(InputStream stream, EventHandler handler, InternalLocation location

this.location = location;

isn = (notifyState, start, length) -> handler.interchangeBegin();
isn = (notifyState, start, length) -> handler.interchangeBegin(dialect);

ien = (notifyState, start, length) -> {
handler.interchangeEnd();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public class ProxyEventHandler implements EventHandler {
private Location[] locations = new Location[99];
private int eventCount = 0;
private int eventIndex = 0;
private Dialect dialect;

public ProxyEventHandler(InternalLocation location, Schema controlSchema) {
this.location = location;
Expand Down Expand Up @@ -127,7 +128,8 @@ public void setBinary(InputStream binary) {
}

@Override
public void interchangeBegin() {
public void interchangeBegin(Dialect dialect) {
this.dialect = dialect;
enqueueEvent(EDIStreamEvent.START_INTERCHANGE, EDIStreamValidationError.NONE, "", null);
}

Expand Down Expand Up @@ -237,7 +239,7 @@ public void elementData(char[] text, int start, int length) {

if (validator() != null) {
final boolean composite = location.getComponentPosition() > -1;
boolean valid = validator().validateElement(location, elementHolder);
boolean valid = validator().validateElement(dialect, location, elementHolder);
derivedComposite = !composite && validator().isComposite();

code = validator().getElementReferenceNumber();
Expand Down Expand Up @@ -308,7 +310,7 @@ public void elementData(char[] text, int start, int length) {
}

public boolean isBinaryElementLength() {
return validator() != null && validator().isBinaryElementLength();
return validator() != null && validator().isBinaryElementLength();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ public enum State {

private static final State BD = State.ELEMENT_DATA_BINARY;

//TODO Decimal character for EDIFACT
/*
* The state transition table takes the current state and the current
* symbol, and returns either a new state or an action. An action is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.Set;

import io.xlate.edi.internal.stream.tokenization.CharacterSet;
import io.xlate.edi.internal.stream.tokenization.Dialect;
import io.xlate.edi.internal.stream.tokenization.EDIException;
import io.xlate.edi.schema.EDISimpleType;
import io.xlate.edi.stream.EDIStreamValidationError;
Expand All @@ -36,7 +37,8 @@ static AlphaNumericValidator getInstance() {
}

@Override
void validate(EDISimpleType element,
void validate(Dialect dialect,
EDISimpleType element,
CharSequence value,
List<EDIStreamValidationError> errors) {

Expand All @@ -60,7 +62,7 @@ void validate(EDISimpleType element,
}

@Override
void format(EDISimpleType element, CharSequence value, Appendable result) throws EDIException {
void format(Dialect dialect, EDISimpleType element, CharSequence value, Appendable result) throws EDIException {
int length = value.length();
assertMaxLength(element, length);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Calendar;
import java.util.List;

import io.xlate.edi.internal.stream.tokenization.Dialect;
import io.xlate.edi.internal.stream.tokenization.EDIException;
import io.xlate.edi.schema.EDISimpleType;
import io.xlate.edi.stream.EDIStreamValidationError;
Expand All @@ -35,7 +36,8 @@ static DateValidator getInstance() {
}

@Override
void validate(EDISimpleType element,
void validate(Dialect dialect,
EDISimpleType element,
CharSequence value,
List<EDIStreamValidationError> errors) {

Expand All @@ -47,7 +49,7 @@ void validate(EDISimpleType element,
}

@Override
void format(EDISimpleType element, CharSequence value, Appendable result) throws EDIException {
void format(Dialect dialect, EDISimpleType element, CharSequence value, Appendable result) throws EDIException {
int length = value.length();
assertMinLength(element, length);
assertMaxLength(element, length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
******************************************************************************/
package io.xlate.edi.internal.stream.validation;

import io.xlate.edi.internal.stream.tokenization.Dialect;

class DecimalValidator extends NumericValidator {

private static final DecimalValidator singleton = new DecimalValidator();
Expand All @@ -27,7 +29,8 @@ static DecimalValidator getInstance() {
}

@Override
int validate(CharSequence value) {
int validate(Dialect dialect, CharSequence value) {
final char decimalMark = dialect.getDecimalMark();
int length = value.length();

int dec = 0;
Expand All @@ -48,14 +51,6 @@ int validate(CharSequence value) {
case '9':
break;

case '.':
length--;

if (++dec > 1 || exp > 0) {
invalid = true;
}
break;

case 'E':
length--;

Expand All @@ -73,7 +68,16 @@ int validate(CharSequence value) {
break;

default:
invalid = true;
if (value.charAt(i) == decimalMark) {
length--;

if (++dec > 1 || exp > 0) {
invalid = true;
}
} else {
invalid = true;
}

break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.util.List;

import io.xlate.edi.internal.stream.tokenization.Dialect;
import io.xlate.edi.internal.stream.tokenization.EDIException;
import io.xlate.edi.schema.EDISimpleType;
import io.xlate.edi.stream.EDIStreamValidationError;
Expand Down Expand Up @@ -70,11 +71,13 @@ protected static void assertMaxLength(EDISimpleType element, int length) throws
}
}

abstract void validate(EDISimpleType element,
abstract void validate(Dialect dialect,
EDISimpleType element,
CharSequence value,
List<EDIStreamValidationError> errors);

abstract void format(EDISimpleType element,
abstract void format(Dialect dialect,
EDISimpleType element,
CharSequence value,
Appendable result) throws EDIException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.io.IOException;
import java.util.List;

import io.xlate.edi.internal.stream.tokenization.Dialect;
import io.xlate.edi.internal.stream.tokenization.EDIException;
import io.xlate.edi.schema.EDISimpleType;
import io.xlate.edi.stream.EDIStreamValidationError;
Expand All @@ -34,8 +35,8 @@ static NumericValidator getInstance() {
}

@Override
void validate(EDISimpleType element, CharSequence value, List<EDIStreamValidationError> errors) {
int length = validate(value);
void validate(Dialect dialect, EDISimpleType element, CharSequence value, List<EDIStreamValidationError> errors) {
int length = validate(dialect, value);
validateLength(element, Math.abs(length), errors);

if (length < 0) {
Expand All @@ -44,8 +45,8 @@ void validate(EDISimpleType element, CharSequence value, List<EDIStreamValidatio
}

@Override
void format(EDISimpleType element, CharSequence value, Appendable result) throws EDIException {
int length = validate(value);
void format(Dialect dialect, EDISimpleType element, CharSequence value, Appendable result) throws EDIException {
int length = validate(dialect, value);
assertMaxLength(element, Math.abs(length));

if (length < 0) {
Expand All @@ -63,7 +64,15 @@ void format(EDISimpleType element, CharSequence value, Appendable result) throws
}
}

int validate(CharSequence value) {
/**
* Validate that the value contains only characters the represent an
* integer.
*
* @param dialect the dialect currently be parsed
* @param value the sequence of characters to validate
* @return true of the value is a valid integer representation, otherwise false
*/
int validate(Dialect dialect, CharSequence value) {
int length = value.length();
boolean invalid = false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.io.IOException;
import java.util.List;

import io.xlate.edi.internal.stream.tokenization.Dialect;
import io.xlate.edi.internal.stream.tokenization.EDIException;
import io.xlate.edi.schema.EDISimpleType;
import io.xlate.edi.stream.EDIStreamValidationError;
Expand All @@ -34,7 +35,8 @@ static TimeValidator getInstance() {
}

@Override
void validate(EDISimpleType element,
void validate(Dialect dialect,
EDISimpleType element,
CharSequence value,
List<EDIStreamValidationError> errors) {
final int length = value.length();
Expand All @@ -45,7 +47,7 @@ void validate(EDISimpleType element,
}

@Override
void format(EDISimpleType element, CharSequence value, Appendable result) throws EDIException {
void format(Dialect dialect, EDISimpleType element, CharSequence value, Appendable result) throws EDIException {
int length = value.length();
assertMaxLength(element, length);

Expand Down
Loading

0 comments on commit 1d41ee8

Please sign in to comment.