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 + -
显示快捷键?