stefan 2004/07/07 09:04:06
Added: proposals/jcrri/src/org/apache/slide/jcr/core/state
TicketItemStateManager.java
Log:
jcrri
Revision Changes Path
1.1
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/state/TicketItemStateManager.java
Index: TicketItemStateManager.java
===================================================================
/*
* $Id: TicketItemStateManager.java,v 1.1 2004/07/07 16:04:06 stefan Exp $
*
* Copyright 2002-2004 Day Management AG, Switzerland.
*
* Licensed under the Day RI License, Version 2.0 (the "License"),
* as a reference implementation of the following specification:
*
* Content Repository API for Java Technology, revision 0.13
* <http://www.jcp.org/en/jsr/detail?id=170>
*
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License files at
*
* http://www.day.com/content/en/licenses/day-ri-license-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.slide.jcr.core.state;
import org.apache.log4j.Logger;
import org.apache.slide.jcr.core.*;
import javax.jcr.RepositoryException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* <code>TicketItemStateManager</code> ...
*
* @author Stefan Guggisberg
* @version $Revision: 1.1 $, $Date: 2004/07/07 16:04:06 $
*/
public class TicketItemStateManager implements ItemStateProvider {
private static Logger log = Logger.getLogger(TicketItemStateManager.class);
private final PersistentItemStateManager persistentStateMgr;
private final TransientItemStateManager transientStateMgr;
private final HierarchyManager hierMgr;
/**
* Creates a new <code>TicketItemStateManager</code> instance.
*
* @param rootNodeUUID
* @param persistentStateMgr
* @param nsResolver
*/
public TicketItemStateManager(String rootNodeUUID, PersistentItemStateManager
persistentStateMgr, NamespaceResolver nsResolver) {
this.persistentStateMgr = persistentStateMgr;
// create transient item state manager
transientStateMgr = new TransientItemStateManager();
// create hierarchy manager that uses both transient and persistent state
hierMgr = new HierarchyManagerImpl(rootNodeUUID, this, nsResolver);
}
static synchronized void collectDescendantItemStates(ItemId id, HierarchyManager
hierMgr, ItemStateProvider provider, List descendents) {
try {
if (id.denotesNode()) {
NodeId parentId = (NodeId) id;
ItemId[] childIds = hierMgr.listChildren(parentId);
for (int i = 0; i < childIds.length; i++) {
ItemId childId = childIds[i];
if (provider.hasItemState(childId)) {
descendents.add(provider.getItemState(childId));
}
// recurse
collectDescendantItemStates(childId, hierMgr, provider,
descendents);
}
// also add transient child nodes that have been unlinked from
// the specified parent node but are not orphaned yet (i.e.
// they are still linked to at least one other parent node)
if (provider.hasItemState(parentId)) {
NodeState parentState = (NodeState)
provider.getItemState(parentId);
Iterator iter =
parentState.getRemovedChildNodeEntries().iterator();
while (iter.hasNext()) {
// removed child nodes
NodeState.ChildNodeEntry cne = (NodeState.ChildNodeEntry)
iter.next();
NodeId removedChildId = new NodeId(cne.getUUID());
if (provider.hasItemState(removedChildId)) {
descendents.add(provider.getItemState(removedChildId));
}
}
}
}
} catch (ItemStateException ise) {
log.warn("inconsistent hierarchy state", ise);
} catch (RepositoryException re) {
log.warn("inconsistent hierarchy state", re);
}
}
static synchronized void collectDescendantItemStatesInAttic(ItemId id,
HierarchyManager hierMgr, ItemStateProvider provider, List descendents) {
try {
if (id.denotesNode()) {
NodeId parentId = (NodeId) id;
// traverse zombie children (i.e. children marked as removed)
ItemId[] childIds = hierMgr.listZombieChildren(parentId);
for (int i = 0; i < childIds.length; i++) {
ItemId childId = childIds[i];
// check attic
if (provider.hasItemStateInAttic(childId)) {
// found on attic, add to descendents list
descendents.add(provider.getItemStateInAttic(childId));
}
// recurse
collectDescendantItemStatesInAttic(childId, hierMgr, provider,
descendents);
}
// traverse existing children (because parentId might denote
// a node that was marked removed)
childIds = hierMgr.listChildren(parentId);
for (int i = 0; i < childIds.length; i++) {
ItemId childId = childIds[i];
// check attic
if (provider.hasItemStateInAttic(childId)) {
// found on attic, add to descendents list
descendents.add(provider.getItemStateInAttic(childId));
}
// recurse
collectDescendantItemStatesInAttic(childId, hierMgr, provider,
descendents);
}
}
} catch (ItemStateException ise) {
log.warn("inconsistent hierarchy state", ise);
} catch (RepositoryException re) {
log.warn("inconsistent hierarchy state", re);
}
}
/**
* Dumps the state of this <code>TransientItemStateManager</code> instance
* (used for diagnostic purposes).
*
* @param ps
*/
public void dump(PrintStream ps) {
ps.println("TicketItemStateManager (" + this + ")");
ps.println();
persistentStateMgr.dump(ps);
ps.println();
transientStateMgr.dump(ps);
ps.println();
}
/**
* Returns the hierarchy manager
*
* @return the hierarchy manager
*/
public HierarchyManager getHierarchyMgr() {
return hierMgr;
}
//----------------------------------------------------< ItemStateProvider >
/**
* @see ItemStateProvider#getItemState(ItemId)
*/
public ItemState getItemState(ItemId id)
throws NoSuchItemStateException, ItemStateException {
try {
// first check if there's transient state for the specified item
return transientStateMgr.getItemState(id);
} catch (NoSuchItemStateException nsise) {
// check if there's persistent state for the specified item
return persistentStateMgr.getItemState(id);
}
}
/**
* @see ItemStateProvider#hasItemState(ItemId)
*/
public boolean hasItemState(ItemId id) {
try {
getItemState(id);
return true;
} catch (ItemStateException ise) {
return false;
}
}
/**
* @see ItemStateProvider#getItemStateInAttic(ItemId)
*/
public ItemState getItemStateInAttic(ItemId id)
throws NoSuchItemStateException, ItemStateException {
return transientStateMgr.getItemStateInAttic(id);
}
/**
* @see ItemStateProvider#hasItemStateInAttic(ItemId)
*/
public boolean hasItemStateInAttic(ItemId id) {
try {
getItemStateInAttic(id);
return true;
} catch (ItemStateException ise) {
return false;
}
}
//< more methods for listing and retrieving transient ItemState instances >
/**
*
* @param id
* @return
* @throws NoSuchItemStateException
* @throws ItemStateException
*/
public ItemState getTransientItemState(ItemId id)
throws NoSuchItemStateException, ItemStateException {
return transientStateMgr.getItemState(id);
}
/**
* @return
*/
public boolean hasAnyTransientItemStates() {
return !transientStateMgr.isEmpty();
}
/**
* Returns an iterator over those transient item state instances that are
* direct or indirect descendents of the item state with the given
* <code>parentId</code>. The transient item state instance with the given
* <code>parentId</code> itself (if there is such) will not be included.
* <p/>
* The instances are returned in depth-first tree traversal order.
*
* @param parentId the id of the common parent of the transient item state
* instances to be returned.
* @return an iterator over descendant transient item state instances
*/
public Iterator getDescendantTransientItemStates(ItemId parentId) {
// @todo need a more efficient way to find descendents in cache (e.g. using
hierarchical index)
ArrayList descendents = new ArrayList();
collectDescendantItemStates(parentId, hierMgr, transientStateMgr, descendents);
return Collections.unmodifiableList(descendents).iterator();
}
/**
* Same as <code>[EMAIL PROTECTED]
#getDescendantTransientItemStates(ItemId)}</code>
* except that item state instances in the attic are returned.
*
* @param parentId the id of the common parent of the transient item state
* instances to be returned.
* @return an iterator over descendant transient item state instances in the
attic
*/
public Iterator getDescendantTransientItemStatesInAttic(ItemId parentId) {
// @todo need a more efficient way to find descendents in attic (e.g. using
hierarchical index)
ArrayList descendents = new ArrayList();
collectDescendantItemStatesInAttic(parentId, hierMgr, transientStateMgr,
descendents);
return Collections.unmodifiableList(descendents).iterator();
}
//------< methods for creating & discarding transient ItemState instances >
/**
* @param uuid
* @param nodeTypeName
* @param parentUUID
* @param initialStatus
* @return
* @throws ItemStateException
*/
public NodeState createTransientNodeState(String uuid, QName nodeTypeName,
String parentUUID, int initialStatus)
throws ItemStateException {
return transientStateMgr.createNodeState(uuid, nodeTypeName, parentUUID,
initialStatus);
}
/**
* @param overlayedState
* @param initialStatus
* @return
* @throws ItemStateException
*/
public NodeState createTransientNodeState(NodeState overlayedState, int
initialStatus)
throws ItemStateException {
return transientStateMgr.createNodeState(overlayedState, initialStatus);
}
/**
* @param parentUUID
* @param propName
* @param initialStatus
* @return
* @throws ItemStateException
*/
public PropertyState createTransientPropertyState(String parentUUID, QName
propName, int initialStatus)
throws ItemStateException {
return transientStateMgr.createPropertyState(parentUUID, propName,
initialStatus);
}
/**
* @param overlayedState
* @param initialStatus
* @return
* @throws ItemStateException
*/
public PropertyState createTransientPropertyState(PropertyState overlayedState,
int initialStatus)
throws ItemStateException {
return transientStateMgr.createPropertyState(overlayedState, initialStatus);
}
/**
* Disposes the specified transient item state instance, i.e. discards it
* and clears it from cache.
*
* @param state the transient <code>ItemState</code> instance that should
* be disposed
* @see ItemState#discard()
*/
public void disposeTransientItemState(ItemState state) {
transientStateMgr.disposeItemState(state);
}
/**
* Transfers the specified transient item state instance from the 'active'
* cache to the attic.
*
* @param state the transient <code>ItemState</code> instance that should
* be moved to the attic
*/
public void moveTransientItemStateToAttic(ItemState state) {
transientStateMgr.moveItemStateToAttic(state);
}
/**
* Disposes the specified transient item state instance in the attic, i.e.
* discards it and removes it from the attic.
*
* @param state the transient <code>ItemState</code> instance that should
* be disposed @see ItemState#discard()
*/
public void disposeTransientItemStateInAttic(ItemState state) {
transientStateMgr.disposeItemStateInAttic(state);
}
/**
* Disposes all transient item states in the cache and in the attic.
*/
public void disposeAllTransientItemStates() {
transientStateMgr.disposeAllItemStates();
}
//------------------< methods for creating persistent ItemState instances >
/**
* Creates a <code>PersistentNodeState</code> instance representing new,
* i.e. not yet existing state. Call <code>[EMAIL PROTECTED]
PersistentNodeState#store()}</code>
* on the returned object to make it persistent.
*
* @param uuid
* @param nodeTypeName
* @param parentUUID
* @return
* @throws ItemStateException
*/
public synchronized PersistentNodeState createPersistentNodeState(String uuid,
QName nodeTypeName, String parentUUID)
throws ItemStateException {
return persistentStateMgr.createNodeState(uuid, nodeTypeName, parentUUID);
}
/**
* Creates a <code>PersistentPropertyState</code> instance representing new,
* i.e. not yet existing state. Call <code>[EMAIL PROTECTED]
PersistentPropertyState#store()}</code>
* on the returned object to make it persistent.
*
* @param parentUUID
* @param propName
* @return
* @throws ItemStateException
*/
public PersistentPropertyState createPersistentPropertyState(String parentUUID,
QName propName)
throws ItemStateException {
return persistentStateMgr.createPropertyState(parentUUID, propName);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]