shareditemstatemanager.java
来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 1,450 行 · 第 1/4 页
JAVA
1,450 行
} finally { if (holdingWriteLock) { // exception occured before downgrading lock rwLock.writeLock().release(); holdingWriteLock = false; } else { rwLock.readLock().release(); } } } /** * Cancel update operation. At the end of this operation, the write lock * on the item state manager will have been released. */ public void cancel() { try { /* let listener know about cancelled operation */ if (eventChannel != null) { eventChannel.updateCancelled(this); } local.disconnect(); for (Iterator iter = shared.modifiedStates(); iter.hasNext();) { ItemState state = (ItemState) iter.next(); try { state.copy(loadItemState(state.getId())); } catch (ItemStateException e) { state.discard(); } } for (Iterator iter = shared.deletedStates(); iter.hasNext();) { ItemState state = (ItemState) iter.next(); try { state.copy(loadItemState(state.getId())); } catch (ItemStateException e) { state.discard(); } } for (Iterator iter = shared.addedStates(); iter.hasNext();) { ItemState state = (ItemState) iter.next(); state.discard(); } } finally { if (holdingWriteLock) { rwLock.writeLock().release(); holdingWriteLock = false; } } } /** * {@inheritDoc} */ public void setAttribute(String name, Object value) { if (attributes == null) { attributes = new HashMap(); } attributes.put(name, value); } /** * {@inheritDoc} */ public Object getAttribute(String name) { if (attributes != null) { return attributes.get(name); } return null; } /** * {@inheritDoc} */ public ChangeLog getChanges() { return local; } /** * {@inheritDoc} */ public EventStateCollection getEvents() { return events; } } /** * Begin update operation. This will return an object that can itself be * ended/cancelled. */ public Update beginUpdate(ChangeLog local, EventStateCollectionFactory factory, VirtualItemStateProvider virtualProvider) throws ReferentialIntegrityException, StaleItemStateException, ItemStateException { Update update = new Update(local, factory, virtualProvider); update.begin(); return update; } /** * Store modifications registered in a <code>ChangeLog</code>. The items * contained in the <tt>ChangeLog</tt> are not states returned by this * item state manager but rather must be reconnected to items provided * by this state manager.<p/> * After successfully storing the states the observation manager is informed * about the changes, if an observation manager is passed to this method.<p/> * NOTE: This method is not synchronized, because all methods it invokes * on instance members (such as {@link PersistenceManager#store} are * considered to be thread-safe. Should this ever change, the * synchronization status has to be re-examined. * * @param local change log containing local items * @param factory event state collection factory * @throws ReferentialIntegrityException if a new or modified REFERENCE * property refers to a non-existent * target or if a removed node is still * being referenced * @throws StaleItemStateException if at least one of the affected item * states has become stale * @throws ItemStateException if another error occurs */ public void update(ChangeLog local, EventStateCollectionFactory factory) throws ReferentialIntegrityException, StaleItemStateException, ItemStateException { beginUpdate(local, factory, null).end(); } /** * Handle an external update. * * @param external external change containing only node and property ids. * @param events events to deliver */ public void externalUpdate(ChangeLog external, EventStateCollection events) { boolean holdingWriteLock = false; try { acquireWriteLock(); holdingWriteLock = true; doExternalUpdate(external); } catch (ItemStateException e) { String msg = "Unable to acquire write lock."; log.error(msg); } try { acquireReadLock(); rwLock.writeLock().release(); holdingWriteLock = false; events.dispatch(); } catch (ItemStateException e) { String msg = "Unable to downgrade to read lock."; log.error(msg); } finally { if (holdingWriteLock) { rwLock.writeLock().release(); holdingWriteLock = false; } else { rwLock.readLock().release(); } } } /** * Perform the external update. While executing this method, the * <code>writeLock</code> on this manager is held. * * @param external external change containing only node and property ids. */ protected void doExternalUpdate(ChangeLog external) { // workaround to flush cache of persistence manager if (persistMgr instanceof CachingPersistenceManager) { ((CachingPersistenceManager) persistMgr).onExternalUpdate(external); } ChangeLog shared = new ChangeLog(); // Build a copy of the external change log, consisting of shared // states we have in our cache. Inform listeners about this // change. Iterator modifiedStates = external.modifiedStates(); while (modifiedStates.hasNext()) { ItemState state = (ItemState) modifiedStates.next(); state = cache.retrieve(state.getId()); if (state != null) { try { ItemState currentState = loadItemState(state.getId()); state.copy(currentState); state.setModCount(currentState.getModCount()); shared.modified(state); } catch (NoSuchItemStateException e) { // This is likely to happen because a subsequent delete // of this very state has not yet been transmitted. String msg = "Unable to retrieve state: " + state.getId() + ", ignored."; log.info(msg); state.discard(); } catch (ItemStateException e) { String msg = "Unable to retrieve state: " + state.getId(); log.warn(msg); state.discard(); } } } Iterator deletedStates = external.deletedStates(); while (deletedStates.hasNext()) { ItemState state = (ItemState) deletedStates.next(); state = cache.retrieve(state.getId()); if (state != null) { shared.deleted(state); } } shared.persisted(); } /** * Add an <code>ItemStateListener</code> * @param listener the new listener to be informed on modifications */ public void addListener(ItemStateListener listener) { dispatcher.addListener(listener); } /** * Remove an <code>ItemStateListener</code> * @param listener an existing listener */ public void removeListener(ItemStateListener listener) { dispatcher.removeListener(listener); } //-------------------------------------------------------< implementation > /** * Create a new node state instance * * @param id uuid * @param nodeTypeName node type name * @param parentId parent UUID * @return new node state instance */ private NodeState createInstance(NodeId id, QName nodeTypeName, NodeId parentId) { NodeState state = persistMgr.createNew(id); state.setNodeTypeName(nodeTypeName); state.setParentId(parentId); state.setStatus(ItemState.STATUS_NEW); state.setContainer(this); return state; } /** * Create root node state * * @param rootNodeId root node id * @param ntReg node type registry * @return root node state * @throws ItemStateException if an error occurs */ private NodeState createRootNodeState(NodeId rootNodeId, NodeTypeRegistry ntReg) throws ItemStateException { NodeState rootState = createInstance(rootNodeId, QName.REP_ROOT, null); NodeState jcrSystemState = createInstance(RepositoryImpl.SYSTEM_ROOT_NODE_ID, QName.REP_SYSTEM, rootNodeId); // FIXME need to manually setup root node by creating mandatory jcr:primaryType property // @todo delegate setup of root node to NodeTypeInstanceHandler // id of the root node's definition NodeDefId nodeDefId; // definition of jcr:primaryType property PropDef propDef; // id of the jcr:system node's definition NodeDefId jcrSystemDefId; try { nodeDefId = ntReg.getRootNodeDef().getId(); EffectiveNodeType ent = ntReg.getEffectiveNodeType(QName.REP_ROOT); propDef = ent.getApplicablePropertyDef(QName.JCR_PRIMARYTYPE, PropertyType.NAME, false); jcrSystemDefId = ent.getApplicableChildNodeDef(QName.JCR_SYSTEM, QName.REP_SYSTEM, ntReg).getId(); } catch (NoSuchNodeTypeException nsnte) { String msg = "internal error: failed to create root node"; log.error(msg, nsnte); throw new ItemStateException(msg, nsnte); } catch (ConstraintViolationException cve) { String msg = "internal error: failed to create root node"; log.error(msg, cve); throw new ItemStateException(msg, cve); } rootState.setDefinitionId(nodeDefId); jcrSystemState.setDefinitionId(jcrSystemDefId); // create jcr:primaryType property on root node state rootState.addPropertyName(propDef.getName()); PropertyState prop = createInstance(propDef.getName(), rootNodeId); prop.setValues(new InternalValue[]{InternalValue.create(QName.REP_ROOT)}); prop.setType(propDef.getRequiredType()); prop.setMultiValued(propDef.isMultiple()); prop.setDefinitionId(propDef.getId()); // create jcr:primaryType property on jcr:system node state jcrSystemState.addPropertyName(propDef.getName()); PropertyState primaryTypeProp = createInstance(propDef.getName(), jcrSystemState.getNodeId()); primaryTypeProp.setValues(new InternalValue[]{InternalValue.create(QName.REP_SYSTEM)}); primaryTypeProp.setType(propDef.getRequiredType()); primaryTypeProp.setMultiValued(propDef.isMultiple()); primaryTypeProp.setDefinitionId(propDef.getId()); // add child node entry for jcr:system node rootState.addChildNodeEntry(QName.JCR_SYSTEM, RepositoryImpl.SYSTEM_ROOT_NODE_ID); // add child node entry for virtual jcr:versionStorage jcrSystemState.addChildNodeEntry(QName.JCR_VERSIONSTORAGE, RepositoryImpl.VERSION_STORAGE_NODE_ID); // add child node entry for virtual jcr:nodeTypes jcrSystemState.addChildNodeEntry(QName.JCR_NODETYPES, RepositoryImpl.NODETYPES_NODE_ID); ChangeLog changeLog = new ChangeLog(); changeLog.added(rootState); changeLog.added(prop); changeLog.added(jcrSystemState); changeLog.added(primaryTypeProp); persistMgr.store(changeLog); changeLog.persisted(); return rootState; } /** * Returns the item state for the given id without considering virtual * item state providers. */ private ItemState getNonVirtualItemState(ItemId id) throws NoSuchItemStateException, ItemStateException { // check cache; synchronized to ensure an entry is not created twice. synchronized (cache) { ItemState state = cache.retrieve(id); if (state == null) { // not found in cache, load from persistent storage state = loadItemState(id); state.setStatus(ItemState.STATUS_EXISTING); // put it in cache cache.cache(state); // set parent container state.setContainer(this); } return state; } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?