package com.google.code.joto.eventrecorder.impl; import java.io.DataInput; import java.io.DataInputStream; import java.io.DataOutput; import java.io.DataOutputStream; import java.io.Externalizable; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.OutputStream; import java.util.Date; import com.google.code.joto.eventrecorder.RecordEventSummary; import com.google.code.joto.util.io.CompressedObjectInputStream; import com.google.code.joto.util.io.CompressedObjectOutputStream; import com.google.code.joto.util.io.IdToObjectStreamClassCompressionContext; import com.google.code.joto.util.io.IdToStringMapCompressionContext; /** * internal helper class for encoding/decoding EventRecordSummary * in a contextual compressed way */ public class EventCompressionContext implements Externalizable { private IdToStringMapCompressionContext threadNameCtx = new IdToStringMapCompressionContext(); private IdToStringMapCompressionContext eventTypeCtx = new IdToStringMapCompressionContext(); private IdToStringMapCompressionContext eventSubTypeCtx = new IdToStringMapCompressionContext(); private IdToStringMapCompressionContext eventClassNameCtx = new IdToStringMapCompressionContext(); private IdToStringMapCompressionContext eventMethodNameCtx = new IdToStringMapCompressionContext(); // not compressed?? private IdToStringMapCompressionContext eventMethodDetail; private IdToObjectStreamClassCompressionContext objectStreamClassCtx = new IdToObjectStreamClassCompressionContext(); // ------------------------------------------------------------------------- public EventCompressionContext() { } //------------------------------------------------------------------------- public void encodeContextualRecordEventSummary(RecordEventSummary src, DataOutputStream out) throws IOException { // not encoded here... eventId; out.writeLong(src.getEventDate().getTime()); threadNameCtx.encodeContextualValue(src.getThreadName(), out); eventTypeCtx.encodeContextualValue(src.getEventType(), out); eventSubTypeCtx.encodeContextualValue(src.getEventSubType(), out); eventClassNameCtx.encodeContextualValue(src.getEventClassName(), out); eventMethodNameCtx.encodeContextualValue(src.getEventMethodName(), out); String eventMethodDetail = src.getEventMethodDetail(); out.writeBoolean(eventMethodDetail != null); if (eventMethodDetail != null) { out.writeUTF(eventMethodDetail); } // not encoded here... internalEventStoreDataAddress; } public RecordEventSummary decodeContextualRecordEventSummary( int eventId, DataInputStream in ) throws IOException { RecordEventSummary res = new RecordEventSummary(eventId); // not decoded here... eventId res.setEventDate(new Date(in.readLong())); res.setThreadName(threadNameCtx.decodeContextualValue(in)); res.setEventType(eventTypeCtx.decodeContextualValue(in)); res.setEventSubType(eventSubTypeCtx.decodeContextualValue(in)); res.setEventClassName(eventClassNameCtx.decodeContextualValue(in)); res.setEventMethodName(eventMethodNameCtx.decodeContextualValue(in)); boolean isEventMethodDetail = in.readBoolean(); if (isEventMethodDetail) { res.setEventMethodDetail(in.readUTF()); } // not decoded here... internalEventStoreDataAddress; return res; } // encode/decode for ObjectData // ------------------------------------------------------------------------- public void encodeContextualObjectData(Object objectData, OutputStream out) throws IOException { CompressedObjectOutputStream compObjOut = new CompressedObjectOutputStream(out, objectStreamClassCtx); compObjOut.writeObject(objectData); } public Object decodeContextualObjectData(InputStream in) throws IOException { Object res; try { CompressedObjectInputStream compObjIn = new CompressedObjectInputStream(in, objectStreamClassCtx); res = compObjIn.readObject(); } catch(ClassNotFoundException ex) { throw new IOException("failed to decode tmp compressed obj", ex); } return res; } // ------------------------------------------------------------------------- /** * implements java.io.Externalizable (optim for Serializable) * => used to encode self ... do not mismatch with encodeContextualValue! */ @Override public void writeExternal(ObjectOutput out) throws IOException { writeExternal2(out); } /** * implements java.io.Externalizable (optim for Serializable) * => used to decode self ... do not mismatch with decodeContextualValue! */ @Override public void readExternal(ObjectInput in) throws IOException { readExternal2(in); } /** * simpler than java.io.Externalizable: used DataOutput instead of ObjectOutput.. */ public void writeExternal2(DataOutput out) throws IOException { threadNameCtx.writeExternal2(out); eventTypeCtx.writeExternal2(out); eventSubTypeCtx.writeExternal2(out); eventClassNameCtx.writeExternal2(out); eventMethodNameCtx.writeExternal2(out); objectStreamClassCtx.writeExternal2(out); } /** * simpler than java.io.Externalizable: used DataInput instead of ObjectInput.. */ public void readExternal2(DataInput in) throws IOException { threadNameCtx.readExternal2(in); eventTypeCtx.readExternal2(in); eventSubTypeCtx.readExternal2(in); eventClassNameCtx.readExternal2(in); eventMethodNameCtx.readExternal2(in); objectStreamClassCtx.readExternal2(in); } public void clear() { threadNameCtx.clear(); eventTypeCtx.clear(); eventSubTypeCtx.clear(); eventClassNameCtx.clear(); eventMethodNameCtx.clear(); objectStreamClassCtx.clear(); } // override java.lang.Object / debugging helper // ------------------------------------------------------------------------- public String toStringSizes() { return "thread:" + threadNameCtx.toStringSize() + ", type:" + eventTypeCtx.toStringSize() + ", subType:" + eventSubTypeCtx.toStringSize() + ", className:" + eventClassNameCtx.toStringSize() + ", methodName:" + eventMethodNameCtx.toStringSize() + ", objectStreamClass:" + objectStreamClassCtx.toStringSize() + "]"; } @Override public String toString() { return "EventCompressionContext[sizes.." + toStringSizes() + "]"; } }