You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2007/02/13 10:31:53 UTC
svn commit: r506927 [7/8] - in /jackrabbit/trunk/contrib/spi: jcr2spi/
jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/
jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/
jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/ jcr2spi...
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/SessionItemStateManager.java Tue Feb 13 01:31:36 2007
@@ -42,14 +42,14 @@
import org.apache.jackrabbit.jcr2spi.operation.AddLabel;
import org.apache.jackrabbit.jcr2spi.operation.RemoveLabel;
import org.apache.jackrabbit.jcr2spi.operation.RemoveVersion;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.apache.jackrabbit.name.QName;
import org.apache.jackrabbit.spi.QPropertyDefinition;
import org.apache.jackrabbit.spi.QNodeDefinition;
-import org.apache.jackrabbit.spi.ItemId;
-import org.apache.jackrabbit.spi.IdFactory;
import org.apache.jackrabbit.spi.QValue;
import org.apache.jackrabbit.spi.QValueFactory;
import org.apache.jackrabbit.uuid.UUID;
@@ -73,11 +73,7 @@
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.lock.LockException;
import java.util.Iterator;
-import java.util.Set;
-import java.util.HashSet;
import java.util.Calendar;
-import java.util.Collection;
-import java.util.Collections;
import java.io.InputStream;
/**
@@ -107,145 +103,21 @@
* @param workspaceItemStateMgr
*/
public SessionItemStateManager(UpdatableItemStateManager workspaceItemStateMgr,
- IdFactory idFactory,
ItemStateValidator validator,
- QValueFactory qValueFactory) {
+ QValueFactory qValueFactory,
+ ItemStateFactory isf) {
+
this.workspaceItemStateMgr = workspaceItemStateMgr;
- this.transientStateMgr = new TransientItemStateManager(idFactory, workspaceItemStateMgr);
+ this.transientStateMgr = new TransientItemStateManager();
+ isf.addCreationListener(transientStateMgr);
+
this.validator = validator;
this.qValueFactory = qValueFactory;
}
- //---------------------------------------------------< ItemStateManager >---
- /**
- * {@inheritDoc}
- * @see ItemStateManager#getRootState()
- */
- public NodeState getRootState() throws ItemStateException {
- // always retrieve from transientStateMgr
- return transientStateMgr.getRootState();
- }
-
- /**
- * {@inheritDoc}
- * @see ItemStateManager#getItemState(ItemId)
- */
- public ItemState getItemState(ItemId id)
- throws NoSuchItemStateException, ItemStateException {
-
- ItemState itemState = transientStateMgr.getItemState(id);
- // check status of ItemState. Transient ISM also returns removed ItemStates
- if (itemState.isValid()) {
- return itemState;
- } else {
- throw new NoSuchItemStateException(id.toString());
- }
- }
-
- /**
- * {@inheritDoc}
- * @see ItemStateManager#hasItemState(ItemId)
- */
- public boolean hasItemState(ItemId id) {
- // first check if the specified item exists at all in the transient ISM
- if (transientStateMgr.hasItemState(id)) {
- // retrieve item and check state
- try {
- ItemState itemState = transientStateMgr.getItemState(id);
- if (itemState.isValid()) {
- return true;
- }
- } catch (ItemStateException e) {
- // has been removed in the meantime
- }
- }
- return false;
- }
-
- /**
- * {@inheritDoc}
- * Since node references cannot be managed within the transient space,
- * this call is delegated to the workspace itemstate manager.
- *
- * @see ItemStateManager#getReferingStates(NodeState)
- * @param nodeState
- */
- public Collection getReferingStates(NodeState nodeState) throws ItemStateException {
- NodeState wspState = (NodeState) nodeState.getWorkspaceState();
- if (wspState == null) {
- // new state => unable to determine references
- return Collections.EMPTY_SET;
- }
-
- Collection rs = workspaceItemStateMgr.getReferingStates(wspState);
- if (rs.isEmpty()) {
- return rs;
- } else {
- // retrieve session-propertystates
- Set refStates = new HashSet();
- for (Iterator it = rs.iterator(); it.hasNext();) {
- PropertyState wState = (PropertyState) it.next();
- ItemState sState = wState.getSessionState();
- if (sState == null) {
- // overlaying state has not been build up to now
- sState = getItemState(wState.getPropertyId());
- }
- // add property state to list of refering states unless it has
- // be removed in the transient layer.
- if (sState.isValid()) {
- refStates.add(sState);
- }
- }
- return Collections.unmodifiableCollection(refStates);
- }
- }
-
- /**
- * {@inheritDoc}
- * Since node references cannot be managed within the transient space,
- * this call is delegated to the workspace itemstate manager.
- *
- * @see ItemStateManager#hasReferingStates(NodeState)
- * @param nodeState
- */
- public boolean hasReferingStates(NodeState nodeState) {
- try {
- return !getReferingStates(nodeState).isEmpty();
- } catch (ItemStateException e) {
- log.warn("Internal error", e);
- return false;
- }
- }
-
- //------------------------------------------< UpdatableItemStateManager >---
- /**
- * {@inheritDoc}
- */
- public void execute(Operation operation) throws RepositoryException {
- operation.accept(this);
- }
-
- /**
- * {@inheritDoc}
- */
- public void execute(ChangeLog changes) throws RepositoryException {
- throw new UnsupportedOperationException("Not implemented for SessionItemStateManager");
- }
-
- /**
- * {@inheritDoc}
- */
- public void dispose() {
- // discard all transient changes
- transientStateMgr.dispose();
- // dispose our (i.e. 'local') state manager
- workspaceItemStateMgr.dispose();
- }
-
- //--------------------------------------------------------------------------
/**
* @return <code>true</code> if this manager has any transient state;
- * <code>false</code> otherwise.
+ * <code>false</code> otherwise.
*/
public boolean hasPendingChanges() {
return transientStateMgr.hasPendingChanges();
@@ -285,9 +157,8 @@
*
* @param itemState the root state of the cancel operation.
* @throws ItemStateException if undoing changes made to <code>state</code>
- * and descendant items is not a closed set of
- * changes. That is, at least another item needs
- * to be canceled as well in another sub-tree.
+ * and descendant items is not a closed set of changes. That is, at least
+ * another item needs to be canceled as well in another sub-tree.
*/
public void undo(ItemState itemState) throws ItemStateException, ConstraintViolationException {
ChangeLog changeLog = getChangeLog(itemState, false);
@@ -298,7 +169,7 @@
IteratorChain chain = new IteratorChain(its);
while (chain.hasNext()) {
ItemState state = (ItemState) chain.next();
- state.revert();
+ state.getHierarchyEntry().revert();
}
// remove transient states and related operations from the t-statemanager
@@ -308,7 +179,8 @@
}
/**
- * Adjust references at the end of a successful {@link Session#importXML(String, InputStream, int) XML import}.
+ * Adjust references at the end of a successful
+ * {@link Session#importXML(String, InputStream, int) XML import}.
*
* @param refTracker
* @throws ConstraintViolationException
@@ -343,46 +215,38 @@
refTracker.clear();
}
- //-------------------------------------------< Transient state handling >---
-
+ //------------------------------------------< UpdatableItemStateManager >---
/**
- *
- * @param itemState
- * @param throwOnStale Throws StaleItemStateException if either the given
- * <code>ItemState</code> or any of its decendants is stale and the flag is true.
- * @return
- * @throws StaleItemStateException if a stale <code>ItemState</code> is
- * encountered while traversing the state hierarchy. The <code>changeLog</code>
- * might have been populated with some transient item states. A client should
- * therefore not reuse the <code>changeLog</code> if such an exception is thrown.
- * @throws ItemStateException if <code>state</code> is a new item state.
+ * {@inheritDoc}
+ * @see UpdatableItemStateManager#execute(Operation)
*/
- private ChangeLog getChangeLog(ItemState itemState, boolean throwOnStale) throws StaleItemStateException, ItemStateException, ConstraintViolationException {
- // build changelog for affected and decendant states only
- ChangeLog changeLog = new ChangeLog(itemState);
- // fail-fast test: check status of this item's state
- if (itemState.getStatus() == Status.NEW) {
- String msg = "Cannot save an item with status NEW (" +itemState+ ").";
- log.debug(msg);
- throw new ItemStateException(msg);
- }
- if (throwOnStale && Status.isStale(itemState.getStatus())) {
- String msg = "Attempt to save an item, that has been externally modified (" +itemState+ ").";
- log.debug(msg);
- throw new StaleItemStateException(msg);
- }
- // collect transient/stale states that should be persisted or reverted
- itemState.collectStates(changeLog, throwOnStale);
+ public void execute(Operation operation) throws RepositoryException {
+ operation.accept(this);
+ }
- changeLog.collectOperations(transientStateMgr.getOperations());
- changeLog.checkIsSelfContained();
- return changeLog;
+ /**
+ * {@inheritDoc}
+ * @see UpdatableItemStateManager#execute(ChangeLog)
+ */
+ public void execute(ChangeLog changes) throws RepositoryException {
+ throw new UnsupportedOperationException("Not implemented for SessionItemStateManager");
}
- //--------------------------------------------------------------------------
+ /**
+ * {@inheritDoc}
+ * @see UpdatableItemStateManager#dispose()
+ */
+ public void dispose() {
+ // discard all transient changes
+ transientStateMgr.dispose();
+ // dispose our (i.e. 'local') state manager
+ workspaceItemStateMgr.dispose();
+ }
+ //---------------------------------------------------< OperationVisitor >---
/**
* @inheritDoc
+ * @see OperationVisitor#visit(AddNode)
*/
public void visit(AddNode operation) throws LockException, ConstraintViolationException, AccessDeniedException, ItemExistsException, NoSuchNodeTypeException, UnsupportedRepositoryOperationException, VersionException, RepositoryException {
int options = ItemStateValidator.CHECK_LOCK | ItemStateValidator.CHECK_COLLISION
@@ -397,11 +261,12 @@
/**
* @inheritDoc
+ * @see OperationVisitor#visit(AddProperty)
*/
public void visit(AddProperty operation) throws ValueFormatException, LockException, ConstraintViolationException, AccessDeniedException, ItemExistsException, UnsupportedRepositoryOperationException, VersionException, RepositoryException {
NodeState parent = operation.getParentState();
QName propertyName = operation.getPropertyName();
- QPropertyDefinition pDef = validator.getApplicablePropertyDefinition(propertyName, operation.getPropertyType(), operation.isMultiValued(), parent);
+ QPropertyDefinition pDef = operation.getDefinition();
int targetType = pDef.getRequiredType();
if (targetType == PropertyType.UNDEFINED) {
targetType = operation.getPropertyType();
@@ -420,6 +285,7 @@
/**
* @inheritDoc
+ * @see OperationVisitor#visit(Move)
*/
public void visit(Move operation) throws LockException, ConstraintViolationException, AccessDeniedException, ItemExistsException, UnsupportedRepositoryOperationException, VersionException, RepositoryException {
@@ -453,6 +319,7 @@
/**
* @inheritDoc
+ * @see OperationVisitor#visit(Remove)
*/
public void visit(Remove operation) throws ConstraintViolationException, AccessDeniedException, UnsupportedRepositoryOperationException, VersionException, RepositoryException {
ItemState state = operation.getRemoveState();
@@ -460,61 +327,68 @@
| ItemStateValidator.CHECK_VERSIONING
| ItemStateValidator.CHECK_CONSTRAINTS;
removeItemState(state, options);
- // remember operation unless new state got removed
+ // unless new state got removed remember operation and mark parent modified.
if (!Status.isTerminal(state.getStatus())) {
transientStateMgr.addOperation(operation);
+ operation.getParentState().markModified();
}
}
/**
* @inheritDoc
+ * @see OperationVisitor#visit(SetMixin)
*/
public void visit(SetMixin operation) throws ConstraintViolationException, AccessDeniedException, NoSuchNodeTypeException, UnsupportedRepositoryOperationException, VersionException, RepositoryException {
// NOTE: nodestate is only modified upon save of the changes!
QName[] mixinNames = operation.getMixinNames();
NodeState nState = operation.getNodeState();
+ NodeEntry nEntry = (NodeEntry) nState.getHierarchyEntry();
- // new array of mixinNames to be set on the nodestate (and corresponding property state)
- if (mixinNames != null && mixinNames.length > 0) {
- // update/create corresponding property state
- if (nState.hasPropertyName(QName.JCR_MIXINTYPES)) {
- // execute value of existing property
- try {
- PropertyState pState = nState.getPropertyState(QName.JCR_MIXINTYPES);
+ try {
+ // new array of mixinNames to be set on the nodestate (and corresponding property state)
+ PropertyEntry mixinEntry = nEntry.getPropertyEntry(QName.JCR_MIXINTYPES);
+ if (mixinNames != null && mixinNames.length > 0) {
+ // update/create corresponding property state
+ if (mixinEntry != null) {
+ // execute value of existing property
+ PropertyState pState = mixinEntry.getPropertyState();
int options = ItemStateValidator.CHECK_LOCK | ItemStateValidator.CHECK_VERSIONING;
setPropertyStateValue(pState, getQValues(mixinNames, qValueFactory), PropertyType.NAME, options);
- } catch (ItemStateException e) {
- // should not occur, since existance has been asserted before
- throw new RepositoryException(e);
+ } else {
+ // create new jcr:mixinTypes property
+ EffectiveNodeType ent = validator.getEffectiveNodeType(nState);
+ QPropertyDefinition pd = ent.getApplicablePropertyDefinition(QName.JCR_MIXINTYPES, PropertyType.NAME, true);
+ QValue[] mixinValue = getQValues(mixinNames, qValueFactory);
+ int options = ItemStateValidator.CHECK_LOCK | ItemStateValidator.CHECK_VERSIONING;
+ addPropertyState(nState, pd.getQName(), pd.getRequiredType(), mixinValue, pd, options);
}
+ nState.markModified();
+ transientStateMgr.addOperation(operation);
} else {
- // create new jcr:mixinTypes property
- EffectiveNodeType ent = validator.getEffectiveNodeType(nState);
- QPropertyDefinition pd = ent.getApplicablePropertyDefinition(QName.JCR_MIXINTYPES, PropertyType.NAME, true);
- QValue[] mixinValue = getQValues(mixinNames, qValueFactory);
- int options = ItemStateValidator.CHECK_LOCK | ItemStateValidator.CHECK_VERSIONING;
- addPropertyState(nState, pd.getQName(), pd.getRequiredType(), mixinValue, pd, options);
- }
- } else {
- // remove the jcr:mixinTypes property state if already present
- if (nState.hasPropertyName(QName.JCR_MIXINTYPES)) {
- try {
- PropertyState pState = nState.getPropertyState(QName.JCR_MIXINTYPES);
+ // remove the jcr:mixinTypes property state if already present
+ if (mixinEntry != null) {
+ PropertyState pState = mixinEntry.getPropertyState();
+ boolean newMixinState = pState.getStatus() == Status.NEW;
int options = ItemStateValidator.CHECK_LOCK | ItemStateValidator.CHECK_VERSIONING;
removeItemState(pState, options);
- } catch (ItemStateException e) {
- // should not occur, since existance has been asserted before
- throw new RepositoryException(e);
+ // only added the remove-mixin operation if it doesn't revert
+ // a previous 'add-mixin' (which has been removed automatically
+ // upon notification of removing the prop-state).
+ if (!newMixinState) {
+ nState.markModified();
+ transientStateMgr.addOperation(operation);
+ }
}
}
+ } catch (ItemStateException e) {
+ // should not occur, since existance has been asserted before
+ throw new RepositoryException(e);
}
-
- nState.markModified();
- transientStateMgr.addOperation(operation);
}
/**
* @inheritDoc
+ * @see OperationVisitor#visit(SetPropertyValue)
*/
public void visit(SetPropertyValue operation) throws ValueFormatException, LockException, ConstraintViolationException, AccessDeniedException, ItemExistsException, UnsupportedRepositoryOperationException, VersionException, RepositoryException {
PropertyState pState = operation.getPropertyState();
@@ -527,6 +401,7 @@
/**
* @inheritDoc
+ * @see OperationVisitor#visit(ReorderNodes)
*/
public void visit(ReorderNodes operation) throws ConstraintViolationException, AccessDeniedException, UnsupportedRepositoryOperationException, VersionException, RepositoryException {
NodeState parent = operation.getParentState();
@@ -541,58 +416,114 @@
transientStateMgr.addOperation(operation);
}
+ /**
+ * @throws UnsupportedOperationException
+ * @see OperationVisitor#visit(Clone)
+ */
public void visit(Clone operation) throws NoSuchWorkspaceException, LockException, ConstraintViolationException, AccessDeniedException, ItemExistsException, UnsupportedRepositoryOperationException, VersionException, RepositoryException {
throw new UnsupportedOperationException("Internal error: Clone cannot be handled by session ItemStateManager.");
}
+ /**
+ * @throws UnsupportedOperationException
+ * @see OperationVisitor#visit(Clone)
+ */
public void visit(Copy operation) throws NoSuchWorkspaceException, LockException, ConstraintViolationException, AccessDeniedException, ItemExistsException, UnsupportedRepositoryOperationException, VersionException, RepositoryException {
throw new UnsupportedOperationException("Internal error: Copy cannot be handled by session ItemStateManager.");
}
+ /**
+ * @throws UnsupportedOperationException
+ * @see OperationVisitor#visit(Clone)
+ */
public void visit(Checkout operation) throws RepositoryException, UnsupportedRepositoryOperationException {
throw new UnsupportedOperationException("Internal error: Checkout cannot be handled by session ItemStateManager.");
}
+ /**
+ * @throws UnsupportedOperationException
+ * @see OperationVisitor#visit(Clone)
+ */
public void visit(Checkin operation) throws UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
throw new UnsupportedOperationException("Internal error: Checkin cannot be handled by session ItemStateManager.");
}
+ /**
+ * @throws UnsupportedOperationException
+ * @see OperationVisitor#visit(Update)
+ */
public void visit(Update operation) throws NoSuchWorkspaceException, AccessDeniedException, LockException, InvalidItemStateException, RepositoryException {
throw new UnsupportedOperationException("Internal error: Update cannot be handled by session ItemStateManager.");
}
+ /**
+ * @throws UnsupportedOperationException
+ * @see OperationVisitor#visit(Restore)
+ */
public void visit(Restore operation) throws VersionException, PathNotFoundException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
throw new UnsupportedOperationException("Internal error: Restore cannot be handled by session ItemStateManager.");
}
+ /**
+ * @throws UnsupportedOperationException
+ * @see OperationVisitor#visit(Merge)
+ */
public void visit(Merge operation) throws NoSuchWorkspaceException, AccessDeniedException, MergeException, LockException, InvalidItemStateException, RepositoryException {
throw new UnsupportedOperationException("Internal error: Merge cannot be handled by session ItemStateManager.");
}
+ /**
+ * @throws UnsupportedOperationException
+ * @see OperationVisitor#visit(ResolveMergeConflict)
+ */
public void visit(ResolveMergeConflict operation) throws VersionException, InvalidItemStateException, UnsupportedRepositoryOperationException, RepositoryException {
throw new UnsupportedOperationException("Internal error: Update cannot be handled by session ItemStateManager.");
}
+ /**
+ * @throws UnsupportedOperationException
+ * @see OperationVisitor#visit(LockOperation)
+ */
public void visit(LockOperation operation) throws AccessDeniedException, InvalidItemStateException, UnsupportedRepositoryOperationException, LockException, RepositoryException {
throw new UnsupportedOperationException("Internal error: Lock cannot be handled by session ItemStateManager.");
}
+ /**
+ * @throws UnsupportedOperationException
+ * @see OperationVisitor#visit(LockRefresh)
+ */
public void visit(LockRefresh operation) throws AccessDeniedException, InvalidItemStateException, UnsupportedRepositoryOperationException, LockException, RepositoryException {
throw new UnsupportedOperationException("Internal error: LockRefresh cannot be handled by session ItemStateManager.");
}
+ /**
+ * @throws UnsupportedOperationException
+ * @see OperationVisitor#visit(LockRelease)
+ */
public void visit(LockRelease operation) throws AccessDeniedException, InvalidItemStateException, UnsupportedRepositoryOperationException, LockException, RepositoryException {
throw new UnsupportedOperationException("Internal error: LockRelease cannot be handled by session ItemStateManager.");
}
+ /**
+ * @throws UnsupportedOperationException
+ * @see OperationVisitor#visit(AddLabel)
+ */
public void visit(AddLabel operation) throws VersionException, RepositoryException {
throw new UnsupportedOperationException("Internal error: AddLabel cannot be handled by session ItemStateManager.");
}
+ /**
+ * @throws UnsupportedOperationException
+ * @see OperationVisitor#visit(RemoveLabel)
+ */
public void visit(RemoveLabel operation) throws VersionException, RepositoryException {
throw new UnsupportedOperationException("Internal error: RemoveLabel cannot be handled by session ItemStateManager.");
}
+ /**
+ * @throws UnsupportedOperationException
+ * @see OperationVisitor#visit(RemoveVersion)
+ */
public void visit(RemoveVersion operation) throws VersionException, AccessDeniedException, ReferentialIntegrityException, RepositoryException {
throw new UnsupportedOperationException("Internal error: RemoveVersion cannot be handled by session ItemStateManager.");
}
@@ -600,6 +531,40 @@
//--------------------------------------------< Internal State Handling >---
/**
*
+ * @param itemState
+ * @param throwOnStale Throws StaleItemStateException if either the given
+ * <code>ItemState</code> or any of its decendants is stale and the flag is true.
+ * @return
+ * @throws StaleItemStateException if a stale <code>ItemState</code> is
+ * encountered while traversing the state hierarchy. The <code>changeLog</code>
+ * might have been populated with some transient item states. A client should
+ * therefore not reuse the <code>changeLog</code> if such an exception is thrown.
+ * @throws ItemStateException if <code>state</code> is a new item state.
+ */
+ private ChangeLog getChangeLog(ItemState itemState, boolean throwOnStale) throws StaleItemStateException, ItemStateException, ConstraintViolationException {
+ // build changelog for affected and decendant states only
+ ChangeLog changeLog = new ChangeLog(itemState);
+ // fail-fast test: check status of this item's state
+ if (itemState.getStatus() == Status.NEW) {
+ String msg = "Cannot save an item with status NEW (" +itemState+ ").";
+ log.debug(msg);
+ throw new ItemStateException(msg);
+ }
+ if (throwOnStale && Status.isStale(itemState.getStatus())) {
+ String msg = "Attempt to save an item, that has been externally modified (" +itemState+ ").";
+ log.debug(msg);
+ throw new StaleItemStateException(msg);
+ }
+ // collect transient/stale states that should be persisted or reverted
+ itemState.getHierarchyEntry().collectStates(changeLog, throwOnStale);
+
+ changeLog.collectOperations(transientStateMgr.getOperations());
+ changeLog.checkIsSelfContained();
+ return changeLog;
+ }
+
+ /**
+ *
* @param parent
* @param propertyName
* @param propertyType
@@ -685,7 +650,7 @@
// recursively remove the given state and all child states.
boolean success = false;
try {
- itemState.remove();
+ itemState.getHierarchyEntry().transientRemove();
success = true;
} catch (ItemStateException e) {
throw new RepositoryException("Cannot remove item: " + e.getMessage(), e);
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/Status.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/Status.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/Status.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/Status.java Tue Feb 13 01:31:36 2007
@@ -18,6 +18,8 @@
*/
public final class Status {
+ public static final int _UNDEFINED_ = -1;
+
/**
* A state once read from persistent storage has been set to invalid. This
* means that the state needs to be re-fetched from persistent storage when
@@ -221,6 +223,9 @@
* @return Human readable status name for the given int.
*/
public static String getName(int status) {
+ if (status == _UNDEFINED_) {
+ return "_UNDEFINED_";
+ }
if (status < 0 || status >= STATUS_NAMES.length) {
throw new IllegalArgumentException("Invalid status " + status);
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientISFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientISFactory.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientISFactory.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientISFactory.java Tue Feb 13 01:31:36 2007
@@ -18,185 +18,178 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.jackrabbit.spi.IdFactory;
import org.apache.jackrabbit.spi.QNodeDefinition;
-import org.apache.jackrabbit.spi.QPropertyDefinition;
import org.apache.jackrabbit.spi.NodeId;
import org.apache.jackrabbit.spi.PropertyId;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
import org.apache.jackrabbit.name.QName;
-import org.apache.jackrabbit.jcr2spi.state.entry.ChildNodeEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
+import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeRegistry;
+
+import java.util.Iterator;
/**
* <code>TransientISFactory</code>...
*/
-final class TransientISFactory implements TransientItemStateFactory {
+public final class TransientISFactory extends AbstractItemStateFactory implements TransientItemStateFactory {
private static Logger log = LoggerFactory.getLogger(TransientISFactory.class);
- private final IdFactory idFactory;
- private final ItemStateManager workspaceItemStateMgr;
-
- private ItemStateCache cache;
- private ItemStateCreationListener listener;
+ private final ItemStateFactory workspaceStateFactory;
+ private final NodeTypeRegistry ntReg;
- TransientISFactory(IdFactory idFactory, ItemStateManager workspaceItemStateMgr) {
- this.idFactory = idFactory;
- this.workspaceItemStateMgr = workspaceItemStateMgr;
+ public TransientISFactory(ItemStateFactory workspaceStateFactory, NodeTypeRegistry ntReg) {
+ this.workspaceStateFactory = workspaceStateFactory;
+ this.ntReg = ntReg;
}
//------------------------------------------< TransientItemStateFactory >---
/**
* @inheritDoc
- * @see TransientItemStateFactory#createNewNodeState(QName, String, NodeState, QName, QNodeDefinition)
+ * @see TransientItemStateFactory#createNewNodeState(NodeEntry , QName, QNodeDefinition)
*/
- public NodeState createNewNodeState(QName name, String uniqueID,
- NodeState parent, QName nodetypeName,
+ public NodeState createNewNodeState(NodeEntry entry, QName nodetypeName,
QNodeDefinition definition) {
- NodeState nodeState = new NodeState(name, uniqueID, parent, nodetypeName,
- definition, Status.NEW, this, idFactory, false);
- // notify listeners when this item state is saved or invalidated
- nodeState.addListener(cache);
- nodeState.addListener(listener);
+ NodeState nodeState = new NodeState(entry, nodetypeName, QName.EMPTY_ARRAY, definition, Status.NEW, false, this, ntReg);
// notify listeners that a node state has been created
- cache.created(nodeState);
- listener.created(nodeState);
+ notifyCreated(nodeState);
return nodeState;
}
/**
* @inheritDoc
- * @see TransientItemStateFactory#createNewPropertyState(QName, NodeState, QPropertyDefinition)
+ * @see TransientItemStateFactory#createNewPropertyState(PropertyEntry, QPropertyDefinition)
*/
- public PropertyState createNewPropertyState(QName name, NodeState parent, QPropertyDefinition definition) {
- PropertyState propState = new PropertyState(name, parent,
- definition, Status.NEW, this, idFactory, false);
-
- // get a notification when this item state is saved or invalidated
- propState.addListener(cache);
- propState.addListener(listener);
+ public PropertyState createNewPropertyState(PropertyEntry entry, QPropertyDefinition definition) {
+ PropertyState propState = new PropertyState(entry, definition.isMultiple(), definition, Status.NEW, false, this, ntReg);
// notify listeners that a property state has been created
- cache.created(propState);
- listener.created(propState);
+ notifyCreated(propState);
return propState;
}
+ //---------------------------------------------------< ItemStateFactory >---
/**
* @inheritDoc
- * @see TransientItemStateFactory#setListener(ItemStateCreationListener)
+ * @see ItemStateFactory#createRootState(NodeEntry)
+ * @param entry
*/
- public void setListener(ItemStateCreationListener listener) {
- this.listener = listener;
+ public NodeState createRootState(NodeEntry entry) throws ItemStateException {
+ // retrieve state to overlay
+ NodeState overlayedState = (NodeState) workspaceStateFactory.createRootState(entry);
+ return buildNodeState(overlayedState, Status.EXISTING);
}
- //---------------------------------------------------< ItemStateFactory >---
/**
* @inheritDoc
- * @see ItemStateFactory#createRootState(ItemStateManager)
+ * @see ItemStateFactory#createNodeState(NodeId,NodeEntry)
*/
- public NodeState createRootState(ItemStateManager ism) throws ItemStateException {
+ public NodeState createNodeState(NodeId nodeId, NodeEntry entry)
+ throws NoSuchItemStateException, ItemStateException {
// retrieve state to overlay
- NodeState overlayedState = (NodeState) workspaceItemStateMgr.getRootState();
- NodeState nodeState = new NodeState(overlayedState, null, Status.EXISTING, this, idFactory);
+ NodeState overlayedState = (NodeState) workspaceStateFactory.createNodeState(nodeId, entry);
+ return buildNodeState(overlayedState, getInitialStatus(entry.getParent()));
+ }
- nodeState.addListener(cache);
- cache.created(nodeState);
- return nodeState;
+ /**
+ * @inheritDoc
+ * @see ItemStateFactory#createDeepNodeState(NodeId, NodeEntry)
+ */
+ public NodeState createDeepNodeState(NodeId nodeId, NodeEntry anyParent) throws NoSuchItemStateException, ItemStateException {
+ NodeState overlayedState = (NodeState) workspaceStateFactory.createDeepNodeState(nodeId, anyParent);
+ return buildNodeState(overlayedState, getInitialStatus(anyParent));
}
/**
* @inheritDoc
- * @see ItemStateFactory#createNodeState(NodeId, ItemStateManager)
+ * @see ItemStateFactory#createPropertyState(PropertyId, PropertyEntry)
*/
- public NodeState createNodeState(NodeId nodeId, ItemStateManager ism)
+ public PropertyState createPropertyState(PropertyId propertyId,
+ PropertyEntry entry)
throws NoSuchItemStateException, ItemStateException {
+ // retrieve state to overlay
+ PropertyState overlayedState = (PropertyState) workspaceStateFactory.createPropertyState(propertyId, entry);
+ return buildPropertyState(overlayedState, getInitialStatus(entry.getParent()));
+ }
- NodeState nodeState = cache.getNodeState(nodeId);
- if (nodeState == null) {
- // retrieve state to overlay
- NodeState overlayedState = (NodeState) workspaceItemStateMgr.getItemState(nodeId);
- NodeState overlayedParent = overlayedState.getParent();
-
- if (overlayedParent == null) {
- // special case root state
- return createRootState(ism);
- }
-
- NodeState parentState = (NodeState) overlayedParent.getSessionState();
- if (parentState == null) {
- parentState = (NodeState) ism.getItemState(overlayedParent.getId());
- }
+ /**
+ * @see ItemStateFactory#createDeepPropertyState(PropertyId, NodeEntry)
+ */
+ public PropertyState createDeepPropertyState(PropertyId propertyId, NodeEntry anyParent) throws NoSuchItemStateException, ItemStateException {
+ PropertyState overlayedState = (PropertyState) workspaceStateFactory.createDeepPropertyState(propertyId, anyParent);
+ return buildPropertyState(overlayedState, getInitialStatus(anyParent));
+ }
- ChildNodeEntry cne = parentState.getChildNodeEntry(nodeId);
- if (cne != null) {
- nodeState = cne.getNodeState();
- nodeState.addListener(cache);
- cache.created(nodeState);
- } else {
- throw new NoSuchItemStateException("No such item " + nodeId.toString());
- }
- }
- return nodeState;
+ /**
+ * @inheritDoc
+ * @see ItemStateFactory#getChildNodeInfos(NodeId)
+ * @param nodeId
+ */
+ public Iterator getChildNodeInfos(NodeId nodeId) throws NoSuchItemStateException, ItemStateException {
+ return workspaceStateFactory.getChildNodeInfos(nodeId);
}
/**
* @inheritDoc
- * @see ItemStateFactory#createNodeState(NodeId, NodeState)
+ * @see ItemStateFactory#getNodeReferences(NodeState)
+ * @param nodeState
*/
- public NodeState createNodeState(NodeId nodeId, NodeState parentState)
- throws NoSuchItemStateException, ItemStateException {
+ public NodeReferences getNodeReferences(NodeState nodeState) {
+ if (nodeState.getStatus() == Status.NEW) {
+ return EmptyNodeReferences.getInstance();
+ }
+
+ NodeState workspaceState = (NodeState) nodeState.getWorkspaceState();
+ return workspaceStateFactory.getNodeReferences(workspaceState);
+ }
- NodeState nodeState = cache.getNodeState(nodeId);
- if (nodeState == null) {
- // retrieve state to overlay
- NodeState overlayedState = (NodeState) workspaceItemStateMgr.getItemState(nodeId);
- nodeState = new NodeState(overlayedState, parentState, Status.EXISTING, this, idFactory);
+ //------------------------------------------------------------< private >---
+ /**
+ *
+ * @param overlayed
+ * @return
+ */
+ private NodeState buildNodeState(NodeState overlayed, int initialStatus) {
+ NodeState nodeState = new NodeState(overlayed, initialStatus, this);
- nodeState.addListener(cache);
- cache.created(nodeState);
- }
+ notifyCreated(nodeState);
return nodeState;
}
+
/**
- * @inheritDoc
- * @see ItemStateFactory#createPropertyState(PropertyId, NodeState)
+ *
+ * @param overlayed
+ * @return
*/
- public PropertyState createPropertyState(PropertyId propertyId,
- NodeState parentState)
- throws NoSuchItemStateException, ItemStateException {
-
- PropertyState propState = cache.getPropertyState(propertyId);
- if (propState == null) {
- // retrieve state to overlay
- PropertyState overlayedState = (PropertyState) workspaceItemStateMgr.getItemState(propertyId);
- propState = new PropertyState(overlayedState, parentState, Status.EXISTING, this, idFactory);
+ private PropertyState buildPropertyState(PropertyState overlayed, int initialStatus) {
+ PropertyState propState = new PropertyState(overlayed, initialStatus, this);
- propState.addListener(cache);
- cache.created(propState);
- }
+ notifyCreated(propState);
return propState;
}
- public ChildNodeEntries getChildNodeEntries(NodeState nodeState) throws NoSuchItemStateException, ItemStateException {
- if (nodeState.getStatus() == Status.NEW) {
- return new ChildNodeEntries(nodeState);
- } else {
- NodeState overlayed = (NodeState) nodeState.getWorkspaceState();
- ChildNodeEntries overlayedEntries = overlayed.isf.getChildNodeEntries(overlayed);
- return new ChildNodeEntries(nodeState, overlayedEntries);
- }
- }
-
/**
- * @inheritDoc
- * @see ItemStateFactory#setCache(ItemStateCache)
- */
- public void setCache(ItemStateCache cache) {
- this.cache = cache;
+ *
+ * @param parent
+ * @return
+ */
+ private static int getInitialStatus(NodeEntry parent) {
+ int status = Status.EXISTING;
+ // walk up hiearchy and check if any of the parents is transiently
+ // removed, in which case the status must be set to EXISTING_REMOVED.
+ while (parent != null) {
+ if (parent.getStatus() == Status.EXISTING_REMOVED) {
+ status = Status.EXISTING_REMOVED;
+ break;
+ }
+ parent = parent.getParent();
+ }
+ return status;
}
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateFactory.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateFactory.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateFactory.java Tue Feb 13 01:31:36 2007
@@ -17,8 +17,10 @@
package org.apache.jackrabbit.jcr2spi.state;
import org.apache.jackrabbit.name.QName;
-import org.apache.jackrabbit.spi.QPropertyDefinition;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
import org.apache.jackrabbit.spi.QNodeDefinition;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
/**
* <code>TransientItemStateFactory</code> extends the item state factory and
@@ -30,36 +32,22 @@
* Creates a transient child <code>NodeState</code> with the given
* <code>name</code>.
*
- * @param name the name of the <code>NodeState</code> to create.
- * @param uniqueID the unique ID of the <code>NodeState</code> to create or
- * <code>null</code> if the created <code>NodeState</code> cannot be
- * identified by a unique ID.
- * @param parent the parent of the <code>NodeState</code> to create.
- * @param nodeTypeName name of the primary nodetype
- * @param definition the definition for this new NodeState
- * @return the created <code>NodeState</code>.
+ * @param entry
+ * @param nodeTypeName
+ * @param definition
+ * @return the created <code>NodeState</code>
*/
- public NodeState createNewNodeState(QName name, String uniqueID,
- NodeState parent, QName nodeTypeName,
+ public NodeState createNewNodeState(NodeEntry entry,
+ QName nodeTypeName,
QNodeDefinition definition);
/**
- * Creates a transient <code>PropertyState</code> with the given
- * <code>name</code>.
+ * Creates a transient <code>PropertyState</code>.
*
- * @param name the name of the <code>PropertyState</code> to create.
- * @param parent the parent of the <code>PropertyState</code> to create.
- * @param definition definition for this new property state.
+ * @param entry
+ * @param definition
* @return the created <code>PropertyState</code>.
*/
- public PropertyState createNewPropertyState(QName name,
- NodeState parent,
+ public PropertyState createNewPropertyState(PropertyEntry entry,
QPropertyDefinition definition);
-
- /**
- * Set the listener that gets informed about NEW states.
- *
- * @param listener
- */
- public void setListener(ItemStateCreationListener listener);
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientItemStateManager.java Tue Feb 13 01:31:36 2007
@@ -17,9 +17,8 @@
package org.apache.jackrabbit.jcr2spi.state;
import org.apache.jackrabbit.jcr2spi.operation.Operation;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
import org.apache.jackrabbit.name.QName;
-import org.apache.jackrabbit.spi.ItemId;
-import org.apache.jackrabbit.spi.IdFactory;
import org.apache.jackrabbit.spi.QNodeDefinition;
import org.apache.jackrabbit.spi.QPropertyDefinition;
import org.apache.jackrabbit.spi.QValue;
@@ -30,21 +29,17 @@
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.ConstraintViolationException;
import java.util.Iterator;
-import java.util.Collection;
/**
- * <code>TransientItemStateManager</code> implements a {@link ItemStateManager}
- * and adds support for transient changes on {@link ItemState}s. This item
- * state manager also returns item states that are transiently deleted. It is
- * the responsiblity of the caller to check whether a certain item state is
- * still valid. This item state manager also provides methods to create new
- * item states. While all other modifications can be invoked on the item state
- * instances itself, creating a new node state is done using
+ * <code>TransientItemStateManager</code> adds support for transient changes on
+ * {@link ItemState}s and also provides methods to create new item states.
+ * While all other modifications can be invoked on the item state instances itself,
+ * creating a new node state is done using
* {@link #createNewNodeState(QName, String, QName, QNodeDefinition, NodeState)}
- * and {@link #createNewPropertyState(QName, NodeState, QPropertyDefinition, QValue[], int)}.
+ * and
+ * {@link #createNewPropertyState(QName, NodeState, QPropertyDefinition, QValue[], int)}.
*/
-public class TransientItemStateManager extends CachingItemStateManager
- implements ItemStateCreationListener {
+public class TransientItemStateManager implements ItemStateCreationListener {
/**
* Logger instance for this class.
@@ -58,24 +53,10 @@
private final ChangeLog changeLog;
/**
- * The root node state or <code>null</code> if it hasn't been retrieved yet.
- */
- private NodeState rootNodeState;
-
- /**
*
- * @param idFactory
- * @param parent
*/
- TransientItemStateManager(IdFactory idFactory, ItemStateManager parent) {
- super(new TransientISFactory(idFactory, parent), idFactory);
+ TransientItemStateManager() {
this.changeLog = new ChangeLog(null);
- getTransientFactory().setListener(this);
- }
-
-
- private TransientItemStateFactory getTransientFactory() {
- return (TransientItemStateFactory) getItemStateFactory();
}
/**
@@ -116,11 +97,15 @@
* @return a new transient {@link NodeState}.
*/
NodeState createNewNodeState(QName nodeName, String uniqueID, QName nodeTypeName,
- QNodeDefinition definition, NodeState parent) {
- NodeState nodeState = getTransientFactory().createNewNodeState(nodeName, uniqueID, parent, nodeTypeName, definition);
+ QNodeDefinition definition, NodeState parent)
+ throws ItemExistsException {
+
+ parent.checkIsSessionState();
+ NodeState nodeState = ((NodeEntry) parent.getHierarchyEntry()).addNewNodeEntry(nodeName, uniqueID, nodeTypeName, definition);
+ nodeState.addListener(this);
+
+ parent.markModified();
- parent.addChildNodeState(nodeState);
- changeLog.added(nodeState);
return nodeState;
}
@@ -141,12 +126,15 @@
QPropertyDefinition definition,
QValue[] values, int propertyType)
throws ItemExistsException, ConstraintViolationException, RepositoryException {
- PropertyState propState = getTransientFactory().createNewPropertyState(propName, parent, definition);
+
+ parent.checkIsSessionState();
+ PropertyState propState = ((NodeEntry) parent.getHierarchyEntry()).addNewPropertyEntry(propName, definition);
// NOTE: callers must make sure, the property type is not 'undefined'
propState.init(propertyType, values);
+ propState.addListener(this);
+
+ parent.markModified();
- parent.addPropertyState(propState);
- changeLog.added(propState);
return propState;
}
@@ -168,71 +156,6 @@
changeLog.removeAll(subChangeLog);
}
- //---------------------------------------------------< ItemStateManager >---
- /**
- * Return the root node state.
- *
- * @return the root node state.
- * @throws ItemStateException if an error occurs while retrieving the root
- * node state.
- * @see ItemStateManager#getRootState()
- */
- public NodeState getRootState() throws ItemStateException {
- if (rootNodeState == null) {
- rootNodeState = getItemStateFactory().createRootState(this);
- }
- return rootNodeState;
- }
-
- /**
- * Return an item state given its id. Please note that this implementation
- * also returns item states that are in removed state ({@link
- * Status#EXISTING_REMOVED} but not yet saved.
- *
- * @return item state.
- * @throws NoSuchItemStateException if there is no item state (not even a
- * removed item state) with the given id.
- * @see ItemStateManager#getItemState(ItemId)
- */
- public ItemState getItemState(ItemId id) throws NoSuchItemStateException, ItemStateException {
- return super.getItemState(id);
- }
-
- /**
- * Return a flag indicating whether a given item state exists.
- *
- * @return <code>true</code> if item state exists within this item state
- * manager; <code>false</code> otherwise
- * @see ItemStateManager#hasItemState(ItemId)
- */
- public boolean hasItemState(ItemId id) {
- return super.hasItemState(id);
- }
-
- /**
- * Always throws an {@link UnsupportedOperationException}. A transient item
- * state manager cannot not maintain node references.
- *
- * @param nodeState
- * @throws UnsupportedOperationException
- * @see ItemStateManager#getReferingStates(NodeState)
- */
- public Collection getReferingStates(NodeState nodeState) {
- throw new UnsupportedOperationException("getNodeReferences() not implemented");
- }
-
- /**
- * Always throws an {@link UnsupportedOperationException}. A transient item
- * state manager cannot not maintain node references.
- *
- * @param nodeState
- * @throws UnsupportedOperationException
- * @see ItemStateManager#hasReferingStates(NodeState)
- */
- public boolean hasReferingStates(NodeState nodeState) {
- throw new UnsupportedOperationException("hasNodeReferences() not implemented");
- }
-
//-----------------------------------------< ItemStateLifeCycleListener >---
/**
* Depending on status of the given state adapt change log.
@@ -243,6 +166,9 @@
* @see ItemStateLifeCycleListener#statusChanged(ItemState, int)
*/
public void statusChanged(ItemState state, int previousStatus) {
+ if (changeLog.isEmpty()) {
+ return;
+ }
switch (state.getStatus()) {
case Status.EXISTING:
case Status.EXISTING_MODIFIED:
@@ -258,8 +184,7 @@
// must not be any transient modifications for that state.
// we ignore it.
case Status.INVALIDATED:
- // only non transient states can change their status to
- // invalidated -> nothing to do here.
+ // -> nothing to do here.
break;
default:
log.error("ItemState has invalid status: " + state.getStatus());
@@ -267,7 +192,6 @@
}
//-----------------------------------------< ItemStateCreationListener >---
-
/**
* @see ItemStateCreationListener#created(ItemState)
*/
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/UpdatableItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/UpdatableItemStateManager.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/UpdatableItemStateManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/UpdatableItemStateManager.java Tue Feb 13 01:31:36 2007
@@ -21,10 +21,9 @@
import javax.jcr.RepositoryException;
/**
- * Identifies an <code>ItemStateManager</code> that allows updating
- * items.
+ * An <code>ItemStateManager</code> that deals with state modifications.
*/
-public interface UpdatableItemStateManager extends ItemStateManager {
+public interface UpdatableItemStateManager {
/**
* Executes the given operation and modifies the affected item states accordingly.
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java Tue Feb 13 01:31:36 2007
@@ -25,29 +25,35 @@
import org.apache.jackrabbit.spi.PropertyInfo;
import org.apache.jackrabbit.spi.SessionInfo;
import org.apache.jackrabbit.spi.RepositoryService;
-import org.apache.jackrabbit.spi.QPropertyDefinition;
import org.apache.jackrabbit.spi.QNodeDefinition;
-import org.apache.jackrabbit.spi.ChildInfo;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
import org.apache.jackrabbit.jcr2spi.WorkspaceManager;
import org.apache.jackrabbit.jcr2spi.nodetype.EffectiveNodeType;
-import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeConflictException;
import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeRegistry;
+import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeConflictException;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyEntry;
+import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.Path;
+import org.apache.jackrabbit.name.MalformedPathException;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
+import javax.jcr.ItemExistsException;
import javax.jcr.ItemNotFoundException;
-import javax.jcr.nodetype.ConstraintViolationException;
-import javax.jcr.nodetype.NoSuchNodeTypeException;
import java.util.HashSet;
import java.util.Set;
import java.util.Collections;
import java.util.Arrays;
import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
/**
* <code>WorkspaceItemStateFactory</code>...
*/
-public class WorkspaceItemStateFactory implements ItemStateFactory {
+public class WorkspaceItemStateFactory extends AbstractItemStateFactory implements ItemStateFactory {
private static Logger log = LoggerFactory.getLogger(WorkspaceItemStateFactory.class);
@@ -55,9 +61,8 @@
private final SessionInfo sessionInfo;
private final WorkspaceManager wspManager;
- private ItemStateCache cache;
-
- public WorkspaceItemStateFactory(RepositoryService service, SessionInfo sessionInfo, WorkspaceManager wspManager) {
+ public WorkspaceItemStateFactory(RepositoryService service, SessionInfo sessionInfo,
+ WorkspaceManager wspManager) {
this.service = service;
this.sessionInfo = sessionInfo;
this.wspManager = wspManager;
@@ -65,12 +70,13 @@
/**
* @inheritDoc
- * @see ItemStateFactory#createRootState(ItemStateManager)
+ * @see ItemStateFactory#createRootState(NodeEntry)
+ * @param entry
*/
- public NodeState createRootState(ItemStateManager ism) throws ItemStateException {
+ public NodeState createRootState(NodeEntry entry) throws ItemStateException {
try {
NodeInfo info = service.getNodeInfo(sessionInfo, service.getRootId(sessionInfo));
- return createNodeState(info, null);
+ return createNodeState(info, entry);
} catch (RepositoryException e) {
throw new ItemStateException("Internal error while building root state.");
}
@@ -81,20 +87,15 @@
* <code>RepositoryService</code>.
*
* @inheritDoc
- * @see ItemStateFactory#createNodeState(NodeId, ItemStateManager)
+ * @see ItemStateFactory#createNodeState(NodeId,NodeEntry)
*/
- public NodeState createNodeState(NodeId nodeId, ItemStateManager ism)
+ public NodeState createNodeState(NodeId nodeId, NodeEntry entry)
throws NoSuchItemStateException, ItemStateException {
try {
NodeInfo info = service.getNodeInfo(sessionInfo, nodeId);
- NodeId parentId = info.getParentId();
- if (parentId != null) {
- NodeState parent = (NodeState) ism.getItemState(parentId);
- return parent.getChildNodeEntry(nodeId).getNodeState();
- } else {
- // special case for root state
- return createNodeState(info, null);
- }
+ return createNodeState(info, entry);
+ } catch (PathNotFoundException e) {
+ throw new NoSuchItemStateException(e.getMessage(), e);
} catch (ItemNotFoundException e) {
throw new NoSuchItemStateException(e.getMessage(), e);
} catch (RepositoryException e) {
@@ -102,172 +103,276 @@
}
}
+ public NodeState createDeepNodeState(NodeId nodeId, NodeEntry anyParent) throws NoSuchItemStateException, ItemStateException {
+ try {
+ NodeInfo info = service.getNodeInfo(sessionInfo, nodeId);
+ // node for nodeId exists -> build missing entries in hierarchy
+ // Note, that the path contained in NodeId does not reveal which
+ // entries are missing -> calculate relative path.
+ Path anyParentPath = anyParent.getPath();
+ Path relPath = anyParentPath.computeRelativePath(info.getPath());
+ Path.PathElement[] missingElems = relPath.getElements();
+
+ NodeEntry entry = anyParent;
+ for (int i = 0; i < missingElems.length; i++) {
+ QName name = missingElems[i].getName();
+ int index = missingElems[i].getNormalizedIndex();
+ if (entry.hasNodeEntry(name, index)) {
+ entry = entry.getNodeEntry(name, index);
+ } else {
+ entry = entry.addNodeEntry(name, null, index);
+ }
+ }
+ if (entry == anyParent) {
+ throw new ItemStateException("Internal error while getting deep itemState");
+ }
+ return createNodeState(info, entry);
+ } catch (PathNotFoundException e) {
+ throw new NoSuchItemStateException(e.getMessage(), e);
+ } catch (ItemNotFoundException e) {
+ throw new NoSuchItemStateException(e.getMessage(), e);
+ } catch (RepositoryException e) {
+ throw new ItemStateException(e.getMessage(), e);
+ } catch (MalformedPathException e) {
+ throw new ItemStateException(e.getMessage(), e);
+ }
+ }
+
/**
- * Creates the node with information retrieved from the
+ * Creates the property with information retrieved from the
* <code>RepositoryService</code>.
*
* @inheritDoc
- * @see ItemStateFactory#createNodeState(NodeId, NodeState)
+ * @see ItemStateFactory#createPropertyState(PropertyId,PropertyEntry)
*/
- public NodeState createNodeState(NodeId nodeId, NodeState parent)
+ public PropertyState createPropertyState(PropertyId propertyId,
+ PropertyEntry entry)
throws NoSuchItemStateException, ItemStateException {
try {
- NodeInfo info = service.getNodeInfo(sessionInfo, nodeId);
- return createNodeState(info, parent);
+ PropertyInfo info = service.getPropertyInfo(sessionInfo, propertyId);
+ return createPropertyState(info, entry);
} catch (PathNotFoundException e) {
throw new NoSuchItemStateException(e.getMessage(), e);
+ } catch (ItemNotFoundException e) {
+ throw new NoSuchItemStateException(e.getMessage(), e);
} catch (RepositoryException e) {
throw new ItemStateException(e.getMessage(), e);
}
}
- /**
- * Creates the node with information retrieved from <code>info</code>.
- *
- * @param info the <code>NodeInfo</code> to use to create the
- * <code>NodeState</code>.
- * @param parent the parent <code>NodeState</code>.
- * @return the new <code>NodeState</code>.
- */
- private NodeState createNodeState(NodeInfo info, NodeState parent)
- throws NoSuchItemStateException, ItemStateException {
+ public PropertyState createDeepPropertyState(PropertyId propertyId, NodeEntry anyParent) throws NoSuchItemStateException, ItemStateException {
try {
- // retrieve definition
- QNodeDefinition definition;
- if (parent == null) {
- // special case for root state
- definition = wspManager.getNodeTypeRegistry().getRootNodeDef();
- } else {
- NodeTypeRegistry ntReg = wspManager.getNodeTypeRegistry();
- EffectiveNodeType ent = ntReg.getEffectiveNodeType(parent.getNodeTypeNames());
- definition = ent.getApplicableNodeDefinition(info.getQName(), info.getNodetype(), ntReg);
- }
-
- // build the node state
- String uniqueID = null;
- if (info.getId().getPath() == null) {
- uniqueID = info.getId().getUniqueID();
+ PropertyInfo info = service.getPropertyInfo(sessionInfo, propertyId);
+ // prop for propertyId exists -> build missing entries in hierarchy
+ // Note, that the path contained in PropertyId does not reveal which
+ // entries are missing -> calculate relative path.
+ Path anyParentPath = anyParent.getPath();
+ Path relPath = anyParentPath.computeRelativePath(info.getPath());
+ Path.PathElement[] missingElems = relPath.getElements();
+ NodeEntry entry = anyParent;
+ int i = 0;
+ // NodeEntries except for the very last 'missingElem'
+ while (i < missingElems.length - 1) {
+ QName name = missingElems[i].getName();
+ int index = missingElems[i].getNormalizedIndex();
+ if (entry.hasNodeEntry(name, index)) {
+ entry = entry.getNodeEntry(name, index);
+ } else {
+ entry = entry.addNodeEntry(name, null, index);
+ }
+ i++;
}
- NodeState state = new NodeState(info.getQName(), uniqueID, parent, info.getNodetype(),
- definition, Status.EXISTING, this, service.getIdFactory(), true);
-
- // names of child property entries
- Set propNames = new HashSet();
- for (IdIterator it = info.getPropertyIds(); it.hasNext(); ) {
- PropertyId pId = (PropertyId) it.nextId();
- propNames.add(pId.getQName());
+ // create PropertyEntry for the last element if not existing yet
+ QName propName = missingElems[i].getName();
+ PropertyEntry propEntry;
+ if (!entry.hasPropertyEntry(propName)) {
+ propEntry = entry.addPropertyEntry(propName);
+ } else {
+ propEntry = entry.getPropertyEntry(propName);
}
-
- // Build node-references object even if the state is not refereceable yet.
- PropertyId[] references = info.getReferences();
- NodeReferences nodeRefs = new NodeReferencesImpl(state, references);
-
- state.init(info.getMixins(), propNames, nodeRefs);
-
- state.addListener(cache);
- cache.created(state);
-
- return state;
- } catch (NodeTypeConflictException e) {
- String msg = "Internal error: failed to retrieve node definition.";
- log.debug(msg);
- throw new ItemStateException(msg, e);
- } catch (ConstraintViolationException e) {
- String msg = "Internal error: failed to retrieve node definition.";
- log.debug(msg);
- throw new ItemStateException(msg, e);
- } catch (NoSuchNodeTypeException e) {
- String msg = "internal error: failed to retrieve node definition.";
- log.debug(msg);
- throw new ItemStateException(msg, e);
+ return createPropertyState(info, propEntry);
+ } catch (PathNotFoundException e) {
+ throw new NoSuchItemStateException(e.getMessage(), e);
+ } catch (ItemNotFoundException e) {
+ throw new NoSuchItemStateException(e.getMessage(), e);
} catch (RepositoryException e) {
throw new ItemStateException(e.getMessage(), e);
+ } catch (MalformedPathException e) {
+ throw new ItemStateException(e.getMessage(), e);
}
}
/**
- * Creates the property with information retrieved from the
- * <code>RepositoryService</code>.
- *
* @inheritDoc
- * @see ItemStateFactory#createPropertyState(PropertyId, NodeState)
+ * @see ItemStateFactory#getChildNodeInfos(NodeId)
+ * @param nodeId
*/
- public PropertyState createPropertyState(PropertyId propertyId,
- NodeState parent)
- throws NoSuchItemStateException, ItemStateException {
+ public Iterator getChildNodeInfos(NodeId nodeId)
+ throws NoSuchItemStateException, ItemStateException {
try {
- PropertyInfo info = service.getPropertyInfo(sessionInfo, propertyId);
- return createPropertyState(info, parent);
+ return service.getChildInfos(sessionInfo, nodeId);
} catch (PathNotFoundException e) {
throw new NoSuchItemStateException(e.getMessage(), e);
+ } catch (ItemNotFoundException e) {
+ throw new NoSuchItemStateException(e.getMessage(), e);
} catch (RepositoryException e) {
throw new ItemStateException(e.getMessage(), e);
}
}
- public ChildNodeEntries getChildNodeEntries(NodeState nodeState)
- throws NoSuchItemStateException, ItemStateException {
+ /**
+ * @inheritDoc
+ * @see ItemStateFactory#getNodeReferences(NodeState)
+ * @param nodeState
+ */
+ public NodeReferences getNodeReferences(NodeState nodeState) {
+ nodeState.checkIsWorkspaceState();
+ // shortcut
+ if (nodeState.getUniqueID() == null || !nodeState.hasPropertyName(QName.JCR_UUID)) {
+ // for sure not referenceable
+ return EmptyNodeReferences.getInstance();
+ }
+
+ // nodestate has a unique ID and is potentially mix:referenceable
+ // => try to retrieve references
try {
- ChildNodeEntries entries = new ChildNodeEntries(nodeState);
- Iterator childInfos = service.getChildInfos(sessionInfo, nodeState.getNodeId());
- while (childInfos.hasNext()) {
- ChildInfo ci = (ChildInfo) childInfos.next();
- entries.add(ci.getName(), ci.getUniqueID(), ci.getIndex());
- }
- return entries;
- } catch (PathNotFoundException e) {
- throw new NoSuchItemStateException(e.getMessage(), e);
+ NodeInfo info = service.getNodeInfo(sessionInfo, nodeState.getNodeId());
+ return new NodeReferencesImpl(info.getReferences());
} catch (RepositoryException e) {
- throw new ItemStateException(e.getMessage(), e);
+ log.debug("No references for NodeState " + nodeState);
+ return EmptyNodeReferences.getInstance();
}
}
+ //------------------------------------------------------------< private >---
/**
- * Creates the property with information retrieved from <code>info</code>.
+ * Creates the node with information retrieved from <code>info</code>.
*
- * @param info the <code>PropertyInfo</code> to use to create the
- * <code>PropertyState</code>.
- * @param parent the parent <code>NodeState</code>.
- * @return the new <code>PropertyState</code>.
- * @throws ItemStateException if an error occurs while retrieving the
- * <code>PropertyState</code>.
+ * @param info the <code>NodeInfo</code> to use to create the <code>NodeState</code>.
+ * @param entry
+ * @return the new <code>NodeState</code>.
*/
- private PropertyState createPropertyState(PropertyInfo info, NodeState parent)
- throws ItemStateException {
- try {
+ private NodeState createNodeState(NodeInfo info, NodeEntry entry) {
+ // make sure the entry has the correct ItemId
+ // this make not be the case, if the hierachy has not been completely
+ // resolved yet -> if uniqueID is present, set it on this entry or on
+ // the appropriate parent entry
+ String uniqueID = info.getId().getUniqueID();
+ Path path = info.getId().getPath();
+ if (path == null) {
+ entry.setUniqueID(uniqueID);
+ } else if (uniqueID != null) {
+ // uniqueID that applies to a parent NodeEntry -> get parentEntry
+ NodeEntry parent = getAncestor(entry, path.getLength());
+ parent.setUniqueID(uniqueID);
+ }
- // retrieve property definition
- EffectiveNodeType ent = wspManager.getNodeTypeRegistry().getEffectiveNodeType(parent.getNodeTypeNames());
- QPropertyDefinition def = ent.getApplicablePropertyDefinition(info.getQName(), info.getType(), info.isMultiValued());
-
- // build the PropertyState
- PropertyState state = new PropertyState(info.getQName(), parent,
- def, Status.EXISTING, this, service.getIdFactory(), true);
- state.init(info.getType(), info.getValues());
- state.addListener(cache);
- cache.created(state);
-
- return state;
- } catch (NodeTypeConflictException e) {
- String msg = "internal error: failed to build property state.";
- log.debug(msg);
- throw new ItemStateException(msg, e);
- } catch (RepositoryException e) {
- String msg = "internal error: failed to build property state.";
- log.debug(msg);
- throw new ItemStateException(msg, e);
+ // retrieve definition
+ NodeTypeRegistry ntReg = wspManager.getNodeTypeRegistry();
+ QNodeDefinition definition = null;
+ NodeEntry parent = entry.getParent();
+ if (parent == null) {
+ // special case for root state
+ definition = wspManager.getNodeTypeRegistry().getRootNodeDef();
+ } else if (parent.isAvailable() && parent.getStatus() != Status.INVALIDATED) {
+ // try to retrieve definition if the parent is available
+ try {
+ NodeState parentState = parent.getNodeState();
+ EffectiveNodeType ent = ntReg.getEffectiveNodeType(parentState.getNodeTypeNames());
+ definition = ent.getApplicableNodeDefinition(info.getQName(), info.getNodetype(), ntReg);
+ } catch (RepositoryException e) {
+ // should not get here
+ log.warn("Internal error", e);
+ } catch (ItemStateException e) {
+ // should not get here
+ log.warn("Internal error", e);
+ } catch (NodeTypeConflictException e) {
+ // should not get here
+ log.warn("Internal error", e);
+ }
+ }
+
+ // now build the nodestate itself
+ NodeState state = new NodeState(entry, info.getNodetype(), info.getMixins(), definition, Status.EXISTING, true, this, ntReg);
+
+ // update NodeEntry from the information present in the NodeInfo (prop entries)
+ List propNames = new ArrayList();
+ for (IdIterator it = info.getPropertyIds(); it.hasNext(); ) {
+ PropertyId pId = (PropertyId) it.nextId();
+ QName propertyName = pId.getQName();
+ propNames.add(propertyName);
}
+ try {
+ entry.addPropertyEntries(propNames);
+ } catch (ItemExistsException e) {
+ // should not get here
+ log.warn("Internal error", e);
+ }
+
+ notifyCreated(state);
+ return state;
}
/**
+ * Creates the property with information retrieved from <code>info</code>.
*
- * @param cache
- * @see ItemStateFactory#setCache(ItemStateCache)
+ * @param info the <code>PropertyInfo</code> to use to create the
+ * <code>PropertyState</code>.
+ * @param entry
+ * @return the new <code>PropertyState</code>.
*/
- public void setCache(ItemStateCache cache) {
- this.cache = cache;
+ private PropertyState createPropertyState(PropertyInfo info, PropertyEntry entry) {
+ // make sure uuid part of id is correct
+ String uniqueID = info.getId().getUniqueID();
+ if (uniqueID != null) {
+ // uniqueID always applies to a parent NodeEntry -> get parentEntry
+ NodeEntry parent = getAncestor(entry, info.getId().getPath().getLength());
+ parent.setUniqueID(uniqueID);
+ }
+
+ QPropertyDefinition definition = null;
+ // try to retrieve property definition
+ if (entry.getParent().isAvailable() && entry.getStatus() != Status.INVALIDATED) {
+ NodeState parentState = null;
+ try {
+ parentState = entry.getParent().getNodeState();
+ EffectiveNodeType ent = wspManager.getNodeTypeRegistry().getEffectiveNodeType(parentState.getNodeTypeNames());
+ definition = ent.getApplicablePropertyDefinition(info.getQName(), info.getType(), info.isMultiValued());
+ } catch (ItemStateException e) {
+ // should not get here
+ log.warn("Internal error", e);
+ } catch (RepositoryException e) {
+ // should not get here
+ log.warn("Internal error", e);
+ } catch (NodeTypeConflictException e) {
+ // should not get here
+ log.warn("Internal error", e);
+ }
+ }
+
+ // build the PropertyState
+ PropertyState state = new PropertyState(entry, info.isMultiValued(), definition, Status.EXISTING, true, this, wspManager.getNodeTypeRegistry());
+ state.init(info.getType(), info.getValues());
+
+ //state.addListener(cache);
+ //cache.created(state);
+ notifyCreated(state);
+
+ return state;
}
+ private static NodeEntry getAncestor(HierarchyEntry entry, int degree) {
+ NodeEntry parent = entry.getParent();
+ degree--;
+ while (parent != null && degree > 0) {
+ parent = parent.getParent();
+ degree--;
+ }
+ if (degree != 0) {
+ throw new IllegalArgumentException();
+ }
+ return parent;
+ }
//-----------------------------------------------------< NodeReferences >---
/**
* <code>NodeReferences</code> represents the references (i.e. properties of
@@ -275,21 +380,15 @@
*/
private class NodeReferencesImpl implements NodeReferences {
- private NodeState nodeState;
+ private PropertyId[] references;
/**
* Private constructor
*
- * @param nodeState
- * @param referenceIds
+ * @param references
*/
- private NodeReferencesImpl(NodeState nodeState, PropertyId[] referenceIds) {
- this.nodeState = nodeState;
-
- // TODO: improve. make usage of the references returned
- // with NodeInfo that was just retrieved and implement a notification
- // mechanism that updates this NodeReference object if references
- // are modified.
+ private NodeReferencesImpl(PropertyId[] references) {
+ this.references = references;
}
//-------------------------------------------------< NodeReferences >---
@@ -297,42 +396,18 @@
* @see NodeReferences#isEmpty()
*/
public boolean isEmpty() {
- // shortcut
- if (nodeState.getUniqueID() == null) {
- return true;
- }
- // nodestate has a unique ID and is potentially mix:referenceable
- // => try to retrieve references
- try {
- NodeInfo info = service.getNodeInfo(sessionInfo, nodeState.getNodeId());
- return info.getReferences().length > 0;
- } catch (RepositoryException e) {
- log.error("Internal error.",e);
- return false;
- }
+ return references.length <= 0;
}
/**
* @see NodeReferences#iterator()
*/
public Iterator iterator() {
- // shortcut
- if (nodeState.getUniqueID() == null) {
- return Collections.EMPTY_SET.iterator();
- }
- // nodestate has a uniqueID and is potentially mix:referenceable
- // => try to retrieve references
- try {
- NodeInfo info = service.getNodeInfo(sessionInfo, nodeState.getNodeId());
- if (info.getReferences().length > 0) {
- Set referenceIds = new HashSet();
- referenceIds.addAll(Arrays.asList(info.getReferences()));
- return Collections.unmodifiableSet(referenceIds).iterator();
- } else {
- return Collections.EMPTY_SET.iterator();
- }
- } catch (RepositoryException e) {
- log.error("Internal error.", e);
+ if (references.length > 0) {
+ Set referenceIds = new HashSet();
+ referenceIds.addAll(Arrays.asList(references));
+ return Collections.unmodifiableSet(referenceIds).iterator();
+ } else {
return Collections.EMPTY_SET.iterator();
}
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/util/LogUtil.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/util/LogUtil.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/util/LogUtil.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/util/LogUtil.java Tue Feb 13 01:31:36 2007
@@ -62,10 +62,9 @@
* @param nsResolver
* @return JCR path
*/
- public static String safeGetJCRPath(ItemState itemState, NamespaceResolver nsResolver
- ) {
+ public static String safeGetJCRPath(ItemState itemState, NamespaceResolver nsResolver) {
try {
- return safeGetJCRPath(itemState.getQPath(), nsResolver);
+ return safeGetJCRPath(itemState.getHierarchyEntry().getPath(), nsResolver);
} catch (RepositoryException e) {
ItemId id = itemState.getId();
log.error("failed to convert " + id + " to JCR path.");
Added: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/util/StateUtility.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/util/StateUtility.java?view=auto&rev=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/util/StateUtility.java (added)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/util/StateUtility.java Tue Feb 13 01:31:36 2007
@@ -0,0 +1,87 @@
+/*
+ * 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.jcr2spi.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.jcr2spi.state.PropertyState;
+import org.apache.jackrabbit.jcr2spi.state.Status;
+import org.apache.jackrabbit.jcr2spi.state.ItemState;
+import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.spi.QValue;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * <code>StateUtility</code>...
+ */
+public class StateUtility {
+
+ private static Logger log = LoggerFactory.getLogger(StateUtility.class);
+
+ /**
+ *
+ * @param ps
+ * @return
+ * @throws IllegalArgumentException if the name of the PropertyState is NOT
+ * {@link QName#JCR_MIXINTYPES}
+ */
+ public static QName[] getMixinNames(PropertyState ps) {
+ if (!QName.JCR_MIXINTYPES.equals(ps.getQName())) {
+ throw new IllegalArgumentException();
+ }
+ if (ps.getStatus() == Status.REMOVED) {
+ return QName.EMPTY_ARRAY;
+ } else {
+ QValue[] values = ps.getValues();
+ QName[] newMixins = new QName[values.length];
+ for (int i = 0; i < values.length; i++) {
+ try {
+ newMixins[i] = QName.valueOf(values[i].getString());
+ } catch (RepositoryException e) {
+ // ignore: should never occur.
+ }
+ }
+ return newMixins;
+ }
+ }
+
+
+ public static boolean isUuidOrMixin(QName propName) {
+ return QName.JCR_UUID.equals(propName) || QName.JCR_MIXINTYPES.equals(propName);
+ }
+
+ public static boolean isMovedState(NodeState state) {
+ state.checkIsSessionState();
+ if (state.isRoot()) {
+ // the root state cannot be moved
+ return false;
+ } else {
+ // a session-state is moved, if its NodeEntry is not the same as
+ // the NodeEntry of its overlayed state. If no overlayedState
+ // exists the state not moved anyway.
+ ItemState overlayed = state.getWorkspaceState();
+ if (overlayed == null) {
+ return false;
+ } else {
+ return state.getHierarchyEntry() != overlayed.getHierarchyEntry();
+ //return modState.overlayedState.getParent() != modState.getParent().overlayedState;
+ }
+ }
+ }
+}
\ No newline at end of file
Propchange: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/util/StateUtility.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/util/StateUtility.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/DefaultVersionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/DefaultVersionManager.java?view=diff&rev=506927&r1=506926&r2=506927
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/DefaultVersionManager.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/DefaultVersionManager.java Tue Feb 13 01:31:36 2007
@@ -26,6 +26,7 @@
import org.apache.jackrabbit.name.QName;
import org.apache.jackrabbit.name.Path;
import org.apache.jackrabbit.jcr2spi.state.NodeState;
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
import org.apache.jackrabbit.spi.IdIterator;
/**
@@ -78,5 +79,13 @@
public void resolveMergeConflict(NodeState nodeState, NodeState versionState, boolean done) throws RepositoryException {
throw new UnsupportedRepositoryOperationException("Versioning ist not supported by this repository.");
+ }
+
+ public NodeEntry getVersionableNodeState(NodeState versionState) {
+ throw new UnsupportedOperationException();
+ }
+
+ public NodeEntry getVersionHistoryNodeState(NodeState versionableState) {
+ throw new UnsupportedOperationException();
}
}