shareditemstatemanager.java
来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 1,450 行 · 第 1/4 页
JAVA
1,450 行
return false; } //----------------------------------------------------< ItemStateListener > /** * {@inheritDoc} * <p/> * Notifications are received for items that this manager created itself or items that are * managed by one of the virtual providers. */ public void stateCreated(ItemState created) { if (created.getContainer() == this) { // shared state was created cache.cache(created); } dispatcher.notifyStateCreated(created); } /** * {@inheritDoc} * <p/> * Notifications are received for items that this manager created itself or items that are * managed by one of the virtual providers. */ public void stateModified(ItemState modified) { dispatcher.notifyStateModified(modified); } /** * {@inheritDoc} * <p/> * Notifications are received for items that this manager created itself or items that are * managed by one of the virtual providers. */ public void stateDestroyed(ItemState destroyed) { if (destroyed.getContainer() == this) { // shared state was destroyed cache.evict(destroyed.getId()); } dispatcher.notifyStateDestroyed(destroyed); } /** * {@inheritDoc} * <p/> * Notifications are received for items that this manager created itself or items that are * managed by one of the virtual providers. */ public void stateDiscarded(ItemState discarded) { if (discarded.getContainer() == this) { // shared state was discarded cache.evict(discarded.getId()); } dispatcher.notifyStateDiscarded(discarded); } //-------------------------------------------------------------< Dumpable > /** * {@inheritDoc} */ public void dump(PrintStream ps) { ps.println("SharedItemStateManager (" + this + ")"); ps.println(); ps.print("[referenceCache] "); cache.dump(ps); } //-------------------------------------------------< misc. public methods > /** * Disposes this <code>SharedItemStateManager</code> and frees resources. */ public void dispose() { // clear cache cache.evictAll(); } /** * Adds a new virtual item state provider.<p/> * NOTE: This method is not synchronized, because it is called right after * creation only by the same thread and therefore concurrency issues * do not occur. Should this ever change, the synchronization status * has to be re-examined. * * @param prov */ public void addVirtualItemStateProvider(VirtualItemStateProvider prov) { VirtualItemStateProvider[] provs = new VirtualItemStateProvider[virtualProviders.length + 1]; System.arraycopy(virtualProviders, 0, provs, 0, virtualProviders.length); provs[virtualProviders.length] = prov; virtualProviders = provs; prov.addListener(this); } /** * Object representing a single update operation. */ class Update implements org.apache.jackrabbit.core.cluster.Update { /** * Local change log. */ private final ChangeLog local; /** * Event state collection factory. */ private final EventStateCollectionFactory factory; /** * Virtual provider containing references to be left out when updating * references. */ private final VirtualItemStateProvider virtualProvider; /** * Shared change log. */ private ChangeLog shared; /** * Virtual node references. */ private List[] virtualNodeReferences; /** * Events to dispatch. */ private EventStateCollection events; /** * Flag indicating whether we are holding write lock. */ private boolean holdingWriteLock; /** * Map of attributes stored for this update operation. */ private HashMap attributes; /** * Create a new instance of this class. */ public Update(ChangeLog local, EventStateCollectionFactory factory, VirtualItemStateProvider virtualProvider) { this.local = local; this.factory = factory; this.virtualProvider = virtualProvider; } /** * Begin update operation. Prepares everything upto the point where * the persistence manager's <code>store</code> method may be invoked. * If this method succeeds, a write lock will have been acquired on the * item state manager and either {@link #end()} or {@link #cancel()} has * to be called in order to release it. */ public void begin() throws ItemStateException, ReferentialIntegrityException { shared = new ChangeLog(); virtualNodeReferences = new List[virtualProviders.length]; /* let listener know about change */ if (eventChannel != null) { eventChannel.updateCreated(this); } try { acquireWriteLock(); holdingWriteLock = true; } finally { if (!holdingWriteLock && eventChannel != null) { eventChannel.updateCancelled(this); } } boolean succeeded = false; try { if (usesReferences) { /** * Update node references based on modifications in change log * (added/modified/removed REFERENCE properties) */ updateReferences(local, virtualProvider); } /** * Check whether reference targets exist/were not removed */ checkReferentialIntegrity(local); /** * prepare the events. this needs to be after the referential * integrity check, since another transaction could have modified * the states. */ try { events = factory.createEventStateCollection(); } catch (RepositoryException e) { String msg = "Unable to create event state collection."; log.error(msg); throw new ItemStateException(msg, e); } /** * Reconnect all items contained in the change log to their * respective shared item and add the shared items to a * new change log. */ for (Iterator iter = local.modifiedStates(); iter.hasNext();) { ItemState state = (ItemState) iter.next(); state.connect(getItemState(state.getId())); if (state.isStale()) { boolean merged = false; if (state.isNode()) { NodeStateMerger.MergeContext context = new NodeStateMerger.MergeContext() { public boolean isAdded(ItemId id) { try { ItemState is = local.get(id); return is != null && is.getStatus() == ItemState.STATUS_NEW; } catch (NoSuchItemStateException e) { return false; } } public boolean isDeleted(ItemId id) { return local.deleted(id); } }; merged = NodeStateMerger.merge((NodeState) state, context); } if (!merged) { String msg = state.getId() + " has been modified externally"; log.debug(msg); throw new StaleItemStateException(msg); } // merge succeeded, fall through } // update modification count (will be persisted as well) state.getOverlayedState().touch(); shared.modified(state.getOverlayedState()); } for (Iterator iter = local.deletedStates(); iter.hasNext();) { ItemState state = (ItemState) iter.next(); state.connect(getItemState(state.getId())); if (state.isStale()) { String msg = state.getId() + " has been modified externally"; log.debug(msg); throw new StaleItemStateException(msg); } shared.deleted(state.getOverlayedState()); } for (Iterator iter = local.addedStates(); iter.hasNext();) { ItemState state = (ItemState) iter.next(); state.connect(createInstance(state)); shared.added(state.getOverlayedState()); } // filter out virtual node references for later processing // (see comment above) for (Iterator iter = local.modifiedRefs(); iter.hasNext();) { NodeReferences refs = (NodeReferences) iter.next(); boolean virtual = false; NodeId id = refs.getId().getTargetId(); for (int i = 0; i < virtualProviders.length; i++) { if (virtualProviders[i].hasItemState(id)) { List virtualRefs = virtualNodeReferences[i]; if (virtualRefs == null) { virtualRefs = new LinkedList(); virtualNodeReferences[i] = virtualRefs; } virtualRefs.add(refs); virtual = true; break; } } if (!virtual) { // if target of node reference does not lie in a virtual // space, add to modified set of normal provider. shared.modified(refs); } } /* create event states */ events.createEventStates(rootNodeId, local, SharedItemStateManager.this); /* let listener know about change */ if (eventChannel != null) { eventChannel.updatePrepared(this); } /* Push all changes from the local items to the shared items */ local.push(); succeeded = true; } finally { if (!succeeded) { cancel(); } } } /** * End update operation. This will store the changes to the associated * <code>PersistenceManager</code>. At the end of this operation, an * eventual read or write lock on the item state manager will have * been released. * @throws ItemStateException if some error occurs */ public void end() throws ItemStateException { boolean succeeded = false; try { /* Store items in the underlying persistence manager */ long t0 = System.currentTimeMillis(); persistMgr.store(shared); succeeded = true; long t1 = System.currentTimeMillis(); if (log.isDebugEnabled()) { log.debug("persisting change log " + shared + " took " + (t1 - t0) + "ms"); } } finally { if (!succeeded) { cancel(); } } try { /* Let the shared item listeners know about the change */ shared.persisted(); // downgrade to read lock acquireReadLock(); rwLock.writeLock().release(); holdingWriteLock = false; /* notify virtual providers about node references */ for (int i = 0; i < virtualNodeReferences.length; i++) { List virtualRefs = virtualNodeReferences[i]; if (virtualRefs != null) { for (Iterator iter = virtualRefs.iterator(); iter.hasNext();) { NodeReferences refs = (NodeReferences) iter.next(); virtualProviders[i].setNodeReferences(refs); } } } /* dispatch the events */ events.dispatch(); /* let listener know about finished operation */ if (eventChannel != null) { eventChannel.updateCommitted(this); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?