/***************************************************************************
* Copyright (C) 2010-2011 by Fabrizio Montesi <famontesi@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Library General Public License as *
* published by the Free Software Foundation; either version 2 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 General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
* For details about the authors of this software, see the AUTHORS file. *
***************************************************************************/
package joliex.storage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Writer;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import jolie.runtime.AndJarDeps;
import jolie.runtime.FaultException;
import jolie.runtime.Value;
import jolie.runtime.embedding.RequestResponse;
import joliex.storage.types.LoadRequest;
import joliex.storage.types.SaveRequest;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
/**
*
* @author Fabrizio Montesi
*/
@AndJarDeps({"jolie-xml.jar"})
public class XmlStorage extends AbstractStorageService
{
private File xmlFile = null;
private final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
private final TransformerFactory transformerFactory = TransformerFactory.newInstance();
public XmlStorage()
{
documentBuilderFactory.setIgnoringElementContentWhitespace( true );
}
@RequestResponse
public void connect( Value request )
throws FaultException
{
try {
xmlFile = new File( request.getFirstChild( "filename" ).strValue() );
if ( xmlFile.exists() == false ) {
xmlFile.createNewFile();
valueToFile( Value.create() );
}
} catch( Exception e ) {
throw new FaultException( "StorageFault", e.getMessage() );
}
}
private Value valueFromFile()
throws FaultException
{
Value value = Value.create();
try {
InputStream istream = new FileInputStream( xmlFile );
DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
InputSource src = new InputSource( new InputStreamReader( istream ) );
Document doc = builder.parse( src );
jolie.xml.XmlUtils.documentToValue( doc, value );
} catch( Exception e ) {
throw new FaultException( "StorageFault", e.getMessage() );
}
return value;
}
private void valueToFile( Value value )
throws FaultException
{
try {
DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
Document doc = builder.newDocument();
jolie.xml.XmlUtils.valueToDocument( value, "storage", doc );
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
Writer writer = new FileWriter( xmlFile );
StreamResult result = new StreamResult( writer );
transformer.transform( new DOMSource( doc ), result );
} catch( Exception e ) {
throw new FaultException( "StorageFault", e.getMessage() );
}
}
private void checkConnection()
throws IOException
{
if ( xmlFile == null ) {
throw new IOException( "XML file not specified (maybe you forgot to call connect?)" );
}
}
public Value load( LoadRequest request )
throws FaultException
{
try {
checkConnection();
Value value = valueFromFile();
return value;
} catch( IOException e ) {
throw new FaultException( "StorageFault", e.getMessage() );
}
}
@RequestResponse
public void save( SaveRequest request )
throws FaultException
{
try {
checkConnection();
valueToFile( request.value() );
} catch( IOException e ) {
throw new FaultException( "StorageFault", e.getMessage() );
}
}
}