![JAR search and dependency download from the Maven repository](/logo.png)
org.jpos.iso.packager.XMLPackager Maven / Gradle / Ivy
/*
* jPOS Project [http://jpos.org]
* Copyright (C) 2000-2016 Alejandro P. Revilla
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package org.jpos.iso.packager;
import org.jpos.iso.*;
import org.jpos.iso.header.BaseHeader;
import org.jpos.util.LogEvent;
import org.jpos.util.LogSource;
import org.jpos.util.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
import java.io.*;
import java.util.Stack;
/**
* packs/unpacks ISOMsgs into XML representation
*
* @author [email protected]
* @version $Id$
* @see ISOPackager
*/
@SuppressWarnings("unchecked")
public class XMLPackager extends DefaultHandler
implements ISOPackager, LogSource
{
protected Logger logger = null;
protected String realm = null;
private ByteArrayOutputStream out;
private PrintStream p;
private XMLReader reader = null;
private Stack stk;
public static final String ISOMSG_TAG = "isomsg";
public static final String ISOFIELD_TAG = "field";
public static final String ID_ATTR = "id";
public static final String VALUE_ATTR = "value";
public static final String TYPE_ATTR = "type";
public static final String TYPE_BINARY = "binary";
public static final String TYPE_BITMAP = "bitmap";
public static final String HEADER_TAG = "header";
public static final String ENCODING_ATTR = "encoding";
public static final String ASCII_ENCODING= "ascii";
public XMLPackager() throws ISOException {
super();
out = new ByteArrayOutputStream();
try {
p = new PrintStream(out, false, "utf-8");
} catch (UnsupportedEncodingException ignored) {
// utf-8 is a supported encoding
}
stk = new Stack();
try {
reader = createXMLReader();
} catch (Exception e) {
throw new ISOException (e.toString());
}
}
public byte[] pack (ISOComponent c) throws ISOException {
LogEvent evt = new LogEvent (this, "pack");
try {
if (!(c instanceof ISOMsg))
throw new ISOException ("cannot pack "+c.getClass());
ISOMsg m = (ISOMsg) c;
byte[] b;
synchronized (this) {
m.setDirection(0); // avoid "direction=xxxxxx" in XML msg
m.dump (p, "");
b = out.toByteArray();
out.reset();
}
if (logger != null)
evt.addMessage (m);
return b;
} catch (ISOException e) {
evt.addMessage (e);
throw e;
} finally {
Logger.log(evt);
}
}
public synchronized int unpack (ISOComponent c, byte[] b)
throws ISOException
{
LogEvent evt = new LogEvent (this, "unpack");
try {
if (!(c instanceof ISOMsg))
throw new ISOException
("Can't call packager on non Composite");
while (!stk.empty()) // purge from possible previous error
stk.pop();
InputSource src = new InputSource (new ByteArrayInputStream(b));
reader.parse (src);
if (stk.empty())
throw new ISOException ("error parsing");
ISOMsg m = (ISOMsg) c;
ISOMsg m1 = (ISOMsg) stk.pop();
m.merge (m1);
m.setHeader (m1.getHeader());
if (logger != null)
evt.addMessage (m);
return b.length;
} catch (ISOException e) {
evt.addMessage (e);
throw e;
} catch (IOException e) {
evt.addMessage (e);
throw new ISOException (e.toString());
} catch (SAXException e) {
evt.addMessage (e);
throw new ISOException (e.toString());
} finally {
Logger.log (evt);
}
}
public synchronized void unpack (ISOComponent c, InputStream in)
throws ISOException, IOException
{
LogEvent evt = new LogEvent (this, "unpack");
try {
if (!(c instanceof ISOMsg))
throw new ISOException
("Can't call packager on non Composite");
while (!stk.empty()) // purge from possible previous error
stk.pop();
reader.parse (new InputSource (in));
if (stk.empty())
throw new ISOException ("error parsing");
ISOMsg m = (ISOMsg) c;
ISOMsg m1 = (ISOMsg) stk.pop();
m.merge (m1);
m.setHeader (m1.getHeader());
if (logger != null)
evt.addMessage (m);
} catch (ISOException e) {
evt.addMessage (e);
throw e;
} catch (SAXException e) {
evt.addMessage (e);
throw new ISOException (e.toString());
} finally {
Logger.log (evt);
}
}
public void startElement
(String ns, String name, String qName, Attributes atts)
throws SAXException
{
int fieldNumber = -1;
try {
String id = atts.getValue(ID_ATTR);
if (id != null) {
try {
fieldNumber = Integer.parseInt (id);
} catch (NumberFormatException ignored) { }
}
if (name.equals (ISOMSG_TAG)) {
if (fieldNumber >= 0) {
if (stk.empty())
throw new SAXException ("inner without outter");
ISOMsg inner = new ISOMsg(fieldNumber);
((ISOMsg)stk.peek()).set (inner);
stk.push (inner);
} else {
stk.push (new ISOMsg(0));
}
} else if (name.equals (ISOFIELD_TAG)) {
ISOMsg m = (ISOMsg) stk.peek();
String value = atts.getValue(VALUE_ATTR);
String type = atts.getValue(TYPE_ATTR);
value = value == null ? "" : value;
if (id == null || value == null)
throw new SAXException ("invalid field");
ISOComponent ic;
if (TYPE_BINARY.equals (type)) {
ic = new ISOBinaryField (
fieldNumber,
ISOUtil.hex2byte (
value.getBytes(), 0, value.length()/2
)
);
}
else {
ic = new ISOField (fieldNumber, value);
}
m.set (ic);
stk.push (ic);
} else if (HEADER_TAG.equals (name)) {
BaseHeader bh = new BaseHeader();
bh.setAsciiEncoding (ASCII_ENCODING.equalsIgnoreCase(atts.getValue(ENCODING_ATTR)));
stk.push (bh);
}
} catch (ISOException e) {
throw new SAXException
("ISOException unpacking "+fieldNumber);
}
}
public void characters (char ch[], int start, int length) {
Object obj = stk.peek();
if (obj instanceof ISOField) {
ISOField f = (ISOField) obj;
String value = f.getValue() + new String(ch, start, length);
try {
f.setValue(value);
} catch (ISOException e) {
try {
f.setValue (e.getMessage());
} catch (ISOException ignored) {
// giving up
}
}
}
else if (obj instanceof BaseHeader) {
BaseHeader bh = (BaseHeader) obj;
String s = new String(ch,start,length);
if (bh.isAsciiEncoding()) {
bh.unpack (s.getBytes());
} else {
bh.unpack (ISOUtil.hex2byte (s));
}
}
}
public void endElement (String ns, String name, String qname)
throws SAXException
{
if (name.equals (ISOMSG_TAG)) {
ISOMsg m = (ISOMsg) stk.pop();
if (stk.empty())
stk.push (m); // push outter message
} else if (ISOFIELD_TAG.equals (name)) {
stk.pop();
} else if (HEADER_TAG.equals (name)) {
BaseHeader h = (BaseHeader) stk.pop();
ISOMsg m = (ISOMsg) stk.peek ();
m.setHeader (h);
}
}
public String getFieldDescription(ISOComponent m, int fldNumber) {
return " ";
}
public void setLogger (Logger logger, String realm) {
this.logger = logger;
this.realm = realm;
}
public String getRealm () {
return realm;
}
public Logger getLogger() {
return logger;
}
public ISOMsg createISOMsg () {
return new ISOMsg();
}
public String getDescription () {
return getClass().getName();
}
private XMLReader createXMLReader () throws SAXException {
XMLReader reader;
try {
reader = XMLReaderFactory.createXMLReader();
} catch (SAXException e) {
reader = XMLReaderFactory.createXMLReader (
System.getProperty(
"org.xml.sax.driver",
"org.apache.crimson.parser.XMLReaderImpl"
)
);
}
reader.setFeature ("http://xml.org/sax/features/validation",false);
reader.setContentHandler(this);
reader.setErrorHandler(this);
return reader;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy