package ecologylab.serialization.deserializers.pullhandlers;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.Charset;
import ecologylab.generic.Debug;
import ecologylab.net.ConnectionAdapter;
import ecologylab.net.PURLConnection;
import ecologylab.net.ParsedURL;
import ecologylab.serialization.DeserializationHookStrategy;
import ecologylab.serialization.FieldType;
import ecologylab.serialization.SIMPLTranslationException;
import ecologylab.serialization.SimplTypesScope;
import ecologylab.serialization.TranslationContext;
import ecologylab.serialization.deserializers.ISimplDeserializationIn;
import ecologylab.serialization.deserializers.ISimplDeserializationPost;
import ecologylab.serialization.deserializers.ISimplDeserializationPre;
import ecologylab.serialization.deserializers.pullhandlers.binaryformats.BinaryPullDeserializer;
import ecologylab.serialization.deserializers.pullhandlers.binaryformats.TLVPullDeserializer;
import ecologylab.serialization.deserializers.pullhandlers.stringformats.JSONPullDeserializer;
import ecologylab.serialization.deserializers.pullhandlers.stringformats.StringPullDeserializer;
import ecologylab.serialization.deserializers.pullhandlers.stringformats.XMLPullDeserializer;
import ecologylab.serialization.formatenums.BinaryFormat;
import ecologylab.serialization.formatenums.Format;
import ecologylab.serialization.formatenums.StringFormat;
public abstract class PullDeserializer extends Debug
{
protected SimplTypesScope translationScope;
protected TranslationContext translationContext;
protected DeserializationHookStrategy deserializationHookStrategy;
static final ConnectionAdapter connectionAdapter = new ConnectionAdapter();
/**
* Constructs that creates a JSON deserialization handler
*
* @param translationScope
* translation scope to use for de/serializing subsequent char sequences
* @param translationContext
* used for graph handling
*/
public PullDeserializer(SimplTypesScope translationScope, TranslationContext translationContext)
{
this.translationScope = translationScope;
this.translationContext = translationContext;
this.deserializationHookStrategy = null;
}
/**
* Constructs that creates a JSON deserialization handler
*
* @param translationScope
* translation scope to use for de/serializing subsequent char sequences
* @param translationContext
* used for graph handling
*/
public PullDeserializer(SimplTypesScope translationScope, TranslationContext translationContext,
DeserializationHookStrategy deserializationHookStrategy)
{
this.translationScope = translationScope;
this.translationContext = translationContext;
this.deserializationHookStrategy = deserializationHookStrategy;
}
/**
*
* @param file
* @return
* @throws SIMPLTranslationException
*/
public Object parse(File file) throws SIMPLTranslationException
{
try
{
FileInputStream fileInputStream = new FileInputStream(file);
BufferedInputStream bufferedStream = new BufferedInputStream(fileInputStream);
this.translationContext.setBaseDirFile(file.getParentFile());
Object object = parse(bufferedStream);
bufferedStream.close();
return object;
}
catch (FileNotFoundException e)
{
throw new SIMPLTranslationException("Can't open file " + file.getAbsolutePath(), e);
}
catch (IOException e)
{
throw new SIMPLTranslationException("Can't close file " + file.getAbsolutePath(), e);
}
}
/**
*
* @param purl
* @return
* @throws SIMPLTranslationException
*/
public Object parse(ParsedURL purl) throws SIMPLTranslationException
{
if (purl.isFile())
return parse(purl.file());
PURLConnection purlConnection = purl.connect(connectionAdapter);
Object result = parse(purlConnection.inputStream());
purlConnection.recycle();
return result;
}
/**
*
* @param url
* @return
* @throws SIMPLTranslationException
*/
public Object parse(URL url) throws SIMPLTranslationException
{
return parse(new ParsedURL(url));
}
/**
*
* @param inputStream
* @param charSet
* @return
* @throws SIMPLTranslationException
*/
public abstract Object parse(InputStream inputStream, Charset charSet)
throws SIMPLTranslationException;
/**
*
* @param inputStream
* @return
* @throws SIMPLTranslationException
*/
public abstract Object parse(InputStream inputStream) throws SIMPLTranslationException;
/**
*
* @param object
* @param translationContext
* TODO
*/
protected void deserializationPreHook(Object object, TranslationContext translationContext)
{
if (object instanceof ISimplDeserializationPre)
{
((ISimplDeserializationPre) object).deserializationPreHook(translationContext);
}
}
/**
*
* @param subRoot
* @param translationContext
*/
protected void deserializationInHook(Object object, TranslationContext translationContext)
{
if (object instanceof ISimplDeserializationIn)
{
((ISimplDeserializationIn) object).deserializationInHook(translationContext);
}
}
/**
*
* @param object
* @param translationContext
* TODO
*/
protected void deserializationPostHook(Object object, TranslationContext translationContext)
{
if (object instanceof ISimplDeserializationPost)
{
((ISimplDeserializationPost) object).deserializationPostHook(translationContext, object);
}
}
/**
*
* @param translationScope
* @param translationContext
* @param format
* @return
* @throws SIMPLTranslationException
*/
public static PullDeserializer getDeserializer(SimplTypesScope translationScope,
TranslationContext translationContext, Format format) throws SIMPLTranslationException
{
return getDeserializer(translationScope, translationContext, null, format);
}
/**
*
* @param translationScope
* @param translationContext
* @param deserializationHookStrategy
* @param format
* @return
* @throws SIMPLTranslationException
*/
public static PullDeserializer getDeserializer(SimplTypesScope translationScope,
TranslationContext translationContext,
DeserializationHookStrategy deserializationHookStrategy, Format format)
throws SIMPLTranslationException
{
switch (format)
{
case XML:
return new XMLPullDeserializer(translationScope,
translationContext, deserializationHookStrategy);
case JSON:
return new JSONPullDeserializer(translationScope, translationContext,
deserializationHookStrategy);
case TLV:
return new TLVPullDeserializer(translationScope, translationContext,
deserializationHookStrategy);
case BIBTEX:
// TODO bibtex pull deserializer not implemented!
// return new BibTeXPullDeserializer(translationScope, translationContext);
default:
throw new SIMPLTranslationException(format + " format not supported");
}
}
/**
*
* @param translationScope
* @param translationContext
* @param stringFormat
* @return
* @throws SIMPLTranslationException
*/
public static StringPullDeserializer getStringDeserializer(SimplTypesScope translationScope,
TranslationContext translationContext, StringFormat stringFormat)
throws SIMPLTranslationException
{
return getStringDeserializer(translationScope, translationContext, null, stringFormat);
}
/**
*
* @param translationScope
* @param translationContext
* @param deserializationHookStrategy
* @param stringFormat
* @return
* @throws SIMPLTranslationException
*/
public static StringPullDeserializer getStringDeserializer(SimplTypesScope translationScope,
TranslationContext translationContext,
DeserializationHookStrategy deserializationHookStrategy, StringFormat stringFormat)
throws SIMPLTranslationException
{
switch (stringFormat)
{
case XML:
return new XMLPullDeserializer(translationScope,
translationContext, deserializationHookStrategy);
case JSON:
return new JSONPullDeserializer(translationScope, translationContext,
deserializationHookStrategy);
case BIBTEX:
// TODO bibtex pull deserializer not implemented!
// return new BibTeXPullDeserializer(translationScope, translationContext);
default:
throw new SIMPLTranslationException(stringFormat + " format not supported");
}
}
/**
*
* @param translationScope
* @param translationContext
* @param binaryFormat
* @return
* @throws SIMPLTranslationException
*/
public static BinaryPullDeserializer getBinaryDeserializer(SimplTypesScope translationScope,
TranslationContext translationContext, BinaryFormat binaryFormat)
throws SIMPLTranslationException
{
return getBinaryDeserializer(translationScope, translationContext, null, binaryFormat);
}
/**
*
* @param translationScope
* @param translationContext
* @param deserializationHookStrategy
* @param binaryFormat
* @return
* @throws SIMPLTranslationException
*/
public static BinaryPullDeserializer getBinaryDeserializer(SimplTypesScope translationScope,
TranslationContext translationContext,
DeserializationHookStrategy deserializationHookStrategy, BinaryFormat binaryFormat)
throws SIMPLTranslationException
{
switch (binaryFormat)
{
case TLV:
default:
throw new SIMPLTranslationException(binaryFormat + " format not supported");
}
}
/**
* a state machine of deserialization states, e.g. now dealing with attributes or elements
*
* @param state
* @param fieldType
* @return
*/
protected DeserializationProcedureState nextDeserializationProcedureState(
DeserializationProcedureState state, FieldType fieldType)
{
// This is for backwards compat. Waiting to change this interface.
// TODO: Fix this.
FieldType ft = fieldType;
switch (ft)
{
case SCALAR:
if (state == DeserializationProcedureState.INIT)
state = DeserializationProcedureState.ATTRIBUTES;
// otherwise remain the same
break;
default:
if (state == DeserializationProcedureState.INIT || state == DeserializationProcedureState.ATTRIBUTES)
state = DeserializationProcedureState.ATTRIBUTES_DONE;
// otherwise remain the same
}
return state;
}
}