/*
* Copyright (c) 1990-2012 kopiLeft Development SARL, Bizerte, Tunisia
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id$
*/
package org.kopi.ebics.xml;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.xml.namespace.QName;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlError;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.kopi.ebics.exception.EbicsException;
import org.kopi.ebics.interfaces.EbicsRootElement;
import org.kopi.ebics.session.EbicsSession;
import org.kopi.ebics.session.OrderType;
public abstract class DefaultEbicsRootElement implements EbicsRootElement {
/**
* Constructs a new default <code>EbicsRootElement</code>
* @param session the current ebics session
*/
public DefaultEbicsRootElement(EbicsSession session) {
this.session = session;
suggestedPrefixes = new HashMap<String, String>();
}
/**
* Constructs a new default <code>EbicsRootElement</code>
*/
public DefaultEbicsRootElement() {
this(null);
}
/**
* Saves the Suggested Prefixes when the XML is printed
* @param uri the namespace URI
* @param prefix the namespace URI prefix
*/
protected static void setSaveSuggestedPrefixes(String uri, String prefix) {
suggestedPrefixes.put(uri, prefix);
}
/**
* Prints a pretty XML document using jdom framework.
* @param input the XML input
* @return the pretty XML document.
* @throws EbicsException pretty print fails
*/
public byte[] prettyPrint() throws EbicsException {
Document document;
XMLOutputter xmlOutputter;
SAXBuilder sxb;
ByteArrayOutputStream output;
sxb = new SAXBuilder();
output = new ByteArrayOutputStream();
xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
try {
document = sxb.build(new InputStreamReader(new ByteArrayInputStream(toByteArray()), "UTF-8"));
xmlOutputter.output(document, output);
} catch (JDOMException e) {
throw new EbicsException(e.getMessage());
} catch (IOException e) {
throw new EbicsException(e.getMessage());
}
return output.toByteArray();
}
/**
* Inserts a schema location to the current ebics root element.
* @param namespaceURI the name space URI
* @param localPart the local part
* @param prefix the prefix
* @param value the value
*/
public void insertSchemaLocation(String namespaceURI,
String localPart,
String prefix,
String value)
{
XmlCursor cursor;
cursor = document.newCursor();
while (cursor.hasNextToken()) {
if (cursor.isStart()) {
cursor.toNextToken();
cursor.insertAttributeWithValue(new QName(namespaceURI, localPart, prefix), value);
break;
} else {
cursor.toNextToken();
}
}
}
/**
* Generates a random file name with a prefix.
* @param type the order type.
* @return the generated file name.
*/
public static String generateName(OrderType type) {
return type.getOrderType() + new BigInteger(130, new SecureRandom()).toString(32);
}
/**
* Generates a random file name with a prefix.
* @param type the prefix to use.
* @return the generated file name.
*/
public static String generateName(String prefix) {
return prefix + new BigInteger(130, new SecureRandom()).toString(32);
}
@Override
public String toString() {
return new String(toByteArray());
}
@Override
public byte[] toByteArray() {
XmlOptions options;
options = new XmlOptions();
options.setSavePrettyPrint();
options.setSaveSuggestedPrefixes(suggestedPrefixes);
return document.xmlText(options).getBytes();
}
@Override
public void addNamespaceDecl(String prefix, String uri) {
XmlCursor cursor;
cursor = document.newCursor();
while (cursor.hasNextToken()) {
if (cursor.isStart()) {
cursor.toNextToken();
cursor.insertNamespace(prefix, uri);
break;
} else {
cursor.toNextToken();
}
}
}
@Override
public void validate() throws EbicsException {
ArrayList<XmlError> validationMessages;
boolean isValid;
validationMessages = new ArrayList<XmlError>();
isValid = document.validate(new XmlOptions().setErrorListener(validationMessages));
if (!isValid) {
String message;
Iterator<XmlError> iter;
iter = validationMessages.iterator();
message = "";
while (iter.hasNext()) {
if (!message.equals("")) {
message += ";";
}
message += iter.next().getMessage();
}
throw new EbicsException(message);
}
}
@Override
public void save(OutputStream out) throws EbicsException {
try {
byte[] element;
element = prettyPrint();
out.write(element);
out.flush();
out.close();
} catch (IOException e) {
throw new EbicsException(e.getMessage());
}
}
@Override
public void print(PrintStream stream) {
stream.println(document.toString());
}
// --------------------------------------------------------------------
// DATA MEMBERS
// --------------------------------------------------------------------
protected XmlObject document;
protected EbicsSession session;
private static Map<String, String> suggestedPrefixes;
private static final long serialVersionUID = -3928957097145095177L;
}