package org.marketcetera.event.impl; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Date; import javax.annotation.concurrent.NotThreadSafe; import org.marketcetera.event.LogEvent; import org.marketcetera.event.LogEventLevel; import org.marketcetera.event.beans.EventBean; import org.marketcetera.event.beans.HasEventBean; import org.marketcetera.event.util.EventServices; import org.marketcetera.marketdata.DateUtils; import org.marketcetera.util.log.I18NBoundMessage; import org.marketcetera.util.log.I18NBoundMessage0P; import org.marketcetera.util.log.I18NBoundMessage1P; import org.marketcetera.util.log.I18NBoundMessage2P; import org.marketcetera.util.log.I18NBoundMessage3P; import org.marketcetera.util.log.I18NBoundMessage4P; import org.marketcetera.util.log.I18NBoundMessage5P; import org.marketcetera.util.log.I18NBoundMessage6P; import org.marketcetera.util.log.I18NBoundMessageNP; import org.marketcetera.util.log.I18NMessage; import org.marketcetera.util.log.I18NMessage0P; import org.marketcetera.util.log.I18NMessage1P; import org.marketcetera.util.log.I18NMessage2P; import org.marketcetera.util.log.I18NMessage3P; import org.marketcetera.util.log.I18NMessage4P; import org.marketcetera.util.log.I18NMessage5P; import org.marketcetera.util.log.I18NMessage6P; import org.marketcetera.util.log.I18NMessageNP; import org.marketcetera.util.misc.ClassVersion; import org.marketcetera.util.ws.wrappers.RemoteI18NBoundMessage; import org.marketcetera.util.ws.wrappers.RemoteProperties; /* $License$ */ /** * Implements {@link LogEvent}. * * <p>Note that this object is <em>not</em> thread-safe. * * @author <a href="mailto:colin@marketcetera.com">Colin DuPlantis</a> * @version $Id: LogEventImpl.java 16834 2014-02-13 20:40:53Z colin $ * @since 2.0.0 */ @NotThreadSafe @ClassVersion("$Id: LogEventImpl.java 16834 2014-02-13 20:40:53Z colin $") final class LogEventImpl implements LogEvent, HasEventBean { /* (non-Javadoc) * @see org.marketcetera.event.beans.HasEventBean#getEventBean() */ @Override public EventBean getEventBean() { return event; } /* (non-Javadoc) * @see org.marketcetera.event.LogEvent#getException() */ @Override public Throwable getException() { return exception; } /* (non-Javadoc) * @see org.marketcetera.event.LogEvent#getLevel() */ @Override public LogEventLevel getLevel() { return level; } /* (non-Javadoc) * @see org.marketcetera.event.LogEvent#getMessage() */ @Override public String getMessage() { if(serialized) { return boundMessage.getText(); } return getI18NBoundMessage().getText(); } /* (non-Javadoc) * @see org.marketcetera.event.Event#getMessageId() */ @Override public long getMessageId() { return event.getMessageId(); } /* (non-Javadoc) * @see org.marketcetera.event.Event#getSource() */ @Override public Object getSource() { return event.getSource(); } /* (non-Javadoc) * @see org.marketcetera.event.Event#getTimestamp() */ @Override public Date getTimestamp() { return event.getTimestamp(); } /* (non-Javadoc) * @see org.marketcetera.event.Event#setSource(java.lang.Object) */ @Override public void setSource(Object inSource) { event.setSource(inSource); } /* (non-Javadoc) * @see org.marketcetera.event.Event#getProvider() */ @Override public String getProvider() { return event.getProvider(); } /* (non-Javadoc) * @see org.marketcetera.event.Event#setProvider(java.lang.String) */ @Override public void setProvider(String inProvider) { event.setProvider(inProvider); } /* (non-Javadoc) * @see org.marketcetera.event.TimestampCarrier#getTimeMillis() */ @Override public long getTimeMillis() { return event.getTimeMillis(); } /* (non-Javadoc) * @see java.lang.Object#hashCode() */ @Override public final int hashCode() { return EventServices.eventHashCode(this); } /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public final boolean equals(Object obj) { return EventServices.eventEquals(this, obj); } /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public final String toString() { return String.format("%s %s event %s", //$NON-NLS-1$ DateUtils.dateToString(getTimestamp()), getLevel(), getMessage()); } /** * Create a new LogEventImpl instance. * * @param inEvent an <code>EventBean</code> value * @param inLevel a <code>LogEventLevel</code> value * @param inMessage an <code>I18NMessage</code> value * @param inException a <code>Throwable</code> value * @param inParameters a <code>Serializable...</code> value * @throws IllegalArgumentException if <code>MessageId</code> < 0 * @throws IllegalArgumentException if <code>Timestamp</code> is <code>null</code> * @throws IllegalArgumentException if <code>Level</code> is <code>null</code> */ LogEventImpl(EventBean inEvent, LogEventLevel inLevel, I18NMessage inMessage, Throwable inException, Serializable... inParameters) { event = EventBean.copy(inEvent); event.setDefaults(); event.validate(); if(inLevel == null) { EventServices.error(VALIDATION_NULL_LOG_LEVEL); } level = inLevel; message = inMessage; exception = inException; parameters = inParameters; } /** * Returns the bound event message. * * @return an <code>I18NBoundMessage</code> value * @throws IllegalStateException if the message takes an unexpected number of parameters */ private I18NBoundMessage getI18NBoundMessage() { switch(message.getParamCount()) { case -1: return new I18NBoundMessageNP((I18NMessageNP)message, parameters); case 0 : return new I18NBoundMessage0P((I18NMessage0P)message); case 1 : return new I18NBoundMessage1P((I18NMessage1P)message, parameters[0]); case 2 : return new I18NBoundMessage2P((I18NMessage2P)message, parameters[0], parameters[1]); case 3 : return new I18NBoundMessage3P((I18NMessage3P)message, parameters[0], parameters[1], parameters[2]); case 4 : return new I18NBoundMessage4P((I18NMessage4P)message, parameters[0], parameters[1], parameters[2], parameters[3]); case 5 : return new I18NBoundMessage5P((I18NMessage5P)message, parameters[0], parameters[1], parameters[2], parameters[3], parameters[4]); case 6 : return new I18NBoundMessage6P((I18NMessage6P)message, parameters[0], parameters[1], parameters[2], parameters[3], parameters[4], parameters[5]); } throw new IllegalStateException(); } /** * @serialData The <code>Level</code>, <code>exceptionInfo</code>, * and <code>boundMessage</code> are emitted. */ private void writeObject(ObjectOutputStream inStream) throws IOException { boundMessage = new RemoteI18NBoundMessage(getI18NBoundMessage()); exceptionInfo = new RemoteProperties(exception); inStream.defaultWriteObject(); } /** * Creates the object from a serialized stream. * * @param inStream an <code>ObjectInputStream</code> value * @throws IOException if an error occurs * @throws ClassNotFoundException if an error occurs */ private void readObject(ObjectInputStream inStream) throws IOException, ClassNotFoundException { inStream.defaultReadObject(); exception = exceptionInfo.getThrowable(); serialized = true; } /** * the event exception information or null valid only after serialization */ private RemoteProperties exceptionInfo; /** * the log level */ private final LogEventLevel level; /** * the bound event message valid only after serialization */ private RemoteI18NBoundMessage boundMessage; /** * the exception value or null, valid only before serialization */ private transient Throwable exception; /** * the unbound message, valid both before and after serialization */ private final transient I18NMessage message; /** * the event attributes */ private final EventBean event; /** * the message parameters, valid only before serialization */ private final transient Serializable[] parameters; /** * indicates whether the object has been serialized or not */ private transient boolean serialized = false; private static final long serialVersionUID = 1L; }