Skip to content

Commit

Permalink
Merge aacc367 into c7d357c
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeEdgar committed Oct 14, 2021
2 parents c7d357c + aacc367 commit b8d20d4
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 23 deletions.
8 changes: 4 additions & 4 deletions src/main/java/io/xlate/edi/internal/schema/Reference.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Reference implements EDIReference {
private static final String TOSTRING_FORMAT = "refId: %s, minOccurs: %d, maxOccurs: %d, type: { %s }";

private String refId;
private String refTag;
private EDIType.Type refTag;
private EDIType referencedType;

final int minOccurs;
Expand Down Expand Up @@ -58,7 +58,7 @@ public int getMaxOccurs(Reference defaultElement) {
}
}

Reference(String refId, String refTag, int minOccurs, int maxOccurs, List<Version> versions, String title, String description) {
Reference(String refId, EDIType.Type refTag, int minOccurs, int maxOccurs, List<Version> versions, String title, String description) {
this.refId = refId;
this.refTag = refTag;
this.minOccurs = minOccurs;
Expand All @@ -68,7 +68,7 @@ public int getMaxOccurs(Reference defaultElement) {
this.description = description;
}

Reference(String refId, String refTag, int minOccurs, int maxOccurs, String title, String description) {
Reference(String refId, EDIType.Type refTag, int minOccurs, int maxOccurs, String title, String description) {
this(refId, refTag, minOccurs, maxOccurs, Collections.emptyList(), title, description);
}

Expand Down Expand Up @@ -100,7 +100,7 @@ String getRefId() {
return refId;
}

String getRefTag() {
EDIType.Type getRefTag() {
return refTag;
}

Expand Down
40 changes: 22 additions & 18 deletions src/main/java/io/xlate/edi/internal/schema/SchemaReaderBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
Expand Down Expand Up @@ -50,11 +51,11 @@ abstract class SchemaReaderBase implements SchemaReader {
static final String ATTR_LEVEL_ID_POSITION = "levelIdPosition";
static final String ATTR_PARENT_ID_POSITION = "parentIdPosition";

static final EDIReference ANY_ELEMENT_REF_OPT = new Reference(StaEDISchema.ANY_ELEMENT_ID, LOCALNAME_ELEMENT, 0, 1, null, null);
static final EDIReference ANY_COMPOSITE_REF_OPT = new Reference(StaEDISchema.ANY_COMPOSITE_ID, LOCALNAME_COMPOSITE, 0, 99, null, null);
static final EDIReference ANY_ELEMENT_REF_OPT = new Reference(StaEDISchema.ANY_ELEMENT_ID, EDIType.Type.ELEMENT, 0, 1, null, null);
static final EDIReference ANY_COMPOSITE_REF_OPT = new Reference(StaEDISchema.ANY_COMPOSITE_ID, EDIType.Type.COMPOSITE, 0, 99, null, null);

static final EDIReference ANY_ELEMENT_REF_REQ = new Reference(StaEDISchema.ANY_ELEMENT_ID, LOCALNAME_ELEMENT, 1, 1, null, null);
static final EDIReference ANY_COMPOSITE_REF_REQ = new Reference(StaEDISchema.ANY_COMPOSITE_ID, LOCALNAME_COMPOSITE, 1, 99, null, null);
static final EDIReference ANY_ELEMENT_REF_REQ = new Reference(StaEDISchema.ANY_ELEMENT_ID, EDIType.Type.ELEMENT, 1, 1, null, null);
static final EDIReference ANY_COMPOSITE_REF_REQ = new Reference(StaEDISchema.ANY_COMPOSITE_ID, EDIType.Type.COMPOSITE, 1, 99, null, null);

static final EDISimpleType ANY_ELEMENT = new ElementType(StaEDISchema.ANY_ELEMENT_ID,
Base.STRING,
Expand Down Expand Up @@ -104,7 +105,7 @@ abstract class SchemaReaderBase implements SchemaReader {

final Map<QName, EDIType.Type> complex;
final Map<QName, EDIType.Type> typeDefinitions;
final Set<QName> references;
final Map<QName, EDIType.Type> references;

protected XMLStreamReader reader;
protected Map<String, Object> properties;
Expand Down Expand Up @@ -147,10 +148,10 @@ protected SchemaReaderBase(String xmlns, XMLStreamReader reader, Map<String, Obj
typeDefinitions.put(qnCompositeType, EDIType.Type.COMPOSITE);
typeDefinitions.put(qnElementType, EDIType.Type.ELEMENT);

references = new HashSet<>(4);
references.add(qnSegment);
references.add(qnComposite);
references.add(qnElement);
references = new HashMap<>(4);
references.put(qnSegment, EDIType.Type.SEGMENT);
references.put(qnComposite, EDIType.Type.COMPOSITE);
references.put(qnElement, EDIType.Type.ELEMENT);

this.reader = reader;
this.properties = properties;
Expand Down Expand Up @@ -327,15 +328,15 @@ Reference readControlStructure(XMLStreamReader reader,

types.put(struct.getId(), struct);

Reference structRef = new Reference(struct.getId(), element.getLocalPart(), minOccurs, maxOccurs, title, descr);
Reference structRef = new Reference(struct.getId(), elementType, minOccurs, maxOccurs, title, descr);
structRef.setReferencedType(struct);

return structRef;
}

Reference createControlReference(XMLStreamReader reader, String attributeName) {
final String refId = parseAttribute(reader, attributeName, String::valueOf);
return new Reference(refId, "segment", 1, 1, null, null);
return new Reference(refId, EDIType.Type.SEGMENT, 1, 1, null, null);
}

void readTransaction(XMLStreamReader reader, Map<String, EDIType> types) {
Expand Down Expand Up @@ -497,19 +498,22 @@ void addReferences(XMLStreamReader reader, EDIType.Type parentType, List<EDIRefe
Reference readReference(XMLStreamReader reader, Map<String, EDIType> types) {
QName element = reader.getName();
String refId = null;
EDIType.Type refTag;

if (qnAny.equals(element)) {
refId = "ANY";
} else if (references.contains(element)) {
refTag = null;
} else if (references.containsKey(element)) {
refId = readReferencedId(reader);
refTag = references.get(element);
Objects.requireNonNull(refId);
} else if (qnLoop.equals(element)) {
refId = parseAttribute(reader, "code", String::valueOf);
refTag = EDIType.Type.LOOP;
} else {
throw unexpectedElement(element, reader);
}

String refTag = element.getLocalPart();
int minOccurs = parseAttribute(reader, ATTR_MIN_OCCURS, Integer::parseInt, 0);
int maxOccurs = parseAttribute(reader, ATTR_MAX_OCCURS, Integer::parseInt, 1);
String title = parseAttribute(reader, ATTR_TITLE, String::valueOf, null);
Expand Down Expand Up @@ -570,7 +574,7 @@ void readSyntax(XMLStreamReader reader, List<EDISyntaxRule> rules) {
EDISyntaxRule.Type typeInt = null;

try {
typeInt = EDISyntaxRule.Type.valueOf(type.toUpperCase());
typeInt = EDISyntaxRule.Type.fromString(type);
} catch (IllegalArgumentException e) {
throw schemaException("Invalid syntax 'type': [" + type + ']', reader, e);
}
Expand Down Expand Up @@ -607,7 +611,7 @@ List<Integer> readSyntaxPositions(XMLStreamReader reader) {
ElementType readSimpleType(XMLStreamReader reader) {
String name = parseAttribute(reader, "name", String::valueOf);
String code = parseAttribute(reader, "code", String::valueOf, name);
Base base = parseAttribute(reader, "base", val -> Base.valueOf(val.toUpperCase()), Base.STRING);
Base base = parseAttribute(reader, "base", Base::fromString, Base.STRING);
int scale = (Base.NUMERIC == base) ? parseAttribute(reader, "scale", Integer::parseInt, 0) : -1;
int number = parseAttribute(reader, "number", Integer::parseInt, -1);
long minLength = parseAttribute(reader, "minLength", Long::parseLong, 1L);
Expand Down Expand Up @@ -788,13 +792,13 @@ void setReferences(StructureType struct, Map<String, EDIType> types) {
EDIType target = types.get(impl.getRefId());

if (target == null) {
throw schemaException(String.format(REFERR_UNDECLARED, struct.getId(), impl.getRefTag(), impl.getRefId()));
throw schemaException(String.format(REFERR_UNDECLARED, struct.getId(), impl.getRefTag().name().toLowerCase(Locale.ROOT), impl.getRefId()));
}

final EDIType.Type refType = target.getType();

if (refType != EDIType.Type.valueOf(impl.getRefTag().toUpperCase())) {
throw schemaException(String.format(REFERR_ILLEGAL, impl.getRefId(), impl.getRefTag(), struct.getId()));
if (refType != impl.getRefTag()) {
throw schemaException(String.format(REFERR_ILLEGAL, impl.getRefId(), impl.getRefTag().name().toLowerCase(Locale.ROOT), struct.getId()));
}

impl.setReferencedType(target);
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/io/xlate/edi/schema/EDISimpleType.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ public enum Base {
TIME,
BINARY,
IDENTIFIER;

public static Base fromString(String value) {
for (Base entry : values()) {
if (entry.name().equalsIgnoreCase(value)) {
return entry;
}
}
throw new IllegalArgumentException("No enum constant for " + Base.class.getName() + "." + value);
}
}

Base getBase();
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/io/xlate/edi/schema/EDISyntaxRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ public enum Type {
* EDIFACT: (D7) If first, then none of the others
*/
FIRSTONLY;

public static Type fromString(String value) {
for (Type entry : values()) {
if (entry.name().equalsIgnoreCase(value)) {
return entry;
}
}
throw new IllegalArgumentException("No enum constant for " + Type.class.getName() + "." + value);
}
}

Type getType();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -635,4 +635,20 @@ void testControlNumbersHaveZeroScaleByDefault() throws EDISchemaException {
// GS06 = N0
assertEquals(Integer.valueOf(0), ((EDISimpleType) ((EDIComplexType) schema.getType("GS")).getReferences().get(5).getReferencedType()).getScale());
}

@Test
void testInvalidElementTypeBase() throws EDISchemaException {
SchemaFactory factory = SchemaFactory.newFactory();
InputStream stream = new ByteArrayInputStream((""
+ "<schema xmlns='" + StaEDISchemaFactory.XMLNS_V4 + "'>"
+ " <include schemaLocation='file:./src/test/resources/x12/EDISchema997.xml' />"
+ " <elementType name=\"DUMMY\" base=\"datetime\" maxLength=\"20\" />"
+ "</schema>").getBytes());

EDISchemaException thrown = assertThrows(EDISchemaException.class, () -> factory.createSchema(stream));
assertEquals("Invalid base", thrown.getOriginalMessage());
assertTrue(thrown.getCause() instanceof StaEDISchemaReadException);
assertTrue(thrown.getCause().getCause() instanceof IllegalArgumentException);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import io.xlate.edi.schema.EDIReference;
import io.xlate.edi.schema.EDISyntaxRule;
import io.xlate.edi.schema.EDIType;
import io.xlate.edi.schema.EDIType.Type;
import io.xlate.edi.stream.EDIInputFactory;
import io.xlate.edi.stream.EDIStreamException;
Expand All @@ -24,7 +25,7 @@ class StructureTypeTest {

@Test
void testStructureConstruction() {
EDIReference ref = new Reference("E1", "element", 1, 1, null, null);
EDIReference ref = new Reference("E1", EDIType.Type.ELEMENT, 1, 1, null, null);
EDISyntaxRule rule = new SyntaxRestriction(EDISyntaxRule.Type.EXCLUSION, Arrays.asList(1, 8));
StructureType s = new StructureType("SEG", Type.SEGMENT, "SEG", Arrays.asList(ref), Arrays.asList(rule), null, null);
assertEquals("id: SEG, type: SEGMENT, code: SEG, references: [{refId: E1, minOccurs: 1, maxOccurs: 1, type: { null }}], syntaxRestrictions: [{type: EXCLUSION, positions: [1, 8]}]",
Expand Down

0 comments on commit b8d20d4

Please sign in to comment.