package de.unisiegen.gtitool.ui.storage;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.Charset;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import de.unisiegen.gtitool.core.exceptions.alphabet.AlphabetException;
import de.unisiegen.gtitool.core.exceptions.state.StateException;
import de.unisiegen.gtitool.core.exceptions.symbol.SymbolException;
import de.unisiegen.gtitool.core.exceptions.transition.TransitionException;
import de.unisiegen.gtitool.core.i18n.Messages;
import de.unisiegen.gtitool.core.storage.Attribute;
import de.unisiegen.gtitool.core.storage.Element;
import de.unisiegen.gtitool.core.storage.Storable;
import de.unisiegen.gtitool.core.storage.exceptions.StoreException;
import de.unisiegen.gtitool.ui.model.DefaultGrammarModel;
import de.unisiegen.gtitool.ui.model.DefaultMachineModel;
import de.unisiegen.gtitool.ui.model.DefaultRegexModel;
/**
* The {@link Storage} class.
*
* @author Christian Fehler
* @version $Id$
*/
public final class Storage
{
/**
* The single instance of the {@link Storage}.
*/
private static Storage singleStorage;
/**
* The name of a supported {@link Charset}.
*/
private static final String CHARSET_NAME = "UTF8"; //$NON-NLS-1$
/**
* The debug flag.
*/
private static final boolean DEBUG = true;
/**
* Returns the single instance of the {@link Storage}.
*
* @return The single instance of the {@link Storage}.
*/
public final static Storage getInstance ()
{
if ( singleStorage == null )
{
singleStorage = new Storage ();
}
return singleStorage;
}
/**
* The used
*/
private BufferedWriter writer;
/**
* Allocates a new {@link Storage}.
*/
private Storage ()
{
// Do nothing
}
/**
* Returns the {@link Element}.
*
* @param node The input {@link Node}.
* @return The {@link Element}.
*/
private final Element getElement ( Node node )
{
Element newElement = new Element ( node.getNodeName () );
if ( node.getAttributes () != null )
{
for ( int i = 0 ; i < node.getAttributes ().getLength () ; i++ )
{
Node current = node.getAttributes ().item ( i );
if ( current.getNodeType () == Node.ATTRIBUTE_NODE )
{
newElement.addAttribute ( new Attribute ( current.getNodeName (),
current.getNodeValue () ) );
}
}
}
if ( node.getChildNodes () != null )
{
for ( int i = 0 ; i < node.getChildNodes ().getLength () ; i++ )
{
Node current = node.getChildNodes ().item ( i );
if ( current.getNodeType () == Node.ELEMENT_NODE )
{
newElement.addElement ( getElement ( current ) );
}
}
}
return newElement;
}
/**
* Loads the {@link Storable} from the given file name.
*
* @param file The {@link File}.
* @return The {@link Storable} from the given file name.
* @throws StoreException If the file could not be loaded.
*/
public final Storable load ( File file ) throws StoreException
{
try
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance ();
DocumentBuilder builder = factory.newDocumentBuilder ();
Document document = builder.parse ( file );
Element element = getElement ( document.getDocumentElement () );
if ( element.getName ().equals ( "MachineModel" ) ) //$NON-NLS-1$
{
return new DefaultMachineModel ( element, null );
}
if ( element.getName ().equals ( "GrammarModel" ) ) //$NON-NLS-1$
{
return new DefaultGrammarModel ( element, null );
}
if ( element.getName ().equals ( "RegexModel" ) ) //$NON-NLS-1$
{
return new DefaultRegexModel ( element, false );
}
throw new StoreException ( Messages.getString ( "StoreException.Readed" ) ); //$NON-NLS-1$
}
catch ( ParserConfigurationException exc )
{
if ( DEBUG )
{
exc.printStackTrace ();
}
throw new StoreException ( Messages.getString ( "StoreException.Parse" ) ); //$NON-NLS-1$
}
catch ( SAXException exc )
{
if ( DEBUG )
{
exc.printStackTrace ();
}
throw new StoreException ( Messages.getString ( "StoreException.Parse" ) ); //$NON-NLS-1$
}
catch ( IOException exc )
{
if ( DEBUG )
{
exc.printStackTrace ();
}
throw new StoreException ( Messages.getString ( "StoreException.Readed" ) ); //$NON-NLS-1$
}
catch ( Exception exc )
{
if ( DEBUG )
{
exc.printStackTrace ();
}
Throwable exception;
if ( exc instanceof InvocationTargetException )
{
exception = exc.getCause ();
}
else
{
exception = exc;
}
if ( exception instanceof StoreException )
{
throw ( StoreException ) exception;
}
if ( exception instanceof AlphabetException )
{
throw new StoreException ( ( ( AlphabetException ) exception )
.getPrettyDescription ().toString () );
}
if ( exception instanceof SymbolException )
{
throw new StoreException ( ( ( SymbolException ) exception )
.getPrettyDescription ().toString () );
}
if ( exception instanceof StateException )
{
throw new StoreException ( ( ( StateException ) exception )
.getPrettyDescription ().toString () );
}
if ( exception instanceof TransitionException )
{
throw new StoreException ( ( ( TransitionException ) exception )
.getPrettyDescription ().toString () );
}
throw new StoreException ( Messages.getString ( "StoreException.Readed" ) ); //$NON-NLS-1$
}
}
/**
* Loads the {@link Element} from the given text.
*
* @param text The text to parse.
* @return The {@link Element} from the text.
* @throws StoreException If the file could not be loaded.
*/
public final Element load ( String text ) throws StoreException
{
try
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance ();
DocumentBuilder builder = factory.newDocumentBuilder ();
byte bytes[] = text.getBytes ();
ByteArrayInputStream inputStream = new ByteArrayInputStream ( bytes );
Document document = builder.parse ( inputStream );
return getElement ( document.getDocumentElement () );
}
catch ( ParserConfigurationException exc )
{
if ( DEBUG )
{
exc.printStackTrace ();
}
throw new StoreException ( Messages.getString ( "StoreException.Parse" ) ); //$NON-NLS-1$
}
catch ( SAXException exc )
{
if ( DEBUG )
{
exc.printStackTrace ();
}
throw new StoreException ( Messages.getString ( "StoreException.Parse" ) ); //$NON-NLS-1$
}
catch ( IOException exc )
{
if ( DEBUG )
{
exc.printStackTrace ();
}
throw new StoreException ( Messages.getString ( "StoreException.Readed" ) ); //$NON-NLS-1$
}
catch ( Exception exc )
{
if ( DEBUG )
{
exc.printStackTrace ();
}
Throwable exception;
if ( exc instanceof InvocationTargetException )
{
exception = exc.getCause ();
}
else
{
exception = exc;
}
if ( exception instanceof StoreException )
{
throw ( StoreException ) exception;
}
if ( exception instanceof AlphabetException )
{
throw new StoreException ( ( ( AlphabetException ) exception )
.getPrettyDescription ().toString () );
}
if ( exception instanceof SymbolException )
{
throw new StoreException ( ( ( SymbolException ) exception )
.getPrettyDescription ().toString () );
}
if ( exception instanceof StateException )
{
throw new StoreException ( ( ( StateException ) exception )
.getPrettyDescription ().toString () );
}
if ( exception instanceof TransitionException )
{
throw new StoreException ( ( ( TransitionException ) exception )
.getPrettyDescription ().toString () );
}
throw new StoreException ( Messages.getString ( "StoreException.Readed" ) ); //$NON-NLS-1$
}
}
/**
* Stores the given {@link Storable} to the given file name.
*
* @param storable The {@link Storable} to store.
* @param file The used {@link File}.
* @throws StoreException If the file could not be loaded.
*/
public final void store ( Storable storable, File file )
throws StoreException
{
try
{
this.writer = new BufferedWriter ( new OutputStreamWriter (
new FileOutputStream ( file ), CHARSET_NAME ) );
this.writer.write ( storable.getElement ().getStoreString () );
this.writer.close ();
}
catch ( Exception exc )
{
if ( DEBUG )
{
exc.printStackTrace ();
}
throw new StoreException ( Messages.getString ( "StoreException.Store" ) ); //$NON-NLS-1$
}
}
}