Skip to content

Commit

Permalink
support for parser of EXI4JSON schema V2
Browse files Browse the repository at this point in the history
  • Loading branch information
danielpeintner committed Aug 23, 2016
1 parent b8fb823 commit ee52f91
Show file tree
Hide file tree
Showing 6 changed files with 351 additions and 165 deletions.
2 changes: 2 additions & 0 deletions src/main/java/com/siemens/ct/exi/json/AbstractEXIforJSON.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public abstract class AbstractEXIforJSON {
static Grammars g2;

final EXIFactory ef;
final String schemaId;

public AbstractEXIforJSON() throws EXIException, IOException {
this(DefaultEXIFactory.newInstance());
Expand All @@ -69,6 +70,7 @@ public AbstractEXIforJSON(String schemaId) throws EXIException, IOException {

public AbstractEXIforJSON(EXIFactory ef, String schemaId) throws EXIException, IOException {
this.ef = ef;
this.schemaId = schemaId;

if(ef.getGrammars().isSchemaInformed()) {
// schema-informed grammars (dedicated grammars in use)
Expand Down
182 changes: 92 additions & 90 deletions src/main/java/com/siemens/ct/exi/json/EXIforJSONGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
Expand All @@ -43,9 +44,7 @@
import com.siemens.ct.exi.EXIBodyEncoder;
import com.siemens.ct.exi.EXIFactory;
import com.siemens.ct.exi.EXIStreamEncoder;
import com.siemens.ct.exi.FidelityOptions;
import com.siemens.ct.exi.exceptions.EXIException;
import com.siemens.ct.exi.helpers.DefaultEXIFactory;
import com.siemens.ct.exi.values.StringValue;

public class EXIforJSONGenerator extends AbstractEXIforJSON {
Expand Down Expand Up @@ -85,12 +84,98 @@ static void printDebugInd(int ind, String s) {
}
}

public void generate(InputStream is, OutputStream os) throws EXIException, IOException {
public void generate(InputStream isJSON, OutputStream osEXI4JSON) throws EXIException, IOException {
if(EXI4JSONConstants.XML_SCHEMA_FOR_JSON.equals(schemaId)) {
generateV1(isJSON, osEXI4JSON);
} else {
generateV2(isJSON, osEXI4JSON);
}
}


public static void main(String[] args) throws FileNotFoundException, EXIException, IOException {
// TEST V2
// String json = "./../../../W3C/EXI/docs/json/V2/personnel_one.json";
// String json = "./../../../W3C/EXI/docs/json/V2/personnel_three.json";

if(false) {
List<String> jsons = new ArrayList<String>();
// Taki
jsons.add("./../../../W3C/EXI/docs/json/V2/personnel_one.json");
jsons.add("./../../../W3C/EXI/docs/json/V2/personnel_two.json");
jsons.add("./../../../W3C/EXI/docs/json/V2/personnel_three.json");

// Some other samples
jsons.add("./../../../W3C/EXI/docs/json/V2/test/bower.json");
jsons.add("./../../../W3C/EXI/docs/json/V2/test/door.jsonld");
jsons.add("./../../../W3C/EXI/docs/json/V2/test/package.json");
jsons.add("./../../../W3C/EXI/docs/json/V2/test/ui.resizable.jquery.json");

// "old" JSON tests
// GPX
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/gpx/sample-set-1/gpx-1-1pts.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/gpx/sample-set-1/gpx-1-100pts.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/gpx/sample-set-1/gpx-1-200pts.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/gpx/sample-set-1/gpx-1-500pts.json");
// JSON Generator
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/json-generator.com/2015-01-06/01.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/json-generator.com/2015-01-06/03.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/json-generator.com/2015-01-06/06.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/json-generator.com/2015-01-06/10.json");
// OpenWheather
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/openweathermap.org/sample-set-1/owm-1-1cities.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/openweathermap.org/sample-set-1/owm-1-100cities.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/openweathermap.org/sample-set-1/owm-1-200cities.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/openweathermap.org/sample-set-1/owm-1-300cities.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/openweathermap.org/sample-set-1/owm-1-400cities.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/openweathermap.org/sample-set-1/owm-1-500cities.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/openweathermap.org/sample-set-1/owm-1-1000cities.json");


System.out.println("Name; JSON; V1; V2");
for(String json: jsons) {
test(json);
}
} else {
// String s = "{\n \"keyNumber\": 123,\n \"keyArrayStrings\": [\n \"s1\",\n \"s2\"\n ]\n}";
String s = "{\n \"glossary\": {\n \"title\": \"example glossary\",\n \"GlossDiv\": {\n \"title\": \"S\",\n \"GlossList\": {\n \"GlossEntry\": {\n \"ID\": \"SGML\",\n \"SortAs\": \"SGML\",\n \"GlossTerm\": \"Standard Generalized Markup Language\",\n \"Acronym\": \"SGML\",\n \"Abbrev\": \"ISO 8879:1986\",\n \"GlossDef\": {\n \"para\": \"A meta-markup language, used to create markup languages such as DocBook.\",\n \"GlossSeeAlso\": [\n \"GML\",\n \"XML\"\n ]\n },\n \"GlossSee\": \"markup\"\n }\n }\n }\n }\n}";
ByteArrayOutputStream baosV2 = new ByteArrayOutputStream();
EXIforJSONGenerator e4jGenerator = new EXIforJSONGenerator();
e4jGenerator.generate(new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8)), baosV2);

File f = File.createTempFile("exi4json", "exi");
FileOutputStream fos = new FileOutputStream(f);
fos.write(baosV2.toByteArray());
fos.close();
System.out.println("EXI4JSON Written to " + f);
}

}

private static void test(String json) throws FileNotFoundException, EXIException, IOException {
ByteArrayOutputStream baosV1 = new ByteArrayOutputStream();
{
EXIforJSONGenerator e4jGenerator = new EXIforJSONGenerator(EXI4JSONConstants.XML_SCHEMA_FOR_JSON);
e4jGenerator.generate(new FileInputStream(json), baosV1);
// System.out.println("Size V1: " + baosV1.size());
}

ByteArrayOutputStream baosV2 = new ByteArrayOutputStream();
{
EXIforJSONGenerator e4jGenerator = new EXIforJSONGenerator();
e4jGenerator.generate(new FileInputStream(json), baosV2);
// System.out.println("Size V2: " + baosV2.size());
}

System.out.println(json + "; " + (new File(json)).length() + "; " + baosV1.size() + "; " + baosV2.size());
}

private void generateV1(InputStream isJSON, OutputStream osEXI4JSON) throws EXIException, IOException {
EXIStreamEncoder streamEncoder = ef.createEXIStreamEncoder();

EXIBodyEncoder bodyEncoder = streamEncoder.encodeHeader(os);
EXIBodyEncoder bodyEncoder = streamEncoder.encodeHeader(osEXI4JSON);

JsonParser parser = Json.createParser(is);
JsonParser parser = Json.createParser(isJSON);

int ind = 0;
String key = null;
Expand Down Expand Up @@ -192,92 +277,10 @@ public void generate(InputStream is, OutputStream os) throws EXIException, IOExc
bodyEncoder.flush();
}


public static void main(String[] args) throws FileNotFoundException, EXIException, IOException {
// TEST V2
// String json = "./../../../W3C/EXI/docs/json/V2/personnel_one.json";
// String json = "./../../../W3C/EXI/docs/json/V2/personnel_three.json";

if(true) {
List<String> jsons = new ArrayList<String>();
// Taki
jsons.add("./../../../W3C/EXI/docs/json/V2/personnel_one.json");
jsons.add("./../../../W3C/EXI/docs/json/V2/personnel_two.json");
jsons.add("./../../../W3C/EXI/docs/json/V2/personnel_three.json");

// Some other samples
jsons.add("./../../../W3C/EXI/docs/json/V2/test/bower.json");
jsons.add("./../../../W3C/EXI/docs/json/V2/test/door.jsonld");
jsons.add("./../../../W3C/EXI/docs/json/V2/test/package.json");
jsons.add("./../../../W3C/EXI/docs/json/V2/test/ui.resizable.jquery.json");

// "old" JSON tests
// GPX
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/gpx/sample-set-1/gpx-1-1pts.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/gpx/sample-set-1/gpx-1-100pts.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/gpx/sample-set-1/gpx-1-200pts.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/gpx/sample-set-1/gpx-1-500pts.json");
// JSON Generator
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/json-generator.com/2015-01-06/01.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/json-generator.com/2015-01-06/03.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/json-generator.com/2015-01-06/06.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/json-generator.com/2015-01-06/10.json");
// OpenWheather
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/openweathermap.org/sample-set-1/owm-1-1cities.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/openweathermap.org/sample-set-1/owm-1-100cities.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/openweathermap.org/sample-set-1/owm-1-200cities.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/openweathermap.org/sample-set-1/owm-1-300cities.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/openweathermap.org/sample-set-1/owm-1-400cities.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/openweathermap.org/sample-set-1/owm-1-500cities.json");
jsons.add("./../../../W3C/Group/EXI/TTFMS/data/JSON/openweathermap.org/sample-set-1/owm-1-1000cities.json");


System.out.println("Name; JSON; V1; V2");
for(String json: jsons) {
test(json);
}
} else {
// String s = "{\n \"keyNumber\": 123,\n \"keyArrayStrings\": [\n \"s1\",\n \"s2\"\n ]\n}";
String s = "{\n \"glossary\": {\n \"title\": \"example glossary\",\n \"GlossDiv\": {\n \"title\": \"S\",\n \"GlossList\": {\n \"GlossEntry\": {\n \"ID\": \"SGML\",\n \"SortAs\": \"SGML\",\n \"GlossTerm\": \"Standard Generalized Markup Language\",\n \"Acronym\": \"SGML\",\n \"Abbrev\": \"ISO 8879:1986\",\n \"GlossDef\": {\n \"para\": \"A meta-markup language, used to create markup languages such as DocBook.\",\n \"GlossSeeAlso\": [\n \"GML\",\n \"XML\"\n ]\n },\n \"GlossSee\": \"markup\"\n }\n }\n }\n }\n}";
ByteArrayOutputStream baosV2 = new ByteArrayOutputStream();
generateV2(new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8)), baosV2, getEXIFactoryV2());

}

}

private static void test(String json) throws FileNotFoundException, EXIException, IOException {
ByteArrayOutputStream baosV1 = new ByteArrayOutputStream();
{
EXIforJSONGenerator e4jGenerator = new EXIforJSONGenerator(EXI4JSONConstants.XML_SCHEMA_FOR_JSON);
e4jGenerator.generate(new FileInputStream(json), baosV1);
// System.out.println("Size V1: " + baosV1.size());
}

ByteArrayOutputStream baosV2 = new ByteArrayOutputStream();
{
generateV2(new FileInputStream(json), baosV2, getEXIFactoryV2());
// System.out.println("Size V2: " + baosV2.size());
}

System.out.println(json + "; " + (new File(json)).length() + "; " + baosV1.size() + "; " + baosV2.size());
}


private static EXIFactory getEXIFactoryV2() throws EXIException, IOException {
EXIFactory efV2 = DefaultEXIFactory.newInstance();
// setup EXI schema/grammars
efV2.setGrammars(AbstractEXIforJSON.loadGrammars2());
// set to strict
efV2.getFidelityOptions().setFidelity(FidelityOptions.FEATURE_STRICT, true);

return efV2;
}

private static void generateV2(InputStream isJSON, OutputStream osEXI4JSON, EXIFactory efV2) throws EXIException, IOException {
private void generateV2(InputStream isJSON, OutputStream osEXI4JSON) throws EXIException, IOException {
// DEBUG = System.out;

EXIStreamEncoder streamEncoder = efV2.createEXIStreamEncoder();
EXIStreamEncoder streamEncoder = ef.createEXIStreamEncoder();

EXIBodyEncoder bodyEncoder = streamEncoder.encodeHeader(osEXI4JSON);

Expand Down Expand Up @@ -381,7 +384,6 @@ private static void checkKeyEnd(List<Event> events, List<String> keys, EXIBodyEn
printDebug("</" + keys.remove(keys.size()-1) +">");
events.remove(events.size()-1);
}

}


Expand Down
113 changes: 110 additions & 3 deletions src/main/java/com/siemens/ct/exi/json/EXIforJSONParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,21 @@ void checkPendingEvent(JsonGenerator generator) {



public void parse(InputStream is, OutputStream os) throws EXIException, IOException {
public void parse(InputStream isEXI4JSON, OutputStream osJSON) throws EXIException, IOException {

if(EXI4JSONConstants.XML_SCHEMA_FOR_JSON.equals(schemaId)) {
parseV1(isEXI4JSON, osJSON);
} else {
parseV2(isEXI4JSON, osJSON);
}
}

private void parseV1(InputStream isEXI4JSON, OutputStream osJSON) throws EXIException, IOException {
EXIStreamDecoder streamDecoder = ef.createEXIStreamDecoder();

EXIBodyDecoder bodyDecoder = streamDecoder.decodeHeader(is);
EXIBodyDecoder bodyDecoder = streamDecoder.decodeHeader(isEXI4JSON);

JsonGenerator generator = Json.createGenerator(new OutputStreamWriter(os));
JsonGenerator generator = Json.createGenerator(new OutputStreamWriter(osJSON));

EventType next;

Expand Down Expand Up @@ -215,7 +224,105 @@ public void parse(InputStream is, OutputStream os) throws EXIException, IOExcept
}
}

generator.flush();
}


private void parseV2(InputStream isEXI4JSON, OutputStream osJSON) throws EXIException, IOException {
EXIStreamDecoder streamDecoder = ef.createEXIStreamDecoder();

EXIBodyDecoder bodyDecoder = streamDecoder.decodeHeader(isEXI4JSON);

JsonGenerator generator = Json.createGenerator(new OutputStreamWriter(osJSON));

EventType next;

while((next = bodyDecoder.next()) != null) {
switch(next) {
case START_DOCUMENT:
bodyDecoder.decodeStartDocument();
break;
case END_DOCUMENT:
bodyDecoder.decodeEndDocument();
break;
case ATTRIBUTE:
QNameContext qncAT = bodyDecoder.decodeAttribute();
if(!EXI4JSONConstants.LOCALNAME_KEY.equals(qncAT.getLocalName())) {
throw new RuntimeException("Not supported EXI attribute: " + qncAT);
}
Value avalue = bodyDecoder.getAttributeValue();
key = avalue.toString();
// checkPendingEvent(generator, jsonEvent, value.toString());
break;
case CHARACTERS:
value = bodyDecoder.decodeCharacters();
checkPendingEvent(generator);
break;
case START_ELEMENT_NS:
// key element
key = bodyDecoder.decodeStartElement().getLocalName();
break;
case START_ELEMENT:
case START_ELEMENT_GENERIC:
case START_ELEMENT_GENERIC_UNDECLARED:
QNameContext qncSE = bodyDecoder.decodeStartElement();
// checkPendingEvent(generator);
if(EXI4JSONConstants.LOCALNAME_MAP.equals(qncSE.getLocalName())) {
if(key == null) {
generator.writeStartObject();
} else {
generator.writeStartObject(key);
key = null;
}
} else if(EXI4JSONConstants.LOCALNAME_ARRAY.equals(qncSE.getLocalName())) {
if(key == null) {
generator.writeStartArray();
} else {
generator.writeStartArray(key);
key = null;
}
} else if(EXI4JSONConstants.LOCALNAME_STRING.equals(qncSE.getLocalName())) {
// wait for value
jsonEvent = Event.VALUE_STRING;
} else if(EXI4JSONConstants.LOCALNAME_NUMBER.equals(qncSE.getLocalName())) {
// wait for value
jsonEvent = Event.VALUE_NUMBER;
} else if(EXI4JSONConstants.LOCALNAME_BOOLEAN.equals(qncSE.getLocalName())) {
// wait for value
jsonEvent = Event.VALUE_FALSE;
} else if(EXI4JSONConstants.LOCALNAME_NULL.equals(qncSE.getLocalName())) {
generator.writeNull();
} else if(EXI4JSONConstants.LOCALNAME_OTHER.equals(qncSE.getLocalName())) {
// TODO other element
throw new RuntimeException("'other' element not yet supported!");
} else {
// key element
key = bodyDecoder.decodeStartElement().getLocalName();
}
break;
case END_ELEMENT:
QNameContext qncEE = bodyDecoder.decodeEndElement();
// checkPendingEvent(generator);
if(EXI4JSONConstants.LOCALNAME_MAP.equals(qncEE.getLocalName())) {
generator.writeEnd();
} else if(EXI4JSONConstants.LOCALNAME_ARRAY.equals(qncEE.getLocalName())) {
generator.writeEnd();
}
break;
default:
throw new RuntimeException("Not supported EXI event: " + next);
}
}

generator.flush();
}

// public static void main(String[] args) throws EXIException, IOException {
// if(args.length == 1) {
// EXIforJSONParser e4jParser = new EXIforJSONParser();
// ByteArrayOutputStream osJSON = new ByteArrayOutputStream();
// e4jParser.parse(new FileInputStream("C:\\Users\\mchn4310\\AppData\\Local\\Temp\\exi4json4302776206135352859exi"), osJSON);
// System.out.println(new String(osJSON.toByteArray()));
// }
// }
}
Loading

0 comments on commit ee52f91

Please sign in to comment.