| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- package com.v2gclarity.risev2g.shared.exiCodec;
- /*******************************************************************************
- * The MIT License (MIT)
- *
- * Copyright (c) 2015-207 V2G Clarity (Dr.-Ing. Marc Mültin)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *******************************************************************************/
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.io.StringWriter;
- import javax.xml.transform.Transformer;
- import javax.xml.transform.TransformerConfigurationException;
- import javax.xml.transform.TransformerException;
- import javax.xml.transform.TransformerFactory;
- import javax.xml.transform.sax.SAXSource;
- import javax.xml.transform.stream.StreamResult;
- import org.xml.sax.InputSource;
- import org.xml.sax.SAXException;
- import org.xml.sax.XMLReader;
- import org.xml.sax.helpers.XMLReaderFactory;
- import com.siemens.ct.exi.EXIFactory;
- import com.siemens.ct.exi.GrammarFactory;
- import com.siemens.ct.exi.api.sax.EXIResult;
- import com.siemens.ct.exi.api.sax.EXISource;
- import com.siemens.ct.exi.exceptions.EXIException;
- import com.siemens.ct.exi.grammars.Grammars;
- import com.siemens.ct.exi.helpers.DefaultEXIFactory;
- import com.v2gclarity.risev2g.shared.enumerations.GlobalValues;
- import com.v2gclarity.risev2g.shared.utils.ByteUtils;
- public final class EXIficientCodec extends ExiCodec {
- // -- BEGIN: SINGLETON DEFINITION --
- /*
- * Eager instantiation of the singleton, since a EXIficientCodec is always needed.
- * The JVM creates the unique instance when the class is loaded and before any thread tries to
- * access the instance variable -> thread safe.
- */
- private static final EXIficientCodec instance = new EXIficientCodec();
-
- private EXIFactory exiFactory;
- private GrammarFactory grammarFactory;
- private Grammars grammarAppProtocol;
- private Grammars grammarMsgDef;
- private Grammars grammarXMLDSig;
- private OutputStream encodeOS;
-
- private EXIficientCodec() {
- super();
-
- setExiFactory(DefaultEXIFactory.newInstance());
- setGrammarFactory(GrammarFactory.newInstance());
-
- /*
- * The Java classes
- * - EXIficient_V2G_CI_AppProtocol,
- * - EXIficient_V2G_CI_MsgDef, and
- * - EXIficient_xmldsig_core_schema
- * are serialized versions of the respective XSD schema files.
- * These serializations have been created using a tool available at
- * https://github.com/EXIficient/exificient-grammars/blob/master/src/main/java/com/siemens/ct/exi/grammars/persistency/Grammars2JavaSourceCode.java
- */
- setGrammarAppProtocol(new EXIficient_V2G_CI_AppProtocol());
- setGrammarMsgDef(new EXIficient_V2G_CI_MsgDef());
- setGrammarXMLDSig(new EXIficient_xmldsig_core_schema());
-
- // Non-default settings to fulfill requirements [V2G2-099] and [V2G2-600]
- getExiFactory().setValuePartitionCapacity(0);
- getExiFactory().setMaximumNumberOfBuiltInElementGrammars(0);
- getExiFactory().setMaximumNumberOfBuiltInProductions(0);
- }
-
- public static EXIficientCodec getInstance() {
- return instance;
- }
- // -- END: SINGLETON DEFINITION --
-
- @Override
- public synchronized byte[] encodeEXI(Object jaxbObject, String xsdSchemaPath) {
- Grammars grammar = null;
-
- if (xsdSchemaPath.equals(GlobalValues.SCHEMA_PATH_APP_PROTOCOL.toString()))
- grammar = getGrammarAppProtocol();
- else if (xsdSchemaPath.equals(GlobalValues.SCHEMA_PATH_MSG_DEF.toString()))
- grammar = getGrammarMsgDef();
- else if (xsdSchemaPath.equals(GlobalValues.SCHEMA_PATH_XMLDSIG.toString()))
- grammar = getGrammarXMLDSig();
- else {
- getLogger().error("False schema path provided for encoding jaxbObject into EXI");
- return null;
- }
-
- InputStream inStream = marshalToInputStream(jaxbObject);
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- baos = ((ByteArrayOutputStream) encode(inStream, grammar));
-
- if (isHexAndBase64MsgRepresentation())
- showHexAndBase64RepresentationOfMessage(jaxbObject, baos.toByteArray());
-
- return baos.toByteArray();
- }
- private synchronized OutputStream encode(InputStream jaxbXML, Grammars grammar) {
- EXIResult exiResult = null;
-
- try {
- exiFactory.setGrammars(grammar);
- encodeOS = new ByteArrayOutputStream();
- exiResult = new EXIResult(exiFactory);
- exiResult.setOutputStream(encodeOS);
- XMLReader xmlReader = XMLReaderFactory.createXMLReader();
- xmlReader.setContentHandler(exiResult.getHandler());
- // parse xml file
- xmlReader.parse(new InputSource(jaxbXML));
-
- encodeOS.close();
- } catch (SAXException | IOException | EXIException e) {
- getLogger().error(e.getClass().getSimpleName() + " occurred while trying to encode", e);
- }
-
- return encodeOS;
- }
-
-
- @Override
- public synchronized Object decodeEXI(byte[] exiEncodedMessage, boolean supportedAppProtocolHandshake) {
- getLogger().debug("Received EXI stream: " + ByteUtils.toHexString(exiEncodedMessage));
-
- ByteArrayInputStream bais = new ByteArrayInputStream(exiEncodedMessage);
- setDecodedExi(decode(bais, supportedAppProtocolHandshake));
-
- return unmarshallToMessage(getDecodedExi());
- }
-
-
- private synchronized String decode(InputStream exiInputStream, boolean supportedAppProtocolHandshake) {
- TransformerFactory tf = TransformerFactory.newInstance();
- Transformer transformer = null;
- StringWriter stringWriter = new StringWriter();
- try {
- transformer = tf.newTransformer();
- } catch (TransformerConfigurationException e) {
- getLogger().error("Error occurred while trying to decode (TransformerConfigurationException)", e);
- }
-
- if (supportedAppProtocolHandshake) exiFactory.setGrammars(grammarAppProtocol);
- else exiFactory.setGrammars(grammarMsgDef);
-
- try {
- EXISource saxSource = new EXISource(exiFactory);
- SAXSource exiSource = new SAXSource(new InputSource(exiInputStream));
- XMLReader exiReader = saxSource.getXMLReader();
- exiSource.setXMLReader(exiReader);
- transformer.transform(exiSource, new StreamResult(stringWriter));
- } catch (EXIException e) {
- getLogger().error("Error occurred while trying to decode (EXIException)", e);
- } catch (TransformerException e) {
- getLogger().error("Error occurred while trying to decode (TransformerException)", e);
- }
-
- return stringWriter.toString();
- }
- private Grammars getGrammarAppProtocol() {
- return grammarAppProtocol;
- }
- private void setGrammarAppProtocol(Grammars grammarAppProtocol) {
- this.grammarAppProtocol = grammarAppProtocol;
- }
- private Grammars getGrammarMsgDef() {
- return grammarMsgDef;
- }
- private void setGrammarMsgDef(Grammars grammarMsgDef) {
- this.grammarMsgDef = grammarMsgDef;
- }
-
- public Grammars getGrammarXMLDSig() {
- return grammarXMLDSig;
- }
- public void setGrammarXMLDSig(Grammars grammarXMLDSig) {
- this.grammarXMLDSig = grammarXMLDSig;
- }
- public EXIFactory getExiFactory() {
- return exiFactory;
- }
- private void setExiFactory(EXIFactory exiFactory) {
- this.exiFactory = exiFactory;
- }
- @SuppressWarnings("unused")
- private GrammarFactory getGrammarFactory() {
- return grammarFactory;
- }
- private void setGrammarFactory(GrammarFactory grammarFactory) {
- this.grammarFactory = grammarFactory;
- }
-
- @Override
- public void setFragment(boolean useFragmentGrammar) {
- getExiFactory().setFragment(useFragmentGrammar);
- }
- }
|