Skip to content

Commit

Permalink
Merge pull request #9 from riege/ADD_FZB_SUPPORT
Browse files Browse the repository at this point in the history
Add support to convert XFZBv3 (eHouse) message to ONE Record Waybill
  • Loading branch information
mskopp authored May 6, 2022
2 parents 7850e7b + 182a3e5 commit c3dbefd
Show file tree
Hide file tree
Showing 13 changed files with 1,176 additions and 81 deletions.
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Cargo-XML XFWB to ONE Record Converter
# Cargo-XML XFWB / XFZB to ONE Record Converter
Note: A live demo of this converter is available at https://onerecord.riege.com/

## Release versioning and IATA Ontology versions

The IATA Ontology version is reflected by the version of the Riege [one-record-ontologymodel library](https://github.com/riege/one-record-ontologymodel).

It is highly recommended to use converter library 1.0 / Ontology version 2.0 or younger for
converting XFWB to ONE Record since IATA Ontology version 2.0 added major improvements for
converting XFWB or XFZB to ONE Record since IATA Ontology version 2.0 added major improvements for
eAWB data fields.

Versions of the converter library:
Expand All @@ -22,7 +22,7 @@ This converter intentionally does neither set IDs nor makes use of persisted dat
The converter is based on two main data structures to convert from Cargo-XML to ONE Record:

* For parsing Cargo-XML the converter uses Java classes which had been generated from the
Cargo-XML XFWB3 schema. These generated classes are included via library
Cargo-XML schema. These generated classes are included via library
https://github.com/riege/cargoxml-jaxb.
Please note that the cargoxml-jaxb package does not contain any schema information from the IATA Cargo-XML
Toolkit.
Expand All @@ -40,12 +40,15 @@ Codes and units are copied 1:1 from the provided Cargo-XML message where applica

Line breaks are respected for some fields if provided in XML, e.g. for multi-line goods description or address name/street. Line breaks are intentionally used in GoodsDescription to preserve and indicate descriptions from more than one field if applicaple from original XML

At the moment the converted is limited to map the Cargo-XML XFWB3 message to ONE Record JSON.
Please note that the XFWB3 to 1R converter is not mapping all possible data yet and has focus on a XFWB message from a forwarder to an airline
Version 0.9 is limited to map the Cargo-XML XFWB3 message to ONE Record JSON.
Version 1.0 adds a basic mapping for the Cargo-XML XFZB3 message.
Please note that the 1R converter is not mapping all possible data yet and has focus on the use-case 'message from a forwarder to an airline'.

## Usage

### Programming

#### XFWB
The main Cargo-XML class for XFWB3 is `com.riege.cargoxml.schema.xfwb3.WaybillType`.

The `com.riege.onerecord.converter.XFWB3toOneRecordConverter` converts a provided
Expand All @@ -67,8 +70,13 @@ into validation results plus hints and especially into ONE Record logistics data
}
Waybill oneRecordWaybill = converter.getOneRecordResult();

The `Waybill` can be serialized easily into JSON, e.g. with https://github.com/FasterXML/jackson
The `Waybill` can be serialized easily into JSON, e.g. with https://github.com/FasterXML/jackson

#### XFZB
For XFZB3, the main Cargo-XML class is `com.riege.cargoxml.schema.xfzb3.HouseWaybillType`.

The `com.riege.onerecord.converter.XFZB3toOneRecordConverter` converts in a similar way
from `HouseWaybillType` into `org.iata.cargo.model.Waybill`.

