SessionListener.java
/*
** Module : SessionListener.java
** Abstract : Interface for objects interested in session life cycle events
**
** Copyright (c) 2004-2017, Golden Code Development Corporation.
**
** -#- -I- --Date-- --JPRM-- ----------------------------Description-----------------------------
** 001 ECF 20060901 @30523 Created initial version. Interface for
** objects interested in receiving Hibernate
** session life cycle events (initially only a
** session closing event is supported).
** 002 ECF 20070602 @33928 Added new scope constants. GLOBAL_SCOPE and
** NO_SCOPE.
** 003 ECF 20070706 @34404 Added deregisteredSessionListener() to API.
** Provides a notification to listener when it is
** deregistered.
** 004 ECF 20090810 @43592 Refactored API to support arbitrary event types.
** Replaced sessionClosing() with sessionEvent().
** Added public enums for event types and scope of
** registration.
** 005 ECF 20160409 Added SESSION_CLEANUP event type.
*/
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
**
** Additional terms under GNU Affero GPL version 3 section 7:
**
** Under Section 7 of the GNU Affero GPL version 3, the following additional
** terms apply to the works covered under the License. These additional terms
** are non-permissive additional terms allowed under Section 7 of the GNU
** Affero GPL version 3 and may not be removed by you.
**
** 0. Attribution Requirement.
**
** You must preserve all legal notices or author attributions in the covered
** work or Appropriate Legal Notices displayed by works containing the covered
** work. You may not remove from the covered work any author or developer
** credit already included within the covered work.
**
** 1. No License To Use Trademarks.
**
** This license does not grant any license or rights to use the trademarks
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
** of Golden Code Development Corporation. You are not authorized to use the
** name Golden Code, FWD, or the names of any author or contributor, for
** publicity purposes without written authorization.
**
** 2. No Misrepresentation of Affiliation.
**
** You may not represent yourself as Golden Code Development Corporation or FWD.
**
** You may not represent yourself for publicity purposes as associated with
** Golden Code Development Corporation, FWD, or any author or contributor to
** the covered work, without written authorization.
**
** 3. No Misrepresentation of Source or Origin.
**
** You may not represent the covered work as solely your work. All modified
** versions of the covered work must be marked in a reasonable way to make it
** clear that the modified work is not originating from Golden Code Development
** Corporation or FWD. All modified versions must contain the notices of
** attribution required in this license.
*/
package com.goldencode.p2j.persist.event;
import com.goldencode.p2j.persist.*;
/**
* Implemented by classes whose instances need to know about session life
* cycle events as they happen.
* <p>
* The following events generate notifications:
* <ul>
* <li>TRANSACTION_COMMITTING - the current database-level transaction is
* about to be committed.</li>
* <li>SESSION_CLOSING_NORMALLY - the current Hibernate session is about to
* be closed due to normal processing (no error).</li>
* <li>SESSION_CLOSING_WITH_ERROR - the current Hibernate session is about
* to be closed due to an error.</li>
* </ul>
* <p>
* <code>SessionListener</code> instances are registered with the {@link
* Persistence} class. They are not explicitly deregistered, but rather are
* implicitly deregistered at the end of a specific scope (or possibly
* earlier -- see below). A listener's scope is determined at registration
* time using one of the following <code>Scope</code> types.
* <ul>
* <li>NONE - the listener is never deregistered and survives until the end
* of the client context.
* <li>GLOBAL - deregister the listener when the context's global scope
* ends. This corresponds with the end of the user session.
* <li>ENCLOSING_EXTERNAL - deregister the listener when the current,
* external scope ends. This corresponds to the enclosing, external
* procedure scope in Progress.
* <li>CURRENT - deregister the listener when the current block scope ends.
* <li>NEXT_EXTERNAL - deregister the listener when the next external scope
* to be opened ends. This corresponds to an external procedure in
* Progress, but not one we currently are in. Care must be taken when
* using this scope; it presumes that the next external scope to be
* opened actually corresponds with the life cycle of the listener.
* The idiom with which this usage typically corresponds is the
* construction of a business logic object, followed by the immediate
* invocation of its primary entry point method (usually called
* <code>execute</code>). This is meant to support listener objects
* which are constructed as instance members of the business logic
* object. We can get into trouble if some other, external scope is
* opened between the construction of our business logic object and the
* invocation of its <code>execute()</code> method. This will not
* happen in converted code, but it is possible in hand-written code.
* </ul>
* <p>
* There are two ways a session listener may be deregistered earlier than at
* end of the scopes described above:
* <ul>
* <li>If the listener object is no longer referenced by business logic, it
* may be collected at any time by the garbage collector.
* <li>If the listener's {@link #sessionEvent} method returns
* <code>true</code>, the listener is deregistered immediately after
* this method returns.
* </ul>
*/
public interface SessionListener
{
/** Type of session event */
public enum Event
{
/** Transaction is about to be committed */
TRANSACTION_COMMITTING,
/** Session is not closing, but requires cleanup */
SESSION_CLEANUP,
/** Session is about to close normally */
SESSION_CLOSING_NORMALLY,
/** Session is about to close due to an error */
SESSION_CLOSING_WITH_ERROR,
};
/** Scope of listener registration */
public enum Scope
{
/** Never deregister the session listener */
NONE,
/** Scope listener registration to context's global scope */
GLOBAL,
/** Scope listener registration to enclosing external block scope */
ENCLOSING_EXTERNAL,
/** Scope listener registration to current block scope */
CURRENT,
/** Scope listener registration to next (lower) external block scope */
NEXT_EXTERNAL,
};
/**
* Invoked when a significant event occurs related to the current Hibernate
* session or transaction.
*
* @param event
* Type of event.
*
* @return <code>true</code> if this listener should be removed from the
* current set of registered listeners; <code>false</code> to
* remain registered.
*
* @throws PersistenceException
* if any error occurs during the implementor's processing of the
* given event. If this exception is thrown, the listener will be
* deregistered as if <code>true</code> had been returned.
*/
public boolean sessionEvent(Event event)
throws PersistenceException;
/**
* Invoked when a session listener is removed from the list of registered
* session listeners. This method is invoked due to deregistration at the
* end of the associated scope and after {@link
* #sessionEvent(com.goldencode.p2j.persist.event.SessionListener.Event)}
* is invoked and returns <code>true</code>. It is <i>not</i> invoked when
* deregistration occurs due to garbage collection, since the listener is
* not in a position to do anything useful at that point anyway, and is no
* longer referenced by business logic.
*/
public void deregisteredSessionListener();
}