/*
* Copyright (c) 1998 - 2005 Versant Corporation
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Versant Corporation - initial API and implementation
*/
package com.versant.core.jdo;
/**
* This keeps track of lists of LifecycleListener's for the different
* LifecycleEvent's. It implements a copy-on-write scheme so the lists on the
* PMF can be shared by all PMs until first modified. Any modification to
* a LifecycleListenerManager via add or remove will return a reference
* to a new LifecycleListenerManager with the change applied. If a
* LifecycleListenerManager becomes empty then null is returned.
*/
public class LifecycleListenerManager {
private PreStoreNode preStoreList;
private PostStoreNode postStoreList;
private DeleteNode deleteList;
/**
* Create new LifecycleListenerManager containinhg toAdd.
*/
public LifecycleListenerManager(LifecycleListener toAdd) {
addImp(toAdd);
}
/**
* Copy constructor.
*/
private LifecycleListenerManager(LifecycleListenerManager toCopy) {
preStoreList = toCopy.preStoreList == null ? null : toCopy.preStoreList.copy();
postStoreList = toCopy.postStoreList == null ? null : toCopy.postStoreList.copy();
deleteList = toCopy.deleteList == null ? null : toCopy.deleteList.copy();
}
/**
* Return a copy of this LifecycleListenerManager with l added.
*/
public LifecycleListenerManager add(LifecycleListener l) {
return new LifecycleListenerManager(this).addImp(l);
}
private LifecycleListenerManager addImp(LifecycleListener l) {
if (l instanceof PreStoreLifecycleListener) {
preStoreList = new PreStoreNode((PreStoreLifecycleListener)l, preStoreList);
}
if (l instanceof PostStoreLifecycleListener) {
postStoreList = new PostStoreNode((PostStoreLifecycleListener)l, postStoreList);
}
if (l instanceof DeleteLifecycleListener) {
deleteList = new DeleteNode((DeleteLifecycleListener)l, deleteList);
}
return this;
}
/**
* Return a copy of this LifecycleListenerManager with l removed or
* null if the resulting LifecycleListenerManager would contain no
* listeners.
*/
public LifecycleListenerManager remove(LifecycleListener l) {
return new LifecycleListenerManager(this).removeImp(l);
}
private LifecycleListenerManager removeImp(LifecycleListener l) {
if (l instanceof PreStoreLifecycleListener) {
PreStoreNode prev = null;
for (PreStoreNode i = preStoreList; i != null; i = i.next) {
if (i.listener == l) {
if (prev == null) {
preStoreList = i.next;
} else {
prev.next = i.next;
}
}
prev = i;
}
}
if (l instanceof DeleteLifecycleListener) {
DeleteNode prev = null;
for (DeleteNode i = deleteList; i != null; i = i.next) {
if (i.listener == l) {
if (prev == null) {
deleteList = i.next;
} else {
prev.next = i.next;
}
}
prev = i;
}
}
if (preStoreList == null && deleteList == null) {
return null;
}
return this;
}
/**
* Fire a preStore event returning true if there were any listeners.
*/
public boolean firePreStore(Object o) {
if (preStoreList == null) {
return false;
}
LifecycleEvent ev = new LifecycleEvent(o, LifecycleEvent.PRESTORE);
for (PreStoreNode i = preStoreList; i != null; i = i.next) {
i.listener.preStore(ev);
}
return true;
}
/**
* Fire a postStore event.
*/
public void firePostStore(Object o) {
if (postStoreList == null) {
return;
}
LifecycleEvent ev = new LifecycleEvent(o, LifecycleEvent.POSTSTORE);
for (PostStoreNode i = postStoreList; i != null; i = i.next) {
i.listener.postStore(ev);
}
}
/**
* Fire a delete event.
*/
public void fireDelete(Object o) {
if (deleteList == null) {
return;
}
LifecycleEvent ev = new LifecycleEvent(o, LifecycleEvent.DELETE);
for (DeleteNode i = deleteList; i != null; i = i.next) {
i.listener.delete(ev);
}
}
/**
* Do we have any postStore listeners?
*/
public boolean hasPostStoreListeners() {
return postStoreList != null;
}
private static class PreStoreNode {
public PreStoreLifecycleListener listener;
public PreStoreNode next;
public PreStoreNode(PreStoreLifecycleListener listener, PreStoreNode next) {
this.listener = listener;
this.next = next;
}
public PreStoreNode copy() {
return new PreStoreNode(listener, next == null ? null : next.copy());
}
}
private static class PostStoreNode {
public PostStoreLifecycleListener listener;
public PostStoreNode next;
public PostStoreNode(PostStoreLifecycleListener listener, PostStoreNode next) {
this.listener = listener;
this.next = next;
}
public PostStoreNode copy() {
return new PostStoreNode(listener, next == null ? null : next.copy());
}
}
private static class DeleteNode {
public DeleteLifecycleListener listener;
public DeleteNode next;
public DeleteNode(DeleteLifecycleListener listener, DeleteNode next) {
this.listener = listener;
this.next = next;
}
public DeleteNode copy() {
return new DeleteNode(listener, next == null ? null : next.copy());
}
}
}
|