### Library usage
The converter library is not published on mavenCentral (yet).
Expand Down
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,11 @@ dependencies {
// implementation('com.github.riege:one-record-ontologymodel:1.1.2') { transitive = false }
// jitpack dependency (commit hash (e.g. daec14a075) based, for unreleased development versions):
// implementation('com.github.riege:one-record-ontologymodel:daec14a075') { transitive = false }
// implementation('com.github.riege:one-record-ontologymodel:e9f5883a21') { transitive = false }
// github/riege internal dependency:
// implementation('com.riege:one-record-ontologymodel:1.1.2') { transitive = false }

implementation('com.github.riege:one-record-ontologymodel:e9f5883a21') { transitive = false }
implementation('com.github.riege:one-record-ontologymodel:2.0.0') { transitive = false }

// cargoxml-jaxb from riege.com cannot be retrieved via https://jitpack.io
// because building it requires access to the Cargo-XML Toolkit schema files
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.riege.onerecord.converter;

import java.util.List;

import org.iata.cargo.model.LogisticsObject;
import org.iata.cargo.model.Waybill;

/**
* Abstract superclass for converters into ONE Record type T
* @param <T> the type of ONE Record LogisticsObject to convert into
*/
public abstract class CargoXMLtoOneRecordConverter<T extends LogisticsObject> {

public static final String VG_GENERAL = "General";
public static final String VG_UNCERTAINTY = "Mapping-Uncertainty";
public static final String VG_UNIMPLEMENTED = "Not-Implemented-Yet";
public static final String VG_XMLDATAWARNING = "XML-Data-Warning";
public static final String VG_XMLDATAERROR = "XML-Data-Error";
public static final String VG_INFORMATION = "Info";
protected final ValidationResult validationResult;

public CargoXMLtoOneRecordConverter() {
validationResult = new ValidationResult();

// General Hints
addHint(VG_GENERAL, "This converter intentionally does neither set IDs nor makes use of persisted data for linked-data purposes.");
addHint(VG_GENERAL, "This converter is based on the schema from IATA CargoXML Toolkit 8th Edition.");
addHint(VG_GENERAL, "This converter is based on ONE RECORD datamodel Ontology 2.0, see https://github.com/IATA-Cargo/ONE-Record/tree/master/June-2021-standard-forCOTBendorsement/Data-Model");
addHint(VG_GENERAL, "Codes and units are applied 1:1 from CargoXML where applicable.");
addHint(VG_GENERAL, "Line breaks are respected for some fields if provided in XML, e.g. for multi-line goods description or address name/street");
addHint(VG_GENERAL, "Line breaks are intentionally added in 'goodsDescription' and 'accountingInformation' to preserve and indicate descriptions from more than one field if applicaple from original XML");
addHint(VG_GENERAL, "The 1R converter is not mapping all possible data yet and has focus on the use-case of 'message from forwarder to airline'");
}

/**
* @return converted ONE Record result
*/
public abstract T getOneRecordResult();

/**
* @return complete conversion errors, warnings and hints
*/
public final ValidationResult getValidationResult() {
return validationResult;
}

/**
* @return conversion hints
*/
public final List<ValidationMessage> getValidationHints() {
return validationResult.getHints();
}

/**
* @return conversion warnings
*/
public final List<ValidationMessage> getValidationWarnings() {
return validationResult.getWarnings();
}

/**
* @return conversion warnings
*/
public final List<ValidationMessage> getValidationErrors() {
return validationResult.getErrors();
}

protected final void addHint(String group, String text) {
validationResult.addHint(group, text);
}

protected final void addWarning(String group, String text) {
validationResult.addWarning(group, text);
}

protected final void addError(String group, String text) {
validationResult.addError(group, text);
}

}
31 changes: 31 additions & 0 deletions src/main/java/com/riege/onerecord/converter/ConverterUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
import javax.xml.bind.Unmarshaller;

import com.riege.cargoxml.schema.xfwb3.WaybillType;
import com.riege.cargoxml.schema.xfzb3.HouseWaybillType;

public final class ConverterUtil {

private Unmarshaller unmarshallerXFWB3;
private Unmarshaller unmarshallerXFZB3;

private Unmarshaller getXFWB3Unmarshaller() throws JAXBException {
if (unmarshallerXFWB3 == null) {
Expand All @@ -24,7 +26,23 @@ private Unmarshaller getXFWB3Unmarshaller() throws JAXBException {
return unmarshallerXFWB3;
}

private Unmarshaller getXFZB3Unmarshaller() throws JAXBException {
if (unmarshallerXFZB3 == null) {
JAXBContext jaxbContext = JAXBContext.newInstance(HouseWaybillType.class.getPackage().getName());
unmarshallerXFZB3 = jaxbContext.createUnmarshaller();
}
return unmarshallerXFZB3;
}

/**
* Deprecated in version 1.0, use unmarshallXFWB3 instead
*/
@Deprecated
public WaybillType unmarshalXFWB3(InputStream inputStream) throws JAXBException {
return unmarshallXFWB3(inputStream);
}

public WaybillType unmarshallXFWB3(InputStream inputStream) throws JAXBException {
Object result = getXFWB3Unmarshaller().unmarshal(inputStream);
if (!(result instanceof JAXBElement)) {
throw new UnmarshalException("Unexpected class " + result.getClass().getName()
Expand All @@ -37,6 +55,19 @@ public WaybillType unmarshalXFWB3(InputStream inputStream) throws JAXBException
return (WaybillType) cargoxml;
}

public HouseWaybillType unmarshallXFZB3(InputStream inputStream) throws JAXBException {
Object result = getXFZB3Unmarshaller().unmarshal(inputStream);
if (!(result instanceof JAXBElement)) {
throw new UnmarshalException("Unexpected class " + result.getClass().getName()
+ " while unmarshalling, expected JAXBElement");
}
Object cargoxml = ((JAXBElement)result).getValue();
if (!(cargoxml instanceof HouseWaybillType)) {
throw new UnmarshalException("No CargoXML XFWZB3 format detected");
}
return (HouseWaybillType) cargoxml;
}

public static boolean isNullOrEmpty( final Collection< ? > c ) {
return c == null || c.isEmpty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ public static final <T> Set<T> buildSet() {
}

/**
* @param <T> the type of elements maintained by this set
* @param singleEntry is added to the generated and returned Set
* @return Set built from the provided data, null if provided data is null
*/
public static final <T> Set<T> buildSet(T singleEntry) {
Expand All @@ -284,6 +286,8 @@ public static final <T> Set<T> buildSet(T singleEntry) {
}

/**
* @param <T> the type of elements maintained by this set
* @param array entries are added to the generated and returned Set
* @return Set built from the provided data even if the array is empty, null if provided data is null
*/
public static final <T> Set<T> buildSet(T[] array) {
Expand All @@ -294,6 +298,8 @@ public static final <T> Set<T> buildSet(T[] array) {
}

/**
* @param <T> the type of elements maintained by this set
* @param list entries are added to the generated and returned Set
* @return Set built from the provided data even if the list is empty, null if provided data is null
*/
public static final <T> Set<T> buildSet(List<T> list) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,11 @@ public String getDetail() {
}

/**
* @Deprecated use {@link #getGroup()} and {@link #getDetail()} instead
* Deprecated in version 1.0 use {@link #getGroup()} and {@link #getDetail()} instead
*
* @return validation message as string, prefixed with group
*/
@Deprecated
public String getMessage() {
return group == null ? detail : "[" + group + "] " + detail;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ public class ValidationResult {
private List<ValidationMessage> messageList = new ArrayList<>();

/**
* @Deprecated in version 0.10, use {@link #addHint(String, String)} instead
* Deprecated in version 1.0, use {@link #addHint(String, String)} instead
*
* @param message message to be added as validation hint
*/
@Deprecated
public void addHint(String message) {
Expand All @@ -21,7 +23,9 @@ public void addHint(String group, String detail) {
}

/**
* @Deprecated in version 0.10, use {@link #addWarning(String, String)} instead
* Deprecated in version 1.0, use {@link #addWarning(String, String)} instead
*
* @param message message to be added as validation warning
*/
@Deprecated
public void addWarning(String message) {
Expand All @@ -33,7 +37,9 @@ public void addWarning(String group, String detail) {
}

/**
* @Deprecated in version 0.10, use {@link #addError(String, String)} instead
* Deprecated in version 1.0, use {@link #addError(String, String)} instead
*
* @param message message to be added as validation werror
*/
@Deprecated
public void addError(String message) {
Expand Down
Loading

0 comments on commit c3dbefd

Please sign in to comment.