You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by tr...@apache.org on 2009/07/19 02:09:41 UTC
svn commit: r795452 [3/3] - in /jackrabbit/sandbox/tripod-JCR-2209: ./
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/
Added: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplRestore.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplRestore.java?rev=795452&view=auto
==============================================================================
--- jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplRestore.java (added)
+++ jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplRestore.java Sun Jul 19 00:09:40 2009
@@ -0,0 +1,552 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.ItemExistsException;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.version.OnParentVersionAction;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionException;
+import javax.jcr.version.VersionManager;
+
+import org.apache.jackrabbit.core.BatchedItemOperations;
+import org.apache.jackrabbit.core.HierarchyManager;
+import org.apache.jackrabbit.core.ItemValidator;
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.id.NodeId;
+import org.apache.jackrabbit.core.nodetype.PropDef;
+import org.apache.jackrabbit.core.security.authorization.Permission;
+import org.apache.jackrabbit.core.state.ChildNodeEntry;
+import org.apache.jackrabbit.core.state.ItemStateException;
+import org.apache.jackrabbit.core.state.PropertyState;
+import org.apache.jackrabbit.core.state.UpdatableItemStateManager;
+import org.apache.jackrabbit.core.value.InternalValue;
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.Path;
+import org.apache.jackrabbit.spi.commons.name.NameConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The JCR Version Manager impementation is split in several classes in order to
+ * group related methods together.
+ * </p>
+ * this class provides methods for the restore operations.
+ */
+abstract public class JcrVersionManagerImplRestore extends JcrVersionManagerImplBase {
+
+ /**
+ * default logger
+ */
+ private static final Logger log = LoggerFactory.getLogger(JcrVersionManagerImplRestore.class);
+
+ /**
+ * Creates a new version manager for the given session
+ * @param session workspace sesion
+ * @param stateMgr the underlying state manager
+ * @param hierMgr local hierarchy manager
+ */
+ protected JcrVersionManagerImplRestore(SessionImpl session,
+ UpdatableItemStateManager stateMgr,
+ HierarchyManager hierMgr) {
+ super(session, stateMgr, hierMgr);
+ }
+
+ /**
+ * @param state the state to restore
+ * @param version the version to restore
+ * @param removeExisting remove existing flag
+ * @throws RepositoryException if an error occurs
+ *
+ * @see javax.jcr.version.VersionManager#restore(String, Version, boolean)
+ */
+ protected void restore(NodeStateEx state, Version version, boolean removeExisting)
+ throws RepositoryException {
+ checkVersionable(state);
+ InternalVersion v = getVersion(version);
+ // check if 'own' version
+ if (!v.getVersionHistory().equals(getVersionHistory(state))) {
+ throw new VersionException("Unable to restore version. Not same version history.");
+ }
+ WriteOperation ops = startWriteOperation();
+ try {
+ internalRestore(state, v, new DateVersionSelector(version.getCreated()), removeExisting);
+ ops.save();
+ } catch (ItemStateException e) {
+ throw new RepositoryException(e);
+ } finally {
+ ops.close();
+ }
+ }
+
+ /**
+ * @param state the state to restore
+ * @param versionName the name of the version to restore
+ * @param removeExisting remove existing flag
+ * @throws RepositoryException if an error occurs
+ *
+ * @see VersionManager#restore(String, String, boolean)
+ */
+ protected void restore(NodeStateEx state, Name versionName, boolean removeExisting)
+ throws RepositoryException {
+ checkVersionable(state);
+ InternalVersion v = getVersionHistory(state).getVersion(versionName);
+ DateVersionSelector gvs = new DateVersionSelector(v.getCreated());
+ WriteOperation ops = startWriteOperation();
+ try {
+ internalRestore(state, v, gvs, removeExisting);
+ ops.save();
+ } catch (ItemStateException e) {
+ throw new RepositoryException(e);
+ } finally {
+ ops.close();
+ }
+ }
+
+ /**
+ * @param state the state to restore
+ * @param versionLabel the name of the version to restore
+ * @param removeExisting remove existing flag
+ * @throws RepositoryException if an error occurs
+ *
+ * @see VersionManager#restoreByLabel(String, String, boolean)
+ */
+ protected void restoreByLabel(NodeStateEx state, Name versionLabel, boolean removeExisting)
+ throws RepositoryException {
+ checkVersionable(state);
+ InternalVersion v = getVersionHistory(state).getVersionByLabel(versionLabel);
+ if (v == null) {
+ throw new VersionException("No version for label " + versionLabel + " found.");
+ }
+ WriteOperation ops = startWriteOperation();
+ try {
+ internalRestore(state, v, new LabelVersionSelector(versionLabel), removeExisting);
+ ops.save();
+ } catch (ItemStateException e) {
+ throw new RepositoryException(e);
+ } finally {
+ ops.close();
+ }
+ }
+
+ /**
+ * Restores the <code>version</code> below the <code>parent</code> node
+ * using the indicated <code>name</code>
+ *
+ * @param parent parent node
+ * @param name desired name
+ * @param version version to restore
+ * @param removeExisting remove exiting flag
+ * @throws RepositoryException if an error occurs
+ */
+ protected void restore(NodeStateEx parent, Name name, Version version, boolean removeExisting)
+ throws RepositoryException {
+ // check if versionable node exists
+ InternalFrozenNode fn = ((VersionImpl) version).getInternalFrozenNode();
+ if (stateMgr.hasItemState(fn.getFrozenId())) {
+ if (removeExisting) {
+ NodeStateEx existing = parent.getNode(fn.getFrozenId());
+ checkVersionable(existing);
+ InternalVersion v = getVersion(version);
+
+ // move versionable node below this one using the given "name"
+ WriteOperation ops = startWriteOperation();
+ try {
+ NodeStateEx exParent = existing.getParent();
+ NodeStateEx state = parent.moveFrom(existing, name, false);
+ exParent.store();
+ parent.store();
+ // and restore it
+ internalRestore(state, v, new DateVersionSelector(v.getCreated()), removeExisting);
+ ops.save();
+ } catch (ItemStateException e) {
+ throw new RepositoryException(e);
+ } finally {
+ ops.close();
+ }
+ } else {
+ throw new ItemExistsException("Unable to restore version. Versionable node already exists.");
+ }
+ } else {
+ // create new node below parent
+ NodeStateEx state = parent.addNode(name, fn.getFrozenPrimaryType(), fn.getFrozenId());
+ state.setMixins(fn.getFrozenMixinTypes());
+ restore(state, version, removeExisting);
+ }
+ }
+
+ /**
+ * @param versions Versions to restore
+ * @param removeExisting remove existing flag
+ * @throws RepositoryException if an error occurs
+ *
+ * @see VersionManager#restore(Version[], boolean)
+ * @see VersionManager#restore(Version, boolean)
+ */
+ protected void restore(final Map<NodeId, InternalVersion> versions,
+ boolean removeExisting)
+ throws RepositoryException {
+
+ // create a version selector to the set of versions
+ VersionSelector vsel = new VersionSelector() {
+ public InternalVersion select(InternalVersionHistory versionHistory) throws RepositoryException {
+ // try to select version as specified
+ InternalVersion v = versions.get(versionHistory.getId());
+ if (v == null) {
+ // select latest one
+ v = DateVersionSelector.selectByDate(versionHistory, null);
+ }
+ return v;
+ }
+ };
+
+ WriteOperation ops = startWriteOperation();
+ try {
+ // now restore all versions that have a node in the workspace
+ int numRestored = 0;
+ while (versions.size() > 0) {
+ Set<InternalVersion> restored = null;
+ for (InternalVersion v : versions.values()) {
+ NodeStateEx state = getNodeStateEx(v.getFrozenNode().getFrozenId());
+ if (state != null) {
+ // todo: check should operate on workspace states, too
+ int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD;
+ checkModify(state, options, Permission.NONE);
+ restored = internalRestore(state, v, vsel, removeExisting);
+ // remove restored versions from set
+ for (InternalVersion r : restored) {
+ versions.remove(r.getVersionHistory().getId());
+ }
+ numRestored += restored.size();
+ break;
+ }
+ }
+ if (restored == null) {
+ if (numRestored == 0) {
+ throw new VersionException("Unable to restore. At least one version needs"
+ + " existing versionable node in workspace.");
+ } else {
+ throw new VersionException("Unable to restore. All versions with non"
+ + " existing versionable nodes need parent.");
+ }
+ }
+ }
+ ops.save();
+ } catch (ItemStateException e) {
+ log.error("Error while reverting changes applied during restore.", e);
+ throw new RepositoryException(e);
+ } finally {
+ ops.close();
+ }
+ }
+
+ /**
+ * Internal method to restore a version.
+ *
+ * @param state the state to restore
+ * @param version version to restore
+ * @param vsel the version selector that will select the correct version for
+ * OPV=Version child nodes.
+ * @param removeExisting remove existing flag
+ * @return set of restored versions
+ * @throws RepositoryException if an error occurs
+ * @throws ItemStateException if an error occurs
+ */
+ protected Set<InternalVersion> internalRestore(NodeStateEx state,
+ InternalVersion version,
+ VersionSelector vsel,
+ boolean removeExisting)
+ throws RepositoryException, ItemStateException {
+
+ // fail if root version
+ if (version.isRootVersion()) {
+ throw new VersionException("Restore of root version not allowed.");
+ }
+
+ boolean isFull = checkVersionable(state);
+
+ // check permission
+ Path path = hierMgr.getPath(state.getNodeId());
+ session.getAccessManager().checkPermission(path, Permission.VERSION_MNGMT);
+
+ // 1. The child node and properties of N will be changed, removed or
+ // added to, depending on their corresponding copies in V and their
+ // own OnParentVersion attributes (see 7.2.8, below, for details).
+ Set<InternalVersion> restored = new HashSet<InternalVersion>();
+ restoreFrozenState(state, version.getFrozenNode(), vsel, restored, removeExisting);
+ restored.add(version);
+
+ if (isFull) {
+ // 2. N's jcr:baseVersion property will be changed to point to V.
+ state.setPropertyValue(
+ NameConstants.JCR_BASEVERSION, InternalValue.create(version.getId()));
+
+ // 4. N's jcr:predecessor property is set to null
+ state.setPropertyValues(NameConstants.JCR_PREDECESSORS, PropertyType.REFERENCE, InternalValue.EMPTY_ARRAY);
+
+ // also clear mergeFailed
+ state.removeProperty(NameConstants.JCR_MERGEFAILED);
+
+ } else {
+ // with simple versioning, the node is checked in automatically,
+ // thus not allowing any branches
+ vMgr.checkin(session, state);
+ }
+ // 3. N's jcr:isCheckedOut property is set to false.
+ state.setPropertyValue(NameConstants.JCR_ISCHECKEDOUT, InternalValue.create(false));
+ state.store();
+ return restored;
+ }
+
+ /**
+ * Restores the properties and child nodes from the frozen state.
+ *
+ * @param state state to restore
+ * @param freeze the frozen node
+ * @param vsel version selector
+ * @param restored set of restored versions
+ * @param removeExisting remove existing flag
+ * @throws RepositoryException if an error occurs
+ * @throws ItemStateException if an error occurs
+ */
+ protected void restoreFrozenState(NodeStateEx state, InternalFrozenNode freeze, VersionSelector vsel,
+ Set<InternalVersion> restored, boolean removeExisting)
+ throws RepositoryException, ItemStateException {
+
+ // check uuid
+ if (state.getEffectiveNodeType().includesNodeType(NameConstants.MIX_REFERENCEABLE)) {
+ if (!state.getNodeId().equals(freeze.getFrozenId())) {
+ throw new ItemExistsException("Unable to restore version of " + safeGetJCRPath(state) + ". UUID changed.");
+ }
+ }
+
+ // check primary type
+ if (!freeze.getFrozenPrimaryType().equals(state.getState().getNodeTypeName())) {
+ // todo: implement
+ throw new UnsupportedRepositoryOperationException("Unable to restore version of " + safeGetJCRPath(state) + ". PrimaryType change not supported yet.");
+ }
+
+ // adjust mixins
+ state.setMixins(freeze.getFrozenMixinTypes());
+
+ // copy frozen properties
+ PropertyState[] props = freeze.getFrozenProperties();
+ HashSet<Name> propNames = new HashSet<Name>();
+ for (PropertyState prop : props) {
+ // skip properties that should not to be reverted back
+ if (prop.getName().equals(NameConstants.JCR_ACTIVITY)) {
+ continue;
+ }
+ propNames.add(prop.getName());
+ state.copyFrom(prop);
+ }
+ // remove properties that do not exist in the frozen representation
+ for (PropertyState prop: state.getProperties()) {
+ // ignore some props that are not well guarded by the OPV
+ Name propName = prop.getName();
+ if (propName.equals(NameConstants.JCR_VERSIONHISTORY)) {
+ // ignore
+ } else if (propName.equals(NameConstants.JCR_PREDECESSORS)) {
+ // ignore
+ } else if (!propNames.contains(propName)) {
+ int opv = state.getDefinition(prop).getOnParentVersion();
+ if (opv == OnParentVersionAction.COPY || opv == OnParentVersionAction.VERSION) {
+ state.removeProperty(propName);
+ }
+ }
+ }
+
+ // add 'auto-create' properties that do not exist yet
+ for (PropDef def: state.getEffectiveNodeType().getAutoCreatePropDefs()) {
+ if (!state.hasProperty(def.getName())) {
+ // compute system generated values if necessary
+ // todo: use NodeTypeInstanceHandler
+ InternalValue[] values =
+ BatchedItemOperations.computeSystemGeneratedPropertyValues(state.getState(), def);
+ if (values == null) {
+ values = def.getDefaultValues();
+ }
+ if (values != null) {
+ state.setPropertyValues(def.getName(), def.getRequiredType(), values, def.isMultiple());
+ }
+ }
+ }
+
+ // first delete some of the child nodes. this is a bit tricky, in case
+ // the child node index changed. mark an sweep
+ LinkedList<ChildNodeEntry> toDelete = new LinkedList<ChildNodeEntry>();
+ for (ChildNodeEntry entry: state.getState().getChildNodeEntries()) {
+ NodeStateEx child = state.getNode(entry.getName(), entry.getIndex());
+ int opv = child.getDefinition().getOnParentVersion();
+ if (opv == OnParentVersionAction.COPY) {
+ // only remove OPV=Copy nodes
+ toDelete.addFirst(entry);
+ } else if (opv == OnParentVersionAction.VERSION) {
+ // only remove, if node to be restored does not contain child,
+ // or if restored child is not versionable
+ NodeId vhId = child.hasProperty(NameConstants.JCR_VERSIONHISTORY)
+ ? child.getPropertyValue(NameConstants.JCR_VERSIONHISTORY).getNodeId()
+ : null;
+ if (vhId == null || !freeze.hasFrozenHistory(vhId)) {
+ toDelete.addFirst(entry);
+ }
+ }
+ }
+ for (ChildNodeEntry entry: toDelete) {
+ state.removeNode(entry.getName(), entry.getIndex());
+ }
+ // need to sync with state manager
+ state.store();
+
+ // restore the frozen nodes
+ InternalFreeze[] frozenNodes = freeze.getFrozenChildNodes();
+ for (InternalFreeze child : frozenNodes) {
+ NodeStateEx restoredChild = null;
+ if (child instanceof InternalFrozenNode) {
+ InternalFrozenNode f = (InternalFrozenNode) child;
+ // check for existing
+ if (f.getFrozenId() != null) {
+ if (stateMgr.hasItemState(f.getFrozenId())) {
+ NodeStateEx existing = state.getNode(f.getFrozenId());
+ if (removeExisting) {
+ NodeStateEx parent = existing.getParent();
+ parent.removeNode(existing);
+ parent.store();
+ } else if (existing.getState().isShareable()) {
+ // if existing node is shareable, then clone it
+ restoredChild = state.moveFrom(existing, existing.getName(), true);
+ } else {
+ // since we delete the OPV=Copy children beforehand, all
+ // found nodes must be outside of this tree
+ throw new ItemExistsException(
+ "Unable to restore node, item already"
+ + " exists outside of restored tree: "
+ + existing);
+ }
+
+ }
+ }
+ if (restoredChild == null) {
+ restoredChild = state.addNode(f.getName(), f.getFrozenPrimaryType(), f.getFrozenId());
+ restoredChild.setMixins(f.getFrozenMixinTypes());
+ restoreFrozenState(restoredChild, f, vsel, restored, removeExisting);
+ }
+
+ } else if (child instanceof InternalFrozenVersionHistory) {
+ InternalFrozenVersionHistory fh = (InternalFrozenVersionHistory) child;
+ InternalVersionHistory vh = vMgr.getVersionHistory(fh.getVersionHistoryId());
+ Name oldVersion = null;
+
+ // check if representing versionable already exists somewhere
+ NodeId nodeId = vh.getVersionableId();
+ if (stateMgr.hasItemState(nodeId)) {
+ NodeStateEx existing = state.getNode(nodeId);
+ if (existing.getParentId() == state.getNodeId()) {
+ // remove
+ state.removeNode(existing);
+ } else if (removeExisting) {
+ NodeStateEx parent = existing.getNode(existing.getNodeId());
+ state.moveFrom(existing, fh.getName(), false);
+ parent.store();
+
+ // get old version name
+ oldVersion = getBaseVersion(existing).getName();
+ } else {
+ // since we delete the OPV=Copy children beforehand, all
+ // found nodes must be outside of this tree
+ throw new ItemExistsException(
+ "Unable to restore node, item already exists"
+ + " outside of restored tree: " + existing);
+ }
+ }
+ // get desired version from version selector
+ InternalVersion v = vsel.select(vh);
+
+ // check existing version of item exists
+ if (!stateMgr.hasItemState(nodeId)) {
+ if (v == null) {
+ // if version selector was unable to select version,
+ // choose the initial one
+ InternalVersion[] vs = vh.getRootVersion().getSuccessors();
+ if (vs.length == 0) {
+ String msg = "Unable to select appropariate version for "
+ + child.getName() + " using " + vsel;
+ log.error(msg);
+ throw new VersionException(msg);
+ }
+ v = vs[0];
+ }
+ InternalFrozenNode f = v.getFrozenNode();
+ restoredChild = state.addNode(fh.getName(), f.getFrozenPrimaryType(), f.getFrozenId());
+ restoredChild.setMixins(f.getFrozenMixinTypes());
+ } else {
+ restoredChild = state.getNode(nodeId);
+ if (v == null || oldVersion == null || v.getName().equals(oldVersion)) {
+ v = null;
+ }
+ }
+ if (v != null) {
+ try {
+ internalRestore(restoredChild, v, vsel, removeExisting);
+ } catch (RepositoryException e) {
+ log.error("Error while restoring node: " + e);
+ log.error(" child path: " + restoredChild);
+ log.error(" selected version: " + v.getName());
+ StringBuffer avail = new StringBuffer();
+ for (Name name: vh.getVersionNames()) {
+ avail.append(name);
+ avail.append(", ");
+ }
+ log.error(" available versions: " + avail);
+ log.error(" versionselector: " + vsel);
+ throw e;
+ }
+ // add this version to set
+ restored.add(v);
+ }
+ }
+ // ensure proper ordering (issue JCR-469)
+ if (restoredChild != null && state.getEffectiveNodeType().hasOrderableChildNodes()) {
+ // order at end
+ ArrayList<ChildNodeEntry> list = new ArrayList<ChildNodeEntry>(state.getState().getChildNodeEntries());
+ ChildNodeEntry toReorder = null;
+ boolean isLast = true;
+ for (ChildNodeEntry e: list) {
+ if (e.getId().equals(restoredChild.getNodeId())) {
+ toReorder = e;
+ } else if (toReorder != null) {
+ isLast = false;
+ }
+ }
+ if (toReorder != null && !isLast) {
+ list.remove(toReorder);
+ list.add(toReorder);
+ state.getState().setChildNodeEntries(list);
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
Propchange: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplRestore.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplRestore.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Modified: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/LabelVersionSelector.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/LabelVersionSelector.java?rev=795452&r1=795451&r2=795452&view=diff
==============================================================================
--- jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/LabelVersionSelector.java (original)
+++ jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/LabelVersionSelector.java Sun Jul 19 00:09:40 2009
@@ -17,9 +17,8 @@
package org.apache.jackrabbit.core.version;
import javax.jcr.RepositoryException;
-import javax.jcr.version.Version;
-import javax.jcr.version.VersionException;
-import javax.jcr.version.VersionHistory;
+
+import org.apache.jackrabbit.spi.Name;
/**
* This Class implements a version selector that selects a version by label.
@@ -38,15 +37,15 @@
/**
* a versionlabel hint
*/
- private String label = null;
+ private Name label = null;
/**
* Creates a <code>LabelVersionSelector</code> that will try to select a
* version with the given label.
*
- * @param label
+ * @param label label hint
*/
- public LabelVersionSelector(String label) {
+ public LabelVersionSelector(Name label) {
this.label = label;
}
@@ -55,28 +54,26 @@
*
* @return the label hint.
*/
- public String getLabel() {
+ public Name getLabel() {
return label;
}
/**
* Sets the label hint
*
- * @param label
+ * @param label label hint
*/
- public void setLabel(String label) {
+ public void setLabel(Name label) {
this.label = label;
}
/**
+ * {@inheritDoc}
+ *
* Selects a version from the given version history using the previously
* assigned hint in the following order: name, label, date, latest.
- *
- * @param versionHistory
- * @return
- * @throws RepositoryException
*/
- public Version select(VersionHistory versionHistory)
+ public InternalVersion select(InternalVersionHistory versionHistory)
throws RepositoryException {
return selectByLabel(versionHistory, label);
}
@@ -84,18 +81,14 @@
/**
* Selects a version by label
*
- * @param history
- * @param label
+ * @param history history to select from
+ * @param label desired label
* @return the version with the given label or <code>null</code>
- * @throws RepositoryException
+ * @throws RepositoryException if an error occurs
*/
- public static Version selectByLabel(VersionHistory history, String label)
+ public static InternalVersion selectByLabel(InternalVersionHistory history, Name label)
throws RepositoryException {
- try {
- return history.getVersionByLabel(label);
- } catch (VersionException e) {
- return null;
- }
+ return history.getVersionByLabel(label);
}
/**
Modified: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java?rev=795452&r1=795451&r2=795452&view=diff
==============================================================================
--- jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java (original)
+++ jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java Sun Jul 19 00:09:40 2009
@@ -16,32 +16,34 @@
*/
package org.apache.jackrabbit.core.version;
+import java.util.List;
+import java.util.Set;
+
+import javax.jcr.ItemExistsException;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+
+import org.apache.jackrabbit.core.PropertyImpl;
import org.apache.jackrabbit.core.id.NodeId;
import org.apache.jackrabbit.core.id.PropertyId;
-import org.apache.jackrabbit.core.PropertyImpl;
import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
import org.apache.jackrabbit.core.nodetype.NodeDef;
import org.apache.jackrabbit.core.nodetype.NodeTypeConflictException;
import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
import org.apache.jackrabbit.core.nodetype.PropDef;
+import org.apache.jackrabbit.core.state.ChildNodeEntry;
import org.apache.jackrabbit.core.state.ItemState;
import org.apache.jackrabbit.core.state.ItemStateException;
import org.apache.jackrabbit.core.state.NodeState;
import org.apache.jackrabbit.core.state.PropertyState;
import org.apache.jackrabbit.core.state.UpdatableItemStateManager;
-import org.apache.jackrabbit.core.state.ChildNodeEntry;
import org.apache.jackrabbit.core.value.InternalValue;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.spi.commons.name.NameConstants;
-import java.util.List;
-import java.util.Set;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.PropertyType;
-import javax.jcr.nodetype.ConstraintViolationException;
-import javax.jcr.nodetype.NoSuchNodeTypeException;
-
/**
* This Class provides some basic node operations directly on the node state.
*/
@@ -70,8 +72,10 @@
/**
* Creates a new persistent node
*
- * @param stateMgr
- * @param nodeState
+ * @param stateMgr state manager
+ * @param ntReg node type registry
+ * @param nodeState underlying node state
+ * @param name name (can be null)
*/
public NodeStateEx(UpdatableItemStateManager stateMgr,
NodeTypeRegistry ntReg,
@@ -82,6 +86,26 @@
this.name = name;
}
+ /**
+ * Creates a new persistent node
+ *
+ * @param stateMgr state manager
+ * @param ntReg node type registry
+ * @param nodeId node id
+ * @throws RepositoryException if the node state can't be loaded
+ */
+ public NodeStateEx(UpdatableItemStateManager stateMgr,
+ NodeTypeRegistry ntReg,
+ NodeId nodeId) throws RepositoryException {
+ try {
+ this.ntReg = ntReg;
+ this.stateMgr = stateMgr;
+ this.nodeState = (NodeState) stateMgr.getItemState(nodeId);
+ } catch (ItemStateException e) {
+ throw new RepositoryException(e);
+ }
+ }
+
/**
* returns the name of this node
@@ -95,7 +119,7 @@
NodeState parent = (NodeState) stateMgr.getItemState(parentId);
name = parent.getChildNodeEntry(nodeState.getNodeId()).getName();
} catch (ItemStateException e) {
- // should never occurr
+ // should never occur
throw new IllegalStateException(e.toString());
}
}
@@ -121,6 +145,19 @@
}
/**
+ * Returns the parent node of this node
+ *
+ * @return the parent node of this node or <code>null</code> if root node
+ * @throws RepositoryException if an error occurs
+ */
+ public NodeStateEx getParent() throws RepositoryException {
+ if (nodeState.getParentId() == null) {
+ return null;
+ }
+ return getNode(nodeState.getParentId());
+ }
+
+ /**
* Returns the underlaying node state.
* @return the underlaying node state.
*/
@@ -132,6 +169,7 @@
* Returns the properties of this node
*
* @return the properties of this node
+ * @throws ItemStateException if an error occurs
*/
public PropertyState[] getProperties() throws ItemStateException {
Set<Name> set = nodeState.getPropertyNames();
@@ -147,7 +185,7 @@
/**
* Checks if the given property exists
*
- * @param name
+ * @param name name of the property
* @return <code>true</code> if the given property exists.
*/
public boolean hasProperty(Name name) {
@@ -158,7 +196,7 @@
/**
* Returns the values of the given property of <code>null</code>
*
- * @param name
+ * @param name name of the property
* @return the values of the given property.
*/
public InternalValue[] getPropertyValues(Name name) {
@@ -174,7 +212,7 @@
/**
* Returns the value of the given property or <code>null</code>
*
- * @param name
+ * @param name name of the property
* @return the value of the given property.
*/
public InternalValue getPropertyValue(Name name) {
@@ -190,9 +228,9 @@
/**
* Sets the property value
*
- * @param name
- * @param value
- * @throws RepositoryException
+ * @param name name of the property
+ * @param value value to set
+ * @throws RepositoryException if an error occurs
*/
public void setPropertyValue(Name name, InternalValue value)
throws RepositoryException {
@@ -202,10 +240,10 @@
/**
* Sets the property values
*
- * @param name
- * @param type
- * @param values
- * @throws RepositoryException
+ * @param name name of the property
+ * @param type property type
+ * @param values values to set
+ * @throws RepositoryException if an error occurs
*/
public void setPropertyValues(Name name, int type, InternalValue[] values)
throws RepositoryException {
@@ -215,56 +253,43 @@
/**
* Sets the property values
*
- * @param name
- * @param type
- * @param values
- * @throws RepositoryException
- */
- public void setPropertyValues(Name name, int type, InternalValue[] values, boolean multiple)
- throws RepositoryException {
-
- PropertyState prop = getOrCreatePropertyState(name, type, multiple);
- prop.setValues(values);
- }
-
-
- /**
- * Retrieves or creates a new property state as child property of this node
- *
- * @param name
- * @param type
- * @param multiValued
- * @return the property state
- * @throws RepositoryException
+ * @param name name of the property
+ * @param type type of the values
+ * @param values values to set
+ * @param multiple <code>true</code>for MV properties
+ * @return the modified property state
+ * @throws RepositoryException if an error occurs
*/
- private PropertyState getOrCreatePropertyState(Name name, int type, boolean multiValued)
+ public PropertyState setPropertyValues(Name name, int type, InternalValue[] values, boolean multiple)
throws RepositoryException {
-
PropertyId propId = new PropertyId(nodeState.getNodeId(), name);
if (stateMgr.hasItemState(propId)) {
try {
PropertyState propState = (PropertyState) stateMgr.getItemState(propId);
- // someone calling this method will always alter the property state, so set status to modified
if (propState.getStatus() == ItemState.STATUS_EXISTING) {
propState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
}
- // although this is not quite correct, we mark node as modified aswell
+ // although this is not quite correct, we mark node as modified as well
if (nodeState.getStatus() == ItemState.STATUS_EXISTING) {
nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
}
+ propState.setType(type);
+ propState.setValues(values);
return propState;
} catch (ItemStateException e) {
throw new RepositoryException("Unable to create property: " + e.toString());
}
} else {
+
+ PropDef pd = getEffectiveNodeType().getApplicablePropertyDef(name, type, multiple);
+
PropertyState propState = stateMgr.createNew(name, nodeState.getNodeId());
propState.setType(type);
- propState.setMultiValued(multiValued);
-
- PropDef pd = getEffectiveNodeType().getApplicablePropertyDef(name, type, multiValued);
+ propState.setMultiValued(multiple);
propState.setDefinitionId(pd.getId());
+ propState.setValues(values);
- // need to store nodestate
+ // need to store node state
nodeState.addPropertyName(name);
if (nodeState.getStatus() == ItemState.STATUS_EXISTING) {
nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
@@ -278,7 +303,7 @@
* of this node's primary and mixin node types.
*
* @return the effective node type
- * @throws RepositoryException
+ * @throws RepositoryException if an error occurs
*/
public EffectiveNodeType getEffectiveNodeType() throws RepositoryException {
try {
@@ -293,7 +318,7 @@
/**
* checks if the given child node exists.
*
- * @param name
+ * @param name name of the node
* @return <code>true</code> if the given child exists.
*/
public boolean hasNode(Name name) {
@@ -303,30 +328,53 @@
/**
* removes the (first) child node with the given name.
*
- * @param name
+ * @param name name of hte node
* @return <code>true</code> if the child was removed
- * @throws RepositoryException
+ * @throws RepositoryException if an error occurs
*/
public boolean removeNode(Name name) throws RepositoryException {
return removeNode(name, 1);
}
/**
+ * removes the given child node
+ *
+ * @param node child node to remove
+ * @return <code>true</code> if the child was removed
+ * @throws RepositoryException if an error occurs
+ */
+ public boolean removeNode(NodeStateEx node) throws RepositoryException {
+ // locate child node entry
+ return removeNode(nodeState.getChildNodeEntry(node.getNodeId()));
+ }
+
+
+ /**
* removes the child node with the given name and 1-based index
*
- * @param name
- * @param index
+ * @param name name of the child node
+ * @param index index of the child node
* @return <code>true</code> if the child was removed.
- * @throws RepositoryException
+ * @throws RepositoryException if an error occurs
*/
public boolean removeNode(Name name, int index) throws RepositoryException {
+ return removeNode(nodeState.getChildNodeEntry(name, index));
+ }
+
+ /**
+ * removes the child node with the given child node entry
+ *
+ * @param entry entry to remove
+ * @return <code>true</code> if the child was removed.
+ * @throws RepositoryException if an error occurs
+ */
+ public boolean removeNode(ChildNodeEntry entry) throws RepositoryException {
try {
- ChildNodeEntry entry = nodeState.getChildNodeEntry(name, index);
if (entry == null) {
return false;
} else {
removeNode(entry.getId());
- nodeState.removeChildNodeEntry(name, index);
+ nodeState.removeChildNodeEntry(entry.getId());
nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
return true;
}
@@ -338,8 +386,8 @@
/**
* removes recursively the node with the given id
*
- * @param id
- * @throws ItemStateException
+ * @param id node id
+ * @throws ItemStateException if an error occurs
*/
private void removeNode(NodeId id) throws ItemStateException {
NodeState state = (NodeState) stateMgr.getItemState(id);
@@ -365,9 +413,9 @@
/**
* removes the property with the given name
*
- * @param name
+ * @param name name of the property
* @return <code>true</code> if the property was removed.
- * @throws RepositoryException
+ * @throws RepositoryException if an error occurs
*/
public boolean removeProperty(Name name) throws RepositoryException {
try {
@@ -390,10 +438,10 @@
* retrieves the child node with the given name and 1-base index or
* <code>null</code> if the node does not exist.
*
- * @param name
- * @param index
+ * @param name name of hte child node
+ * @param index index of thechild node
* @return the node state.
- * @throws RepositoryException
+ * @throws RepositoryException if an error occurs
*/
public NodeStateEx getNode(Name name, int index) throws RepositoryException {
ChildNodeEntry entry = nodeState.getChildNodeEntry(name, index);
@@ -409,14 +457,57 @@
}
/**
+ * Returns the node with the given id.
+ * @param id node id
+ * @return the new node state
+ * @throws RepositoryException if an error occurs
+ */
+ public NodeStateEx getNode(NodeId id) throws RepositoryException {
+ try {
+ NodeState state = (NodeState) stateMgr.getItemState(id);
+ return new NodeStateEx(stateMgr, ntReg, state, name);
+ } catch (ItemStateException e) {
+ throw new RepositoryException("Unable to getNode: " + e.toString());
+ }
+ }
+
+ /**
+ * Checks if the given node state exists
+ * @param id node id
+ * @return <code>true</code> if the node state exists
+ */
+ public boolean hasNode(NodeId id) {
+ return stateMgr.hasItemState(id);
+ }
+
+ /**
* Adds a new child node with the given name
*
- * @param nodeName
- * @param nodeTypeName
+ * @param nodeName name of the new node
+ * @param nodeTypeName node type name
+ * @param id id of the new node
* @return the node state
- * @throws NoSuchNodeTypeException
- * @throws ConstraintViolationException
- * @throws RepositoryException
+ * @throws NoSuchNodeTypeException if the node type does not exist
+ * @throws ConstraintViolationException if there is a constraint violation
+ * @throws RepositoryException if an error occurs
+ */
+ public NodeStateEx addNode(Name nodeName, Name nodeTypeName, NodeId id)
+ throws NoSuchNodeTypeException, ConstraintViolationException, RepositoryException {
+ return addNode(nodeName, nodeTypeName, id,
+ ntReg.getEffectiveNodeType(nodeTypeName).includesNodeType(NameConstants.MIX_REFERENCEABLE));
+ }
+
+ /**
+ * Adds a new child node with the given name
+ *
+ * @param nodeName name of the new node
+ * @param nodeTypeName node type name
+ * @param id id of the new node
+ * @param referenceable if <code>true</code>, a UUID property is created
+ * @return the node state
+ * @throws NoSuchNodeTypeException if the node type does not exist
+ * @throws ConstraintViolationException if there is a constraint violation
+ * @throws RepositoryException if an error occurs
*/
public NodeStateEx addNode(Name nodeName, Name nodeTypeName,
NodeId id, boolean referenceable)
@@ -445,9 +536,11 @@
/**
* creates a new child node
*
- * @param name
- * @param id
+ * @param name name
+ * @param nodeTypeName node type name
+ * @param id id
* @return the newly created node.
+ * @throws RepositoryException if an error occurs
*/
private NodeStateEx createChildNode(Name name, Name nodeTypeName, NodeId id)
throws RepositoryException {
@@ -475,10 +568,119 @@
}
/**
+ * Moves the source node to this node using the given name.
+ * @param src shareable source node
+ * @param name name of new node
+ * @param createShare if <code>true</code> a share is created instead.
+ * @return child node
+ * @throws RepositoryException if an error occurs
+ */
+ public NodeStateEx moveFrom(NodeStateEx src, Name name, boolean createShare)
+ throws RepositoryException {
+ if (name == null) {
+ name = src.getName();
+ }
+ // (4) check for name collisions
+ NodeDef def;
+ try {
+ def = getEffectiveNodeType().getApplicableChildNodeDef(name, nodeState.getNodeTypeName(), ntReg);
+ } catch (RepositoryException re) {
+ String msg = "no definition found in parent node's node type for new node";
+ throw new ConstraintViolationException(msg, re);
+ }
+ ChildNodeEntry cne = nodeState.getChildNodeEntry(name, 1);
+ if (cne != null) {
+ // there's already a child node entry with that name;
+ // check same-name sibling setting of new node
+ if (!def.allowsSameNameSiblings()) {
+ throw new ItemExistsException(getNodeId() + "/" + name);
+ }
+ NodeState existingChild;
+ try {
+ // check same-name sibling setting of existing node
+ existingChild = (NodeState) stateMgr.getItemState(cne.getId());
+ } catch (ItemStateException e) {
+ throw new RepositoryException(e);
+ }
+ if (!ntReg.getNodeDef(existingChild.getDefinitionId()).allowsSameNameSiblings()) {
+ throw new ItemExistsException(existingChild.toString());
+ }
+ } else {
+ // check if 'add' is allowed
+ if (getDefinition().isProtected()) {
+ String msg = "not allowed to modify a protected node";
+ throw new ConstraintViolationException(msg);
+ }
+ }
+
+ if (createShare) {
+ // (5) do clone operation
+ NodeId parentId = getNodeId();
+ src.addShareParent(parentId);
+ // attach to this parent
+ nodeState.addChildNodeEntry(name, src.getNodeId());
+ if (nodeState.getStatus() == ItemState.STATUS_EXISTING) {
+ nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
+ }
+ return new NodeStateEx(stateMgr, ntReg, src.getState(), name);
+ } else {
+ // detach from parent
+ NodeStateEx parent = getNode(src.getParentId());
+ parent.nodeState.removeChildNodeEntry(src.getNodeId());
+ if (parent.nodeState.getStatus() == ItemState.STATUS_EXISTING) {
+ parent.nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
+ }
+ // attach to this parent
+ nodeState.addChildNodeEntry(name, src.getNodeId());
+ if (nodeState.getStatus() == ItemState.STATUS_EXISTING) {
+ nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
+ }
+ NodeState srcState = src.getState();
+ srcState.setParentId(getNodeId());
+ srcState.setDefinitionId(def.getId());
+
+ if (srcState.getStatus() == ItemState.STATUS_EXISTING) {
+ srcState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
+ }
+ return new NodeStateEx(stateMgr, ntReg, srcState, name);
+ }
+ }
+
+ /**
+ * Adds a share parent id
+ * @param parentId the parent id
+ * @throws RepositoryException if an error occurs
+ */
+ private void addShareParent(NodeId parentId) throws RepositoryException {
+ // verify that we're shareable
+ if (!nodeState.isShareable()) {
+ String msg = this + " is not shareable.";
+ throw new RepositoryException(msg);
+ }
+
+ // detect share cycle (TODO)
+ // NodeId srcId = getNodeId();
+ //HierarchyManager hierMgr = session.getHierarchyManager();
+ //if (parentId.equals(srcId) || hierMgr.isAncestor(srcId, parentId)) {
+ // String msg = "This would create a share cycle.";
+ // log.debug(msg);
+ // throw new RepositoryException(msg);
+ //}
+
+ if (!nodeState.containsShare(parentId)) {
+ if (nodeState.addShare(parentId)) {
+ return;
+ }
+ }
+ String msg = "Adding a shareable node twice to the same parent is not supported.";
+ throw new UnsupportedRepositoryOperationException(msg);
+ }
+
+ /**
* returns all child nodes
*
* @return the child nodes.
- * @throws RepositoryException
+ * @throws RepositoryException if an error occurs
*/
public NodeStateEx[] getChildNodes() throws RepositoryException {
try {
@@ -498,7 +700,7 @@
/**
* stores the persistent state recursively
*
- * @throws RepositoryException
+ * @throws RepositoryException if an error occurs
*/
public void store() throws RepositoryException {
try {
@@ -511,8 +713,8 @@
/**
* stores the given persistent state recursively
*
- * @param state
- * @throws ItemStateException
+ * @param state node state to store
+ * @throws ItemStateException if an error occurs
*/
private void store(NodeState state)
throws ItemStateException {
@@ -539,12 +741,12 @@
/**
* reloads the persistent state recursively
*
- * @throws RepositoryException
+ * @throws RepositoryException if an error occurs
*/
public void reload() throws RepositoryException {
try {
reload(nodeState);
- // refetch nodestate if discarded
+ // refetch node state if discarded
nodeState = (NodeState) stateMgr.getItemState(nodeState.getNodeId());
} catch (ItemStateException e) {
throw new RepositoryException(e);
@@ -554,8 +756,8 @@
/**
* reloads the given persistent state recursively
*
- * @param state
- * @throws ItemStateException
+ * @param state node state
+ * @throws ItemStateException if an error occurs
*/
private void reload(NodeState state) throws ItemStateException {
if (state.getStatus() != ItemState.STATUS_EXISTING) {
@@ -580,8 +782,8 @@
/**
* copies a property
*
- * @param prop
- * @throws RepositoryException
+ * @param prop source property
+ * @throws RepositoryException if an error occurs
*/
public void copyFrom(PropertyImpl prop) throws RepositoryException {
if (prop.getDefinition().isMultiple()) {
@@ -596,4 +798,36 @@
}
}
+ /**
+ * copies a property
+ *
+ * @param prop source property
+ * @throws RepositoryException if an error occurs
+ */
+ public void copyFrom(PropertyState prop) throws RepositoryException {
+ InternalValue[] values = prop.getValues();
+ InternalValue[] copiedValues = new InternalValue[values.length];
+ for (int i = 0; i < values.length; i++) {
+ copiedValues[i] = values[i].createCopy();
+ }
+ setPropertyValues(prop.getName(), prop.getType(), copiedValues, prop.isMultiValued());
+ }
+
+ /**
+ * Returns the NodeDef for this state
+ * @return the node def
+ */
+ public NodeDef getDefinition() {
+ return ntReg.getNodeDef(nodeState.getDefinitionId());
+ }
+
+ /**
+ * Returns the property definition for the property state
+ * @param prop the property state
+ * @return the prop def
+ */
+ public PropDef getDefinition(PropertyState prop) {
+ return ntReg.getPropDef(prop.getDefinitionId());
+ }
+
}
Modified: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java?rev=795452&r1=795451&r2=795452&view=diff
==============================================================================
--- jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java (original)
+++ jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java Sun Jul 19 00:09:40 2009
@@ -62,20 +62,22 @@
* invokes the checkin() on the persistent version manager and remaps the
* newly created version objects.
*
+ * @param session session that invokes the checkin
* @param node node to checkin
* @return the newly created version
* @throws RepositoryException if an error occurs
*/
- Version checkin(NodeImpl node) throws RepositoryException;
+ InternalVersion checkin(Session session, NodeStateEx node) throws RepositoryException;
/**
* invokes the checkout() on the persistent version manager.
*
- * @param node node to checkout
- * @return the base version
+ * @param state node to checkout
+ * @param activityId node id if the current activity
+ * @return the base version id
* @throws RepositoryException if an error occurs
*/
- Version checkout(NodeImpl node) throws RepositoryException;
+ NodeId canCheckout(NodeStateEx state, NodeId activityId) throws RepositoryException;
/**
* Removes the specified version from the given version history.
Modified: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java?rev=795452&r1=795451&r2=795452&view=diff
==============================================================================
--- jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java (original)
+++ jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java Sun Jul 19 00:09:40 2009
@@ -23,20 +23,19 @@
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
+import javax.jcr.version.ActivityViolationException;
import javax.jcr.version.Version;
import javax.jcr.version.VersionException;
import javax.jcr.version.VersionHistory;
-import javax.jcr.version.ActivityViolationException;
import org.apache.commons.collections.map.ReferenceMap;
-import org.apache.jackrabbit.core.id.ItemId;
-import org.apache.jackrabbit.core.id.NodeId;
-import org.apache.jackrabbit.core.NodeImpl;
-import org.apache.jackrabbit.core.id.PropertyId;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.cluster.UpdateEventChannel;
import org.apache.jackrabbit.core.cluster.UpdateEventListener;
import org.apache.jackrabbit.core.fs.FileSystem;
+import org.apache.jackrabbit.core.id.ItemId;
+import org.apache.jackrabbit.core.id.NodeId;
+import org.apache.jackrabbit.core.id.PropertyId;
import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
import org.apache.jackrabbit.core.observation.DelegatingObservationDispatcher;
import org.apache.jackrabbit.core.observation.EventState;
@@ -51,10 +50,10 @@
import org.apache.jackrabbit.core.state.ItemStateException;
import org.apache.jackrabbit.core.state.ItemStateListener;
import org.apache.jackrabbit.core.state.LocalItemStateManager;
+import org.apache.jackrabbit.core.state.NodeReferences;
import org.apache.jackrabbit.core.state.NodeState;
import org.apache.jackrabbit.core.state.PropertyState;
import org.apache.jackrabbit.core.state.SharedItemStateManager;
-import org.apache.jackrabbit.core.state.NodeReferences;
import org.apache.jackrabbit.core.value.InternalValue;
import org.apache.jackrabbit.core.virtual.VirtualItemStateProvider;
import org.apache.jackrabbit.spi.Name;
@@ -357,10 +356,9 @@
* checks if the checkout is valid in respect to a possible activity set on
* the session
*/
- public Version checkout(NodeImpl node) throws RepositoryException {
- NodeId baseId = NodeId.valueOf(node.getProperty(NameConstants.JCR_BASEVERSION).getString());
- NodeImpl activity = (NodeImpl) node.getSession().getWorkspace().getVersionManager().getActivity();
- if (activity != null) {
+ public NodeId canCheckout(NodeStateEx state, NodeId activityId) throws RepositoryException {
+ NodeId baseId = state.getPropertyValue(NameConstants.JCR_BASEVERSION).getNodeId();
+ if (activityId != null) {
// If there exists another workspace with node N' where N' also has version
// history H, N' is checked out and the jcr:activity property of N'
// references A, then the checkout fails with an
@@ -369,10 +367,9 @@
// we're currently leverage the fact, that only references to "real"
// workspaces are recorded.
- NodeId nodeId = activity.getNodeId();
- if (stateMgr.hasNodeReferences(nodeId)) {
+ if (stateMgr.hasNodeReferences(activityId)) {
try {
- NodeReferences refs = stateMgr.getNodeReferences(nodeId);
+ NodeReferences refs = stateMgr.getNodeReferences(activityId);
if (refs.hasReferences()) {
throw new ActivityViolationException("Unable to checkout. " +
"Activity is already used for the same node in " +
@@ -383,12 +380,11 @@
}
}
- // TODO:
// If there is a version in H that is not an eventual predecessor of N but
// whose jcr:activity references A, then the checkout fails with an
// ActivityViolationException
- InternalActivityImpl a = (InternalActivityImpl) getItem(nodeId);
- NodeId historyId = NodeId.valueOf(node.getProperty(NameConstants.JCR_VERSIONHISTORY).getString());
+ InternalActivityImpl a = (InternalActivityImpl) getItem(activityId);
+ NodeId historyId = state.getPropertyValue(NameConstants.JCR_VERSIONHISTORY).getNodeId();
InternalVersionHistory history = (InternalVersionHistory) getItem(historyId);
InternalVersion version = a.getLatestVersion(history);
if (version != null) {
@@ -402,8 +398,7 @@
}
}
}
- return (VersionImpl)
- ((SessionImpl) node.getSession()).getNodeById(baseId);
+ return baseId;
}
/**
@@ -412,16 +407,17 @@
* This method must not be synchronized since it could cause deadlocks with
* item-reading listeners in the observation thread.
*/
- public Version checkin(final NodeImpl node) throws RepositoryException {
- InternalVersion version = (InternalVersion)
- escFactory.doSourced((SessionImpl) node.getSession(), new SourcedTarget() {
+ public InternalVersion checkin(final Session session, final NodeStateEx node)
+ throws RepositoryException {
+ return (InternalVersion)
+ escFactory.doSourced((SessionImpl) session, new SourcedTarget() {
public Object run() throws RepositoryException {
InternalVersionHistory vh;
- if (node.isNodeType(NameConstants.MIX_VERSIONABLE)) {
+ if (node.getEffectiveNodeType().includesNodeType(NameConstants.MIX_VERSIONABLE)) {
// in full versioning, the history id can be retrieved via
// the property
- String histUUID = node.getProperty(NameConstants.JCR_VERSIONHISTORY).getString();
- vh = getVersionHistory(NodeId.valueOf(histUUID));
+ NodeId histId = node.getPropertyValue(NameConstants.JCR_VERSIONHISTORY).getNodeId();
+ vh = getVersionHistory(histId);
return internalCheckin((InternalVersionHistoryImpl) vh, node, false);
} else {
// in simple versioning the history id needs to be calculated
@@ -430,9 +426,6 @@
}
}
});
-
- return (VersionImpl)
- ((SessionImpl) node.getSession()).getNodeById(version.getId());
}
/**
Modified: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionSelector.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionSelector.java?rev=795452&r1=795451&r2=795452&view=diff
==============================================================================
--- jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionSelector.java (original)
+++ jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionSelector.java Sun Jul 19 00:09:40 2009
@@ -17,8 +17,6 @@
package org.apache.jackrabbit.core.version;
import javax.jcr.RepositoryException;
-import javax.jcr.version.Version;
-import javax.jcr.version.VersionHistory;
/**
* This Interface defines the version selector that needs to provide a version,
@@ -42,10 +40,7 @@
*
* @see DateVersionSelector
* @see LabelVersionSelector
- * @see org.apache.jackrabbit.core.NodeImpl#restore(String, boolean)
- * @see org.apache.jackrabbit.core.NodeImpl#restore(Version, boolean)
- * @see org.apache.jackrabbit.core.NodeImpl#restore(Version, String, boolean)
- * @see org.apache.jackrabbit.core.NodeImpl#restoreByLabel(String, boolean)
+ * @see javax.jcr.version.VersionManager#restore
*
*/
public interface VersionSelector {
@@ -59,6 +54,6 @@
* @return A version or <code>null</code>.
* @throws RepositoryException if an error occurs.
*/
- Version select(VersionHistory versionHistory) throws RepositoryException;
+ InternalVersion select(InternalVersionHistory versionHistory) throws RepositoryException;
}
Modified: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java?rev=795452&r1=795451&r2=795452&view=diff
==============================================================================
--- jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java (original)
+++ jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java Sun Jul 19 00:09:40 2009
@@ -208,31 +208,32 @@
/**
* {@inheritDoc}
*/
- public Version checkout(NodeImpl node) throws RepositoryException {
- return vMgr.checkout(node);
+ public NodeId canCheckout(NodeStateEx state, NodeId activityId) throws RepositoryException {
+ return vMgr.canCheckout(state, activityId);
}
/**
* {@inheritDoc}
*/
- public Version checkin(NodeImpl node) throws RepositoryException {
+ public InternalVersion checkin(Session session, NodeStateEx node) throws RepositoryException {
if (isInXA()) {
InternalVersionHistory vh;
InternalVersion version;
- if (node.isNodeType(NameConstants.MIX_VERSIONABLE)) {
+ if (node.getEffectiveNodeType().includesNodeType(NameConstants.MIX_VERSIONABLE)) {
// in full versioning, the history id can be retrieved via
// the property
- String histUUID = node.getProperty(NameConstants.JCR_VERSIONHISTORY).getString();
- vh = getVersionHistory(NodeId.valueOf(histUUID));
+ NodeId histId = node.getPropertyValue(NameConstants.JCR_VERSIONHISTORY).getNodeId();
+ vh = getVersionHistory(histId);
version = internalCheckin((InternalVersionHistoryImpl) vh, node, false);
} else {
// in simple versioning the history id needs to be calculated
vh = getVersionHistoryOfNode(node.getNodeId());
version = internalCheckin((InternalVersionHistoryImpl) vh, node, true);
}
- return (Version) ((SessionImpl) node.getSession()).getNodeById(version.getId());
+ return version;
+ } else {
+ return vMgr.checkin(session, node);
}
- return vMgr.checkin(node);
}
/**
@@ -449,7 +450,7 @@
* Before modifying version history given, make a local copy of it.
*/
protected InternalVersion internalCheckin(InternalVersionHistoryImpl history,
- NodeImpl node, boolean simple)
+ NodeStateEx node, boolean simple)
throws RepositoryException {
if (history.getVersionManager() != this) {
Modified: jackrabbit/sandbox/tripod-JCR-2209/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/tripod-JCR-2209/pom.xml?rev=795452&r1=795451&r2=795452&view=diff
==============================================================================
--- jackrabbit/sandbox/tripod-JCR-2209/pom.xml (original)
+++ jackrabbit/sandbox/tripod-JCR-2209/pom.xml Sun Jul 19 00:09:40 2009
@@ -55,7 +55,7 @@
<module>jackrabbit-spi2jcr</module>
<module>jackrabbit-spi2dav</module>
<module>jackrabbit-jcr-client</module>
- <module>jackrabbit-standalone</module>
+ <!-- <module>jackrabbit-standalone</module> -->
</modules>
<scm>