QJCC homepage

biz.chitec.quarterback.util
Class Logger

java.lang.Object
  extended bybiz.chitec.quarterback.util.Logger
Direct Known Subclasses:
TransactionLogger, UpdateableLogger

public class Logger
extends java.lang.Object

Basic logging object. Gets objects to "log" and handles them in a separate Thread. Main idea is simple: Objects to log are delivered through logObject(), and handled within handleLogObject(), which is executed in a seperate thread. Thread management and object locking is handled by the Logger object.

Implementation notes: This object uses some infrastructure which reminds to the ThreadInterface object. It doesn't use ThreadInterface internally only for historic reasons: In fact, Logger has been developed (shortly) before ThreadInterface.

Logger is fed through the logObject() methods. It knows three different working modes concerning how the object is sent to its origin. Of course, this makes only a difference if the origin actually is among the registered receivers:

By combining logObject() and logObjectToSenderOnly(), Logger offers a very straightforward way to send a special version of the logged object to its origin while all other receivers do another version. Loggers can be added with a LogicExpr. In this case, the LogicExpr is evaluated with the message as parameter for each receiver and the message is sent only if the expression evaluates the message to true. It is even possible that the same LoggingReceiver is added multiple times with different logical expressions. In this case, each expression is evaluated and the message is delivered if at least one evaluates to true. If a Logger is added multiple times with different logical expressions, each addition must be done with a reference object (e.g. the inserting instance). If the LoggingReceiver is lateron removed, the same reference object must be given again. The receiver is only removed completely if all references have been removed. You must not mix unconditional receiver addition and addition with a logical expression. Doing so leads to runtime exceptions. To perform a complete cleanup, emergencyRemoveReceiver(LoggingReceiver) can be used which removes the given receiver completely and regardsless of conditional or unconditional addition.

Version:
$Id: 480ae10fbf7d9ddc3829796abff1c7c46221f639 $
Author:
Dirk Hillbrecht 1997-1999, chitec/Dirk Hillbrecht 2000-2003, cantamen/Dirk Hillbrecht 2003-2008. Distributed under the terms of the GNU LGPL.
See Also:
ThreadInterface

Nested Class Summary
protected  class Logger.ChainElem
          Simple subclass: element of a simple linked list.
 
Field Summary
protected  Logger.ChainElem first
          leading element of the list.
protected  java.lang.Thread handleloophandler
          internally managed Thread for the handler
protected  java.util.List receiverexpr
          Logic expression to decide whether messages should be really passed to receiver at same index.
protected  java.util.List receivers
          All receivers of the messages
protected  boolean sleeping
          Description of the Field
protected  Logger.ChainElem worked
          actually handled element of the list.
 
Constructor Summary
Logger()
          Only constructor of the simple logger.
 
Method Summary
 boolean addReceiver(LoggingReceiver lr)
          Add a receiver unconditionally to this logger.
 boolean addReceiver(LoggingReceiver lr, java.lang.Object reference, LogicExpr sexpr)
          Add a receiver with a condition to this logger.
 boolean containsReceiver(LoggingReceiver lr)
          Returns whether a certain logging receiver has actually been added.
protected  void continueHandleLogObject(java.lang.Object o, LoggingReceiver sender, long ts, int seqnr, boolean tosenderonly)
          Generic logging event handler.
protected  void doSendInHandleLoop(java.lang.Object o, LoggingReceiver receiver, long ts, int seqnr)
          Send data to one receiver, Handle loop part.
protected  void doSendToReceiver(java.lang.Object o, LoggingReceiver receiver, long ts, int seqnr)
          Actually send data to one receiver.
 void emergencyRemoveReceiver(LoggingReceiver lr)
          Remove a logging receiver without taking care on logic expressions or unconditional checking.
private  boolean evaluateExpressions(int idx, java.lang.Object o)
          Evaluate the logical expression for a logging receiver.
protected  void handleLogObject(java.lang.Object o, LoggingReceiver sender, long ts, boolean tosenderonly)
          Top-level internal log object handling method.
 void handleloop()
          Main handling loop.
 void logObject(LoggingReceiver lr, java.lang.Object o)
          Delivers a new message object that has to be logged to all receivers except of the one given as parameter.
 void logObject(LoggingReceiver lr, java.lang.Object o, boolean tosenderonly)
          Deliveres a new message object either to all but the given receiver or to the given receiver only.
 void logObject(java.lang.Object o)
          Delivers a new message object that has to be logged to all receivers.
 void logObjectToSenderOnly(LoggingReceiver lr, java.lang.Object o)
          Convenience method for {@link #logObject(LoggingReceiver, Object, boolean) with third parameter set to true.
 boolean nothingToHandle()
          Checks whether the logger has something in the queue to log
 boolean removeReceiver(LoggingReceiver lr)
          Remove an unconditionally added receiver.
 boolean removeReceiver(LoggingReceiver lr, java.lang.Object reference)
          Remove a receiver which has been added with a logical expression as condition.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

first

protected Logger.ChainElem first
leading element of the list.


worked

protected Logger.ChainElem worked
actually handled element of the list.


handleloophandler

protected java.lang.Thread handleloophandler
internally managed Thread for the handler


receivers

protected java.util.List receivers
All receivers of the messages


receiverexpr

protected java.util.List receiverexpr
Logic expression to decide whether messages should be really passed to receiver at same index.


sleeping

protected boolean sleeping
Description of the Field

Constructor Detail

Logger

public Logger()
Only constructor of the simple logger. Chain is initialized and handling thread is started.

Method Detail

addReceiver

public boolean addReceiver(LoggingReceiver lr)
Add a receiver unconditionally to this logger. The receiver is informed about any messages passed through this logger until it is removed again. If the receiver has already been added, it is not added again and false is returned. Do not mixup this method with addReceiver(LoggingReceiver, Object, LogicExpr) on the same receiver. This will simply throw an exception.

Parameters:
lr - LoggingReceiver to receive the messages
Returns:
True if the receiver was actually added, false if not.

addReceiver

public boolean addReceiver(LoggingReceiver lr,
                           java.lang.Object reference,
                           LogicExpr sexpr)
Add a receiver with a condition to this logger. The receiver is added and for each message, the given condition is checked against the message. If the condition matches, the receiver gets the message, otherwise not. Addition is done with a reference object which must be given on removal, again. A typical reference object is the invoking instance of this method which is then also responsible for removing the receiver. The design is influenced by the GJSA infrastructure: A CommandExecutor adds its ServerThreadBase (via LoggerCenter) to the logger and later removes it. It passes itself as reference so that multiple executors can perform this addition without knowing from each other.

Parameters:
lr - LoggingReceiver to receive the messages
reference - Reference object which allows removal of this receiver lateron
sexpr - Logical expression which evaluates the message
Returns:
True if the receiver was actually added, false if not.

removeReceiver

public boolean removeReceiver(LoggingReceiver lr)
Remove an unconditionally added receiver. Do not use this method on receivers which have been added with a logical expression. It will throw an exception. Note that differently from removeReceiver(LoggingReceiver, Object), this method will not check whether the receiver has been added multiple times. Instead, it will simply be removed. If there are multiple adding instances for one receiver using this unconditional scheme, each has to evaluate the return value of addReceiver(LoggingReceiver) and only remove the receiver when it's time if that method returned true on addition.

Parameters:
lr - Receiver to remove.
Returns:
true if the receiver has actually been removed, false if not (e.g. because it has not been added in the beginning)

removeReceiver

public boolean removeReceiver(LoggingReceiver lr,
                              java.lang.Object reference)
Remove a receiver which has been added with a logical expression as condition. When performing such a removal, the reference object must be given again which has been passed before on the addition. The receiver will only be removed completely if all referencing objects have removed it.

Parameters:
lr -
reference -
Returns:

emergencyRemoveReceiver

public void emergencyRemoveReceiver(LoggingReceiver lr)
Remove a logging receiver without taking care on logic expressions or unconditional checking. The receiver and all of its logic expressions (if existing) are removed from the receiver list. This is kind of a "emergency exit" option if a receiver finally and definitely becomes inoperable (e.g. a ServerThreadBase handling a GJSA client which just closes the connection).

This method never fails.

Parameters:
lr - Logging receiver to remove from the receiver list

containsReceiver

public boolean containsReceiver(LoggingReceiver lr)
Returns whether a certain logging receiver has actually been added. The method does not look at logical expressions. It returns true regardless whether the receiver has been added conditionally or unconditionally.

Parameters:
lr - Logging receiver to check
Returns:
true if the given receiver has been added, false if not

handleloop

public void handleloop()
Main handling loop. This routine is executed in a separate thread. The routine tries to fetch a new element from the linked list (chain). It nothing is available, it wait()s. Doing this, no processor time is needed.


handleLogObject

protected void handleLogObject(java.lang.Object o,
                               LoggingReceiver sender,
                               long ts,
                               boolean tosenderonly)
Top-level internal log object handling method. This method is the main invocation point for passing messages to the logger. Its implementation in this class just redirects to continueHandleLogObject(Object, LoggingReceiver, long, int, boolean) to allow subclasses to hook into the process.

DO NOT USE THIS METHOD TO DELIVER SOMETHING TO LOG TO THE LOGGER!!! This is the internal handling method of the logger. For passing messages from a sender, use logObject(Object) and friends!

Parameters:
o - Message object to log
sender - Source for the logging, may be null.
ts - timestamp for UpdateableLogger
tosenderonly - Flag to force sending to sender itself only

continueHandleLogObject

protected void continueHandleLogObject(java.lang.Object o,
                                       LoggingReceiver sender,
                                       long ts,
                                       int seqnr,
                                       boolean tosenderonly)
Generic logging event handler. Separation from the visible handleLogObject(Object, LoggingReceiver, long, boolean) method is needed due to all the different logger types (TransactionLogger/UpdateableLogger).

Parameters:
o - Object to log
sender - Source for the logging object, may be null.
ts - Timestamp for UpdateableLogger
seqnr - Sequence counter for TransactionLogger
tosenderonly - Flag to force sending to sender itself only

evaluateExpressions

private boolean evaluateExpressions(int idx,
                                    java.lang.Object o)
Evaluate the logical expression for a logging receiver. A non-existing logical expression always evaluates to true. Otherwise, all logical expressions are evaluated and the method returns true if one of them evaluates to true (logical OR).

Parameters:
idx - Index of the receiver (and therefore the logical expression container) in the receiver list
o - Message to evaluate
Returns:
True if no expression exists or at least one of the expressions evaluate to true.

doSendInHandleLoop

protected void doSendInHandleLoop(java.lang.Object o,
                                  LoggingReceiver receiver,
                                  long ts,
                                  int seqnr)
Send data to one receiver, Handle loop part. In this implementation this method does nothing but calling doSendToReceiver(Object, LoggingReceiver, long, int). This can, however, be overwritten by the subclasses.

Parameters:
o - Message object to log
ts - timestamp for UpdateableLogger
seqnr - Sequence counter for TransactionLogger

doSendToReceiver

protected void doSendToReceiver(java.lang.Object o,
                                LoggingReceiver receiver,
                                long ts,
                                int seqnr)
Actually send data to one receiver.

Parameters:
o - Message object to log
ts - timestamp for UpdateableLogger
seqnr - Sequence counter for TransactionLogger

nothingToHandle

public boolean nothingToHandle()
Checks whether the logger has something in the queue to log

Returns:
True if no objects waits for being logged (and the logger therefore is idling), false if things are there to process.

logObject

public void logObject(java.lang.Object o)
Delivers a new message object that has to be logged to all receivers. The message to send is not passed immediately to the receivers. Instead, it is put into an internal queue which is handled by an internal thread. In that thread, actual message delivery takes place. This method itself returns immediately.

Parameters:
o - Message object to handle

logObject

public void logObject(LoggingReceiver lr,
                      java.lang.Object o)
Delivers a new message object that has to be logged to all receivers except of the one given as parameter. Typically, this method is used if the delivering message source is among the receivers of the logger and does not want to be informed itself about the message. In this case, the sender just passes itself as first parameter. Supression of this sending happens regardlessly of the logical expressions connected to this or any other receivers. Otherwise, this method works similar to logObject(Object).

Parameters:
lr - Receiver not to receive the message even if it is among the receivers and regardsless of its logical expression.
o - Message object to handle

logObject

public void logObject(LoggingReceiver lr,
                      java.lang.Object o,
                      boolean tosenderonly)
Deliveres a new message object either to all but the given receiver or to the given receiver only. Typically, this method is used if the delivering message source is among the receivers and wants on the one side noone but itself to become aware of the message while on the other side not to leave the usual delivery ways. In this case, the sender just passes itself as first parameter and a boolean flag as third parameter. Supression of this sending happens regardlessly of the logical expressions connected to this or any other receivers. Otherwise, this method works similar to logObject(Object). If tosenderonly is set to false, this method is the same as logObject(LoggingReceiver, Object).

Parameters:
lr - Receiver not to receive the message even if it is among the receivers and regardsless of its logical expression.
o - Message object to handle
tosenderonly - If true, send object only to given receiver. If false, send object to all but the given receiver.

logObjectToSenderOnly

public void logObjectToSenderOnly(LoggingReceiver lr,
                                  java.lang.Object o)
Convenience method for {@link #logObject(LoggingReceiver, Object, boolean) with third parameter set to true.

Parameters:
lr - Receiver to receive the message only if it is among the receivers and its logical expression matches.
o - Message object to handle

QJCC homepage