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]

Reply via email to