/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.integration.regression;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import org.fudgemsg.FudgeContext;
import org.fudgemsg.FudgeMsg;
import org.fudgemsg.MutableFudgeMsg;
import org.fudgemsg.mapping.FudgeDeserializer;
import org.fudgemsg.mapping.FudgeSerializer;
import org.fudgemsg.wire.FudgeMsgReader;
import org.fudgemsg.wire.FudgeMsgWriter;
import org.fudgemsg.wire.xml.FudgeXMLStreamReader;
import org.fudgemsg.wire.xml.FudgeXMLStreamWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.opengamma.util.fudgemsg.OpenGammaFudgeContext;
import com.opengamma.util.xml.FormattingXmlStreamWriter;
/**
* Implementation of I/O using an XML representation of the Fudge binary encoding. Note that this is simply a human readable form of the Fudge binary data - as a result it is not as efficient or
* appear as natural as other XML representations which may be available.
*/
public class FudgeXMLFormat implements RegressionIO.Format {
/**
* The default file extension.
*/
/* package */static final String FILE_EXTENSION = ".xml";
private static final Logger s_logger = LoggerFactory.getLogger(FudgeXMLFormat.class);
private static final class Context {
private final FudgeContext _ctx;
private final FudgeSerializer _serializer;
private final FudgeDeserializer _deserializer;
private Context(final FudgeContext ctx, final FudgeSerializer write, final FudgeDeserializer read) {
_ctx = ctx;
_serializer = write;
_deserializer = read;
}
public static Context of(final FudgeContext ctx, final FudgeSerializer write, final FudgeDeserializer read) {
if ((write != null) || (read != null)) {
return new Context(ctx, write, read);
} else {
return null;
}
}
}
@Override
public Object openRead(final Object context) {
if (context == null) {
final FudgeContext ctx = OpenGammaFudgeContext.getInstance();
return new Context(ctx, null, new FudgeDeserializer(ctx));
} else {
final Context ctx = (Context) context;
assert ctx._deserializer == null;
return new Context(ctx._ctx, ctx._serializer, new FudgeDeserializer(ctx._ctx));
}
}
@Override
public Object openWrite(final Object context) {
if (context == null) {
final FudgeContext ctx = OpenGammaFudgeContext.getInstance();
return new Context(ctx, new FudgeSerializer(ctx), null);
} else {
final Context ctx = (Context) context;
assert ctx._serializer == null;
return new Context(ctx._ctx, new FudgeSerializer(ctx._ctx), ctx._deserializer);
}
}
@Override
public String getLogicalFileExtension(final Object context) {
return FILE_EXTENSION;
}
@Override
public void write(final Object context, final Object o, final OutputStream dest) throws IOException {
final Context ctx = (Context) context;
final Writer writer = new OutputStreamWriter(dest);
FormattingXmlStreamWriter xmlStreamWriter = FormattingXmlStreamWriter.builder(writer)
.indent(true)
.build();
final FudgeXMLStreamWriter streamWriter = new FudgeXMLStreamWriter(ctx._ctx, xmlStreamWriter);
// Don't close fudgeMsgWriter; the caller will close the stream later
@SuppressWarnings("resource")
FudgeMsgWriter fudgeMsgWriter = new FudgeMsgWriter(streamWriter);
MutableFudgeMsg msg = ctx._serializer.objectToFudgeMsg(o);
FudgeSerializer.addClassHeader(msg, o.getClass());
fudgeMsgWriter.writeMessage(msg);
fudgeMsgWriter.flush();
writer.append("\n");
s_logger.debug("Wrote object {}", o);
}
@Override
public Object read(final Object context, final InputStream in) throws IOException {
final Context ctx = (Context) context;
final Reader reader = new InputStreamReader(in);
FudgeXMLStreamReader streamReader = new FudgeXMLStreamReader(ctx._ctx, reader);
// Don't close fudgeMsgReader; the caller will close the stream later
@SuppressWarnings("resource")
FudgeMsgReader fudgeMsgReader = new FudgeMsgReader(streamReader);
FudgeMsg msg = fudgeMsgReader.nextMessage();
final Object object = ctx._deserializer.fudgeMsgToObject(msg);
s_logger.debug("Read object {}", object);
return object;
}
@Override
public Object closeRead(final Object context) {
final Context ctx = (Context) context;
assert ctx._deserializer != null;
return Context.of(ctx._ctx, ctx._serializer, null);
}
@Override
public Object closeWrite(final Object context) {
final Context ctx = (Context) context;
assert ctx._serializer != null;
return Context.of(ctx._ctx, null, ctx._deserializer);
}
}