internalversionimpl.java

来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 421 行

JAVA
421
字号
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *      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.jackrabbit.core.version;import org.apache.jackrabbit.core.state.NodeState;import org.apache.jackrabbit.core.value.InternalValue;import org.apache.jackrabbit.core.NodeId;import org.apache.jackrabbit.name.QName;import org.apache.jackrabbit.uuid.UUID;import javax.jcr.PropertyType;import javax.jcr.RepositoryException;import java.util.ArrayList;import java.util.Arrays;import java.util.Calendar;import java.util.HashSet;import java.util.List;/** * Implements a <code>InternalVersion</code> */class InternalVersionImpl extends InternalVersionItemImpl        implements InternalVersion {    /**     * the date when this version was created     */    private Calendar created;    /**     * the set of version labes of this history (values == String)     */    private HashSet labelCache = null;    /**     * specifies if this is the root version     */    private final boolean isRoot;    /**     * the version name     */    private final QName name;    /**     * the version history     */    private final InternalVersionHistory versionHistory;    /**     * Creates a new internal version with the given version history and     * persistance node. please note, that versions must be created by the     * version history.     *     * @param node     */    public InternalVersionImpl(InternalVersionHistoryImpl vh, NodeStateEx node, QName name) {        super(vh.getVersionManager(), node);        this.versionHistory = vh;        this.name = name;        // init internal values        InternalValue[] values = node.getPropertyValues(QName.JCR_CREATED);        if (values != null) {            created = (Calendar) values[0].internalValue();        }        isRoot = name.equals(QName.JCR_ROOTVERSION);    }    /**     * {@inheritDoc}     */    public NodeId getId() {        return node.getNodeId();    }    /**     * {@inheritDoc}     */    public InternalVersionItem getParent() {        return versionHistory;    }    /**     * {@inheritDoc}     */    public QName getName() {        return name;    }    /**     * {@inheritDoc}     */    public InternalFrozenNode getFrozenNode() {        // get frozen node        try {            NodeState.ChildNodeEntry entry = node.getState().getChildNodeEntry(QName.JCR_FROZENNODE, 1);            if (entry == null) {                throw new InternalError("version has no frozen node: " + getId());            }            return (InternalFrozenNode) vMgr.getItem(entry.getId());        } catch (RepositoryException e) {            throw new IllegalStateException("unable to retrieve frozen node: " + e);        }    }    /**     * {@inheritDoc}     */    public Calendar getCreated() {        return created;    }    /**     * {@inheritDoc}     */    public InternalVersion[] getSuccessors() {        vMgr.acquireReadLock();        try {            InternalValue[] values = node.getPropertyValues(QName.JCR_SUCCESSORS);            if (values != null) {                InternalVersion[] versions = new InternalVersion[values.length];                for (int i = 0; i < values.length; i++) {                    NodeId vId = new NodeId((UUID) values[i].internalValue());                    versions[i] = versionHistory.getVersion(vId);                }                return versions;            } else {                return new InternalVersion[0];            }        } finally {            vMgr.releaseReadLock();        }    }    /**     * {@inheritDoc}     */    public InternalVersion[] getPredecessors() {        InternalValue[] values = node.getPropertyValues(QName.JCR_PREDECESSORS);        if (values != null) {            InternalVersion[] versions = new InternalVersion[values.length];            for (int i = 0; i < values.length; i++) {                NodeId vId = new NodeId((UUID) values[i].internalValue());                versions[i] = versionHistory.getVersion(vId);            }            return versions;        } else {            return new InternalVersion[0];        }    }    /**     * {@inheritDoc}     */    public boolean isMoreRecent(InternalVersion v) {        InternalVersion[] preds = getPredecessors();        for (int i = 0; i < preds.length; i++) {            InternalVersion pred = preds[i];            if (pred.equals(v) || pred.isMoreRecent(v)) {                return true;            }        }        return false;    }    /**     * {@inheritDoc}     */    public InternalVersionHistory getVersionHistory() {        return versionHistory;    }    /**     * {@inheritDoc}     */    public boolean hasLabel(QName label) {        return internalHasLabel(label);    }    /**     * {@inheritDoc}     */    public QName[] getLabels() {        return internalGetLabels();    }    /**     * {@inheritDoc}     */    public boolean isRootVersion() {        return isRoot;    }    /**     * Clear the list of predecessors/successors and the label cache.     */    void clear() {        labelCache = null;    }    /**     * stores the given successors or predecessors to the persistance node     *     * @throws RepositoryException     */    private void storeXCessors(List cessors, QName propname, boolean store)            throws RepositoryException {        InternalValue[] values = new InternalValue[cessors.size()];        for (int i = 0; i < values.length; i++) {            values[i] = InternalValue.create(                    ((InternalVersion) cessors.get(i)).getId().getUUID());        }        node.setPropertyValues(propname, PropertyType.STRING, values);        if (store) {            node.store();        }    }    /**     * Detaches itself from the version graph.     *     * @throws RepositoryException     */    void internalDetach() throws RepositoryException {        // detach this from all successors        InternalVersion[] succ = getSuccessors();        for (int i = 0; i < succ.length; i++) {            ((InternalVersionImpl) succ[i]).internalDetachPredecessor(this, true);        }        // detach cached successors from preds        InternalVersion[] preds = getPredecessors();        for (int i = 0; i < preds.length; i++) {            ((InternalVersionImpl) preds[i]).internalDetachSuccessor(this, true);        }        // clear properties        clear();    }    /**     * Attaches this version as successor to all predecessors. assuming that the     * predecessors are already set.     *     * @throws RepositoryException     */    void internalAttach() throws RepositoryException {        InternalVersion[] preds = getPredecessors();        for (int i = 0; i < preds.length; i++) {            ((InternalVersionImpl) preds[i]).internalAddSuccessor(this, true);        }    }    /**     * Adds a version to the set of successors.     *     * @param succ     * @param store     * @throws RepositoryException     */    private void internalAddSuccessor(InternalVersionImpl succ, boolean store)            throws RepositoryException {        List l = new ArrayList(Arrays.asList(getSuccessors()));        if (!l.contains(succ)) {            l.add(succ);            storeXCessors(l, QName.JCR_SUCCESSORS, store);        }    }    /**     * Removes the predecessor V of this predecessors list and adds all of Vs     * predecessors to it.     * <p/>     * please note, that this operation might corrupt the version graph     *     * @param v the successor to detach     */    private void internalDetachPredecessor(InternalVersionImpl v, boolean store)            throws RepositoryException {        // remove 'v' from predecessor list        List l = new ArrayList(Arrays.asList(getPredecessors()));        l.remove(v);        // attach v's predecessors        l.addAll(Arrays.asList(v.getPredecessors()));        storeXCessors(l, QName.JCR_PREDECESSORS, store);    }    /**     * Removes the successor V of this successors list and adds all of Vs     * successors to it.     * <p/>     * please note, that this operation might corrupt the version graph     *     * @param v the successor to detach     */    private void internalDetachSuccessor(InternalVersionImpl v, boolean store)            throws RepositoryException {        // remove 'v' from successors list        List l = new ArrayList(Arrays.asList(getSuccessors()));        l.remove(v);        // attach v's successors        l.addAll(Arrays.asList(v.getSuccessors()));        storeXCessors(l, QName.JCR_SUCCESSORS, store);    }    /**     * adds a label to the label cache. does not affect storage     *     * @param label     * @return <code>true</code> if the label was added     */    boolean internalAddLabel(QName label) {        if (labelCache == null) {            labelCache = new HashSet();        }        return labelCache.add(label);    }    /**     * removes a label from the label cache. does not affect storage     *     * @param label     * @return <code>true</code> if the label was removed     */    boolean internalRemoveLabel(QName label) {        if (labelCache == null) {            return false;        } else {            return labelCache.remove(label);        }    }    /**     * checks, if a label is in the label cache     *     * @param label     * @return <code>true</code> if the label exists     */    boolean internalHasLabel(QName label) {        if (labelCache == null) {            return false;        } else {            return labelCache.contains(label);        }    }    /**     * returns the array of the cached labels     *     * @return the internal labels     */    QName[] internalGetLabels() {        if (labelCache == null) {            return new QName[0];        } else {            return (QName[]) labelCache.toArray(new QName[labelCache.size()]);        }    }    /**     * Invalidate this item.     */    void invalidate() {        node.getState().discard();    }    /**     * Resolves jcr:successor properties that are missing.     *     * @throws RepositoryException     */    void legacyResolveSuccessors() throws RepositoryException {        InternalValue[] values = node.getPropertyValues(QName.JCR_PREDECESSORS);        if (values != null) {            for (int i = 0; i < values.length; i++) {                NodeId vId = new NodeId((UUID) values[i].internalValue());                InternalVersionImpl v = (InternalVersionImpl) versionHistory.getVersion(vId);                v.internalAddSuccessor(this, false);            }        }    }    /**     * {@inheritDoc}     */    public boolean equals(Object obj) {        if (this == obj) {            return true;        }        if (obj instanceof InternalVersionImpl) {            InternalVersionImpl v = (InternalVersionImpl) obj;            return v.getId().equals(getId());        }        return false;    }    /**     * {@inheritDoc}     */    public int hashCode() {        return getId().hashCode();    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?