What I was suggesting as a potential approach (with the drawbacks mentioned), is the value of hashCode at the time of creation could be obtained and stored as a distinct member that would be be used to distinguish objects that are identical in value in all other respects.
That is replacing:
LoggingEvent() { ... synchronized(LoggingEvent.class) { sequenceNumber = sequenceCount++; } }
with
LoggingEvent() { ... eventID = super.hashCode(); }
I see. That could work quite well.
Two logging events that are identical in all other respects would have a high likelihood of having distinct values for eventID and acquiring the hash code would not incur an synchronization lock.
So, "all" you are suggesting is to replace
class LoggingEvent { long sequenceNumber; ...
LoggingEvent(...) { ... sequenceNumber = sequenceCount++; } }
with
class LoggingEvent { int eventID ; ...
LoggingEvent(...) { ... eventID = super.hashCode(); }
eventID replacing sequenceNumber. The existing implementations of equals() and hashCode() would remain the same. Correct?
I missed that most of the setters are protected by checks that they haven't been set previously. setSequenceNumber and setTimestamp don't have those protections. setRenderedMessage looks like it could be used to override the creation message if the original message hadn't been rendered.
I did an experiment by changing all the mutator classes to private access. The only thing that broke was PatternParserTest which used:
event = new LoggingEvent(); event.setLogger(logger); event.setTimeStamp(now); event.setLevel(Level.INFO); event.setMessage("msg 1");
to construct an LoggingEvent, changing it to:
event = new LoggingEvent(logger.getClass().toString(), logger, now, Level.INFO, "msg 1", null);
compiled and all tests passed.
On my side changing setLevel to private breaks the following:
EventDetailLayout.java log4j-1.3/src/java/org/apache/log4j/chainsaw/layout line 196
LayoutEditorPane.java log4j-1.3/src/java/org/apache/log4j/chainsaw/layout line 186
DBReceiverJob.java log4j-1.3/src/java/org/apache/log4j/db line 98
LogFilePatternReceiver.java log4j-1.3/src/java/org/apache/log4j/varia
UtilLoggingXMLDecoder.java log4j-1.3/src/java/org/apache/log4j/xml line 380
XMLDecoder.java log4j-1.3/src/java/org/apache/log4j/xml line 386
PatternParserTest.java log4j-1.3/tests/src/java/org/apache/log4j/pattern line 57
From that usage and your comments, it appears that your intent was not to allow filters to modify messages (which was my mistaken guess at the justification), but to provide an incremental "construction" mechanism instead of passing all the arguments in the constructor.
That is correct.
A much better approach to this would be to add a LoggingEventBuilder (or LoggingEventFactory) class that would serve the same role as StringBuffer does for String. The code in PatternParserTest would look like:
LoggingEventBuilder builder = new LoggingEventBuilder(); builder.setLogger(logger); builder.setTimeStamp(now); builder.setLevel(Level.INFO); builder.setMessage("msg 1"); LoggingEvent event = builder.newInstance();
Advantages of the approach:
Violations of invariants (like an LoggingEvent must have a level) can raise exceptions in the newInstance call. The other approach would allow you to pass a LoggingEvent without a level which would likely cause problems in the processing.
Good point.
Multiple objects that are slightly different can be created by repeated invocations of newInstance.
Yes? How so?
Member variables can be marked as final.
I assume that part of you motivation is to simplify the calling signatures of the constructors. Instead of a zero-parameter constructor, this pattern could be implemented with a one-parameter constructor.
public class LoggingEvent { public LoggingEvent(final LoggingEventBuilder builder) { ... } ... }
public class LoggingEventBuilder { public LoggingEvent newInstance() { return new LoggingEvent(builder); } }
This technique allows new fields to be added to the LoggingEvent without changing the signature of the LoggingEvent constructor.
Sounds good.
-- Ceki Gülcü
The complete log4j manual: http://www.qos.ch/log4j/
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]