You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by dp...@apache.org on 2008/04/14 14:35:36 UTC
svn commit: r647767 [1/2] - in
/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core:
./ version/
Author: dpfister
Date: Mon Apr 14 05:35:33 2008
New Revision: 647767
URL: http://svn.apache.org/viewvc?rev=647767&view=rev
Log:
JCR-1104 - JSR 283 support
- shareble nodes (work in progress)
- prepare for returning stable paths on shareable nodes or their descendants
Added:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/AbstractNodeData.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemData.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeData.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeDataRef.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyData.java
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionHistoryImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionImpl.java
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/AbstractNodeData.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/AbstractNodeData.java?rev=647767&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/AbstractNodeData.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/AbstractNodeData.java Mon Apr 14 05:35:33 2008
@@ -0,0 +1,107 @@
+/*
+ * 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;
+
+import javax.jcr.nodetype.NodeDefinition;
+import org.apache.jackrabbit.core.state.NodeState;
+
+/**
+ * Data object representing a node.
+ */
+public abstract class AbstractNodeData extends ItemData {
+
+ /** Primary parent id of a shareable node. */
+ private NodeId primaryParentId;
+
+ /**
+ * Create a new instance of this class.
+ *
+ * @param state node state
+ * @param definition node definition
+ */
+ protected AbstractNodeData(NodeState state, NodeDefinition definition) {
+ super(state, definition);
+
+ if (state.isShareable()) {
+ this.primaryParentId = state.getParentId();
+ }
+ }
+
+ /**
+ * Create a new instance of this class.
+ */
+ protected AbstractNodeData() {
+ }
+
+ /**
+ * Return the associated node state.
+ *
+ * @return node state
+ */
+ public NodeState getNodeState() {
+ return (NodeState) getState();
+ }
+
+ /**
+ * Return the associated node defintion.
+ *
+ * @return node defintion
+ */
+ public NodeDefinition getNodeDefinition() {
+ return (NodeDefinition) getDefinition();
+ }
+
+ /**
+ * Return the parent id of this node. Every shareable node in a shared set
+ * has a different parent.
+ *
+ * @return parent id
+ */
+ public NodeId getParentId() {
+ if (primaryParentId != null) {
+ return primaryParentId;
+ }
+ return getState().getParentId();
+ }
+
+ /**
+ * Return the primary parent id of this node. Every shareable node in a
+ * shared set has a different primary parent. Returns <code>null</code>
+ * for nodes that are not shareable.
+ *
+ * @return primary parent id or <code>null</code>
+ */
+ public NodeId getPrimaryParentId() {
+ return primaryParentId;
+ }
+
+ /**
+ * Set the primary parent id of this node.
+ *
+ * @param primaryParentId primary parent id
+ */
+ protected void setPrimaryParentId(NodeId primaryParentId) {
+ this.primaryParentId = primaryParentId;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isNode() {
+ return true;
+ }
+}
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemData.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemData.java?rev=647767&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemData.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemData.java Mon Apr 14 05:35:33 2008
@@ -0,0 +1,133 @@
+/*
+ * 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;
+
+import javax.jcr.nodetype.ItemDefinition;
+import org.apache.jackrabbit.core.state.ItemState;
+
+/**
+ * Data object referenced by different <code>ItemImpl</code> instances that
+ * all represent the same item, i.e. items having the same <code>ItemId</code>.
+ */
+public abstract class ItemData {
+
+ /** Associated item state */
+ protected ItemState state;
+
+ /** Associated item definition */
+ protected ItemDefinition definition;
+
+ /** Status */
+ protected int status;
+
+ /**
+ * Create a new instance of this class.
+ *
+ * @param state item state
+ * @param definition item definition
+ */
+ protected ItemData(ItemState state, ItemDefinition definition) {
+ this.state = state;
+ this.definition = definition;
+ }
+
+ /**
+ * Create a new instance of this class.
+ */
+ protected ItemData() {
+ }
+
+ /**
+ * Return the associated item state.
+ *
+ * @return item state
+ */
+ public ItemState getState() {
+ return state;
+ }
+
+ /**
+ * Set the associated item state.
+ *
+ * @param state item state
+ */
+ protected void setState(ItemState state) {
+ this.state = state;
+ }
+
+ /**
+ * Return the associated item definition.
+ *
+ * @return item definition
+ */
+ public ItemDefinition getDefinition() {
+ return definition;
+ }
+
+ /**
+ * Set the associated item definition.
+ *
+ * @param definition item definition
+ */
+ protected void setDefinition(ItemDefinition definition) {
+ this.definition = definition;
+ }
+
+ /**
+ * Return the status.
+ *
+ * @return status
+ */
+ public int getStatus() {
+ return status;
+ }
+
+ /**
+ * Set the status.
+ *
+ * @param status
+ */
+ protected void setStatus(int status) {
+ this.status = status;
+ }
+
+ /**
+ * Return a flag indicating whether item is a node.
+ *
+ * @return <code>true</code> if this item is a node;
+ * <code>false</code> otherwise.
+ */
+ public boolean isNode() {
+ return false;
+ }
+
+ /**
+ * Return the id associated with this item.
+ *
+ * @return item id
+ */
+ public ItemId getId() {
+ return getState().getId();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return getId().toString();
+ }
+}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java?rev=647767&r1=647766&r2=647767&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java Mon Apr 14 05:35:33 2008
@@ -17,7 +17,6 @@
package org.apache.jackrabbit.core;
import org.apache.commons.collections.iterators.IteratorChain;
-import org.apache.commons.collections.map.ReferenceMap;
import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
import org.apache.jackrabbit.core.nodetype.NodeDef;
import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
@@ -65,10 +64,8 @@
import javax.jcr.version.VersionHistory;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.Map;
import java.util.Set;
/**
@@ -83,7 +80,7 @@
protected static final int STATUS_DESTROYED = 2;
protected static final int STATUS_INVALIDATED = 3;
- protected int status;
+ //protected int status;
protected final ItemId id;
@@ -98,9 +95,9 @@
protected final RepositoryImpl rep;
/**
- * <code>ItemState</code> associated with this <code>Item</code>
+ * Item data associated with this item.
*/
- protected ItemState state;
+ protected final ItemData data;
/**
* <code>ItemManager</code> that created this <code>Item</code>
@@ -113,12 +110,6 @@
protected final SessionItemStateManager stateMgr;
/**
- * Listeners (weak references)
- */
- protected final Map listeners =
- Collections.synchronizedMap(new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.WEAK));
-
- /**
* Package private constructor.
*
* @param itemMgr the <code>ItemManager</code> that created this <code>Item</code>
@@ -127,21 +118,14 @@
* @param state state associated with this <code>Item</code>
* @param listeners listeners on life cycle changes of this <code>ItemImpl</code>
*/
- ItemImpl(ItemManager itemMgr, SessionImpl session, ItemId id, ItemState state,
- ItemLifeCycleListener[] listeners) {
+ ItemImpl(ItemManager itemMgr, SessionImpl session, ItemData data) {
this.session = session;
rep = (RepositoryImpl) session.getRepository();
stateMgr = session.getItemStateManager();
- this.id = id;
+ this.id = data.getId();
this.itemMgr = itemMgr;
- this.state = state;
- status = STATUS_NORMAL;
-
- if (listeners != null) {
- for (int i = 0; i < listeners.length; i++) {
- addLifeCycleListener(listeners[i]);
- }
- }
+ this.data = data;
+ data.setStatus(STATUS_NORMAL);
}
/**
@@ -154,13 +138,14 @@
session.sanityCheck();
// check status of this item for read operation
+ final int status = data.getStatus();
if (status == STATUS_DESTROYED || status == STATUS_INVALIDATED) {
throw new InvalidItemStateException(id + ": the item does not exist anymore");
}
}
protected boolean isTransient() {
- return state.isTransient();
+ return getItemState().isTransient();
}
protected abstract ItemState getOrCreateTransientItemState() throws RepositoryException;
@@ -175,6 +160,7 @@
* @throws RepositoryException if an error occurs
*/
protected void setRemoved() throws RepositoryException {
+ final int status = data.getStatus();
if (status == STATUS_INVALIDATED || status == STATUS_DESTROYED) {
// this instance is already 'invalid', get outta here
return;
@@ -194,10 +180,10 @@
stateMgr.moveTransientItemStateToAttic(transientState);
// set state of this instance to 'invalid'
- status = STATUS_INVALIDATED;
- // notify the listeners that this instance has been
+ data.setStatus(STATUS_INVALIDATED);
+ // notify the manager that this instance has been
// temporarily invalidated
- notifyInvalidated();
+ itemMgr.itemInvalidated(id, data);
}
}
@@ -207,74 +193,7 @@
* @return state associated with this <code>Item</code>
*/
ItemState getItemState() {
- return state;
- }
-
- /**
- * Notify the listeners that this instance has been created.
- */
- protected void notifyCreated() {
- // copy listeners to array to avoid ConcurrentModificationException
- ItemLifeCycleListener[] la =
- (ItemLifeCycleListener[]) listeners.values().toArray(
- new ItemLifeCycleListener[listeners.size()]);
- for (int i = 0; i < la.length; i++) {
- if (la[i] != null) {
- la[i].itemCreated(this);
- }
- }
- }
-
- /**
- * Notify the listeners that this instance has been invalidated
- * (i.e. it has been temporarily rendered 'invalid').
- */
- protected void notifyInvalidated() {
- // copy listeners to array to avoid ConcurrentModificationException
- ItemLifeCycleListener[] la =
- (ItemLifeCycleListener[]) listeners.values().toArray(
- new ItemLifeCycleListener[listeners.size()]);
- for (int i = 0; i < la.length; i++) {
- if (la[i] != null) {
- la[i].itemInvalidated(id, this);
- }
- }
- }
-
- /**
- * Notify the listeners that this instance has been destroyed
- * (i.e. it has been permanently rendered 'invalid').
- */
- protected void notifyDestroyed() {
- // copy listeners to array to avoid ConcurrentModificationException
- ItemLifeCycleListener[] la =
- (ItemLifeCycleListener[]) listeners.values().toArray(
- new ItemLifeCycleListener[listeners.size()]);
- for (int i = 0; i < la.length; i++) {
- if (la[i] != null) {
- la[i].itemDestroyed(id, this);
- }
- }
- }
-
- /**
- * Add an <code>ItemLifeCycleListener</code>
- *
- * @param listener the new listener to be informed on life cycle changes
- */
- void addLifeCycleListener(ItemLifeCycleListener listener) {
- if (!listeners.containsKey(listener)) {
- listeners.put(listener, listener);
- }
- }
-
- /**
- * Remove an <code>ItemLifeCycleListener</code>
- *
- * @param listener an existing listener
- */
- void removeLifeCycleListener(ItemLifeCycleListener listener) {
- listeners.remove(listener);
+ return data.getState();
}
/**
@@ -353,6 +272,7 @@
// fail-fast test: check status of this item's state
if (isTransient()) {
String msg;
+ final ItemState state = getItemState();
switch (state.getStatus()) {
case ItemState.STATUS_EXISTING_MODIFIED:
// add this item's state to the list
@@ -695,15 +615,15 @@
// walk through list of transient items and persist each one
while (iter.hasNext()) {
- ItemState itemState = (ItemState) iter.next();
- ItemImpl item = itemMgr.getItem(itemState);
+ ItemState state = (ItemState) iter.next();
+ ItemImpl item = itemMgr.getItem(state.getId(),
+ state.getStatus() == ItemState.STATUS_NEW);
// persist state of transient item
item.makePersistent();
}
}
private void restoreTransientItems(Iterator iter) {
-
// walk through list of transient states and re-apply transient changes
while (iter.hasNext()) {
ItemState itemState = (ItemState) iter.next();
@@ -717,11 +637,7 @@
// TransientItemStateManager will bark because of a deleted
// state in its attic. We therefore have to forge a new item
// instance ourself.
- if (itemState.isNode()) {
- item = itemMgr.createNodeInstance((NodeState) itemState);
- } else {
- item = itemMgr.createPropertyInstance((PropertyState) itemState);
- }
+ item = itemMgr.createItemInstance(itemState);
itemState.setStatus(ItemState.STATUS_NEW);
} else {
try {
@@ -730,11 +646,7 @@
// itemState probably represents a 'new' item and the
// ItemImpl instance wrapping it has already been gc'ed;
// we have to re-create the ItemImpl instance
- if (itemState.isNode()) {
- item = itemMgr.createNodeInstance((NodeState) itemState);
- } else {
- item = itemMgr.createPropertyInstance((PropertyState) itemState);
- }
+ item = itemMgr.createItemInstance(itemState);
itemState.setStatus(ItemState.STATUS_NEW);
}
}
@@ -943,123 +855,8 @@
*/
public abstract Name getQName() throws RepositoryException;
- //----------------------------------------------------< ItemStateListener >
- /**
- * {@inheritDoc}
- */
- public void stateCreated(ItemState created) {
- status = STATUS_NORMAL;
- }
-
- /**
- * {@inheritDoc}
- */
- public void stateDestroyed(ItemState destroyed) {
- if (state == destroyed) {
- // set state of this instance to 'destroyed'
- status = STATUS_DESTROYED;
- // dispose state
- if (state == destroyed) {
- state = null;
- }
- /**
- * notify the listeners that this instance has been
- * permanently invalidated
- */
- notifyDestroyed();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void stateModified(ItemState modified) {
- if (state == modified) {
- status = STATUS_MODIFIED;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void stateDiscarded(ItemState discarded) {
- if (state == discarded) {
- /**
- * the state of this item has been discarded, probably as a result
- * of calling Item.refresh(false) or ItemImpl.setRemoved()
- */
- if (isTransient()) {
- switch (state.getStatus()) {
- /**
- * persistent item that has been transiently removed
- */
- case ItemState.STATUS_EXISTING_REMOVED:
- /**
- * persistent item that has been transiently modified
- */
- case ItemState.STATUS_EXISTING_MODIFIED:
- /**
- * persistent item that has been transiently modified or removed
- * and the underlying persistent state has been externally
- * modified since the transient modification/removal.
- */
- case ItemState.STATUS_STALE_MODIFIED:
- ItemState persistentState = state.getOverlayedState();
- /**
- * the state is a transient wrapper for the underlying
- * persistent state, therefore restore the
- * persistent state and resurrect this item instance
- * if necessary
- */
- stateMgr.disconnectTransientItemState(state);
- state = persistentState;
-
- return;
-
- /**
- * persistent item that has been transiently modified or removed
- * and the underlying persistent state has been externally
- * destroyed since the transient modification/removal.
- */
- case ItemState.STATUS_STALE_DESTROYED:
- /**
- * first notify the listeners that this instance has been
- * permanently invalidated
- */
- notifyDestroyed();
- // now set state of this instance to 'destroyed'
- status = STATUS_DESTROYED;
- state = null;
- return;
-
- /**
- * new item that has been transiently added
- */
- case ItemState.STATUS_NEW:
- /**
- * first notify the listeners that this instance has been
- * permanently invalidated
- */
- notifyDestroyed();
- // now set state of this instance to 'destroyed'
- status = STATUS_DESTROYED;
- // finally dispose state
- state = null;
- return;
- }
- }
-
- /**
- * first notify the listeners that this instance has been
- * invalidated
- */
- notifyInvalidated();
- // now render this instance 'invalid'
- status = STATUS_INVALIDATED;
- }
- }
-
//-----------------------------------------------------------------< Item >
+
/**
* {@inheritDoc}
*/
@@ -1086,6 +883,7 @@
* {@inheritDoc}
*/
public boolean isNew() {
+ final ItemState state = getItemState();
return state.isTransient() && state.getOverlayedState() == null;
}
@@ -1095,6 +893,7 @@
* be saved but not yet persisted.
*/
protected boolean isTransactionalNew() {
+ final ItemState state = getItemState();
return state.getStatus() == ItemState.STATUS_NEW;
}
@@ -1102,6 +901,7 @@
* {@inheritDoc}
*/
public boolean isModified() {
+ final ItemState state = getItemState();
return state.isTransient() && state.getOverlayedState() != null;
}
@@ -1371,7 +1171,7 @@
// check status of this item's state
if (isTransient()) {
- transientState = state;
+ transientState = getItemState();
switch (transientState.getStatus()) {
case ItemState.STATUS_STALE_MODIFIED:
case ItemState.STATUS_STALE_DESTROYED:
@@ -1484,6 +1284,7 @@
// check state of this instance
sanityCheck();
+ final ItemState state = getItemState();
if (state.getParentId() == null) {
// shortcut
return 0;
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java?rev=647767&r1=647766&r2=647767&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java Mon Apr 14 05:35:33 2008
@@ -76,7 +76,7 @@
* If the parent <code>Session</code> is an <code>XASession</code>, there is
* one <code>ItemManager</code> instance per started global transaction.
*/
-public class ItemManager implements ItemLifeCycleListener, Dumpable, ItemStateListener {
+public class ItemManager implements Dumpable, ItemStateListener {
private static Logger log = LoggerFactory.getLogger(ItemManager.class);
@@ -197,10 +197,7 @@
// check privileges
if (!canRead(id)) {
// clear cache
- ItemImpl item = retrieveItem(id);
- if (item != null) {
- evictItem(id);
- }
+ evictItems(id);
throw new AccessDeniedException("cannot read item " + id);
}
@@ -299,7 +296,7 @@
// check privileges
if (!canRead(id)) {
// clear cache
- evictItem(id);
+ evictItems(id);
// item exists but the session has not been granted read access
return false;
}
@@ -396,24 +393,24 @@
// check sanity of session
session.sanityCheck();
- // check cache
- ItemImpl item = retrieveItem(id);
- if (item == null) {
+ ItemData data = retrieveItem(id);
+ if (data == null) {
// not yet in cache, need to create instance:
// check privileges
if (!canRead(id)) {
throw new AccessDeniedException("cannot read item " + id);
}
- // create instance of item
- item = createItemInstance(id);
+ // create instance of item data
+ data = createItemData(id);
+ cacheItem(data);
}
- return item;
+ return createItemInstance(data);
}
/**
* Returns a node with a given id and parent id. If the indicated node is
* shareable, there might be multiple nodes associated with the same id,
- * but only one node with the given parent id.
+ * but there'is only one node with the given parent id.
*
* @param id node id
* @param parentId parent node id
@@ -422,54 +419,71 @@
*/
public synchronized NodeImpl getNode(NodeId id, NodeId parentId)
throws ItemNotFoundException, AccessDeniedException, RepositoryException {
- // check sanity of session
- session.sanityCheck();
- // check shareable nodes
- NodeImpl node = shareableNodesCache.retrieve(id, parentId);
- if (node != null) {
- return node;
+ if (parentId == null) {
+ return (NodeImpl) getItem(id);
}
-
- node = (NodeImpl) getItem(id);
- if (!node.getParentId().equals(parentId)) {
+ AbstractNodeData data = (AbstractNodeData) retrieveItem(id, parentId);
+ if (data == null) {
+ data = (AbstractNodeData) createItemData(id);
+ cacheItem(data);
+ }
+ if (!data.getParentId().equals(parentId)) {
// verify that parent actually appears in the shared set
- if (!node.hasShareParent(parentId)) {
+ if (!data.getNodeState().containsShare(parentId)) {
String msg = "Node with id '" + id
+ "' does not have shared parent with id: " + parentId;
throw new ItemNotFoundException(msg);
}
-
- node = new NodeImpl(node, parentId, new ItemLifeCycleListener[] { this });
- node.notifyCreated();
+ data = new NodeDataRef(data, parentId);
+ cacheItem(data);
}
- return node;
+ return createNodeInstance(data);
}
/**
- * Returns the item instance for the given item state.
+ * Returns the item instance for the given item id.
+ *
* @param state the item state
+ * @param checkAccess whether to check access
* @return the item instance for the given item <code>state</code>.
* @throws RepositoryException
*/
- public synchronized ItemImpl getItem(ItemState state)
+ synchronized ItemImpl getItem(ItemId id, boolean isNew)
throws ItemNotFoundException, AccessDeniedException, RepositoryException {
// check sanity of session
session.sanityCheck();
- ItemId id = state.getId();
// check cache
- ItemImpl item = retrieveItem(id);
- if (item == null) {
+ ItemData data = retrieveItem(id);
+ if (data == null) {
// not yet in cache, need to create instance:
// only check privileges if state is not new
- if (state.getStatus() != ItemState.STATUS_NEW && !canRead(id)) {
+ if (!isNew && !canRead(id)) {
throw new AccessDeniedException("cannot read item " + id);
}
// create instance of item
- item = createItemInstance(id);
+ data = createItemData(id);
+ cacheItem(data);
}
- return item;
+ return createItemInstance(data);
+ }
+
+ /**
+ * Create an item instance from an item state. This method creates a
+ * new <code>ItemData</code> instance without looking at the cache and
+ * returns a new item instance.
+ *
+ * @param state item state
+ * @return item instance
+ * @throws RepositoryException if an error occurs
+ */
+ synchronized ItemImpl createItemInstance(ItemState state)
+ throws RepositoryException {
+
+ ItemData data = createItemData(state);
+ cacheItem(data);
+ return createItemInstance(data);
}
/**
@@ -603,10 +617,10 @@
}
//-------------------------------------------------< item factory methods >
- private ItemImpl createItemInstance(ItemId id)
+
+ private ItemData createItemData(ItemId id)
throws ItemNotFoundException, RepositoryException {
- // create instance of item using its state object
- ItemImpl item;
+
ItemState state;
try {
state = itemStateProvider.getItemState(id);
@@ -617,98 +631,47 @@
log.error(msg, ise);
throw new RepositoryException(msg, ise);
}
+ return createItemData(state);
+ }
+ private ItemData createItemData(ItemState state) throws RepositoryException {
+ ItemId id = state.getId();
if (id.equals(rootNodeId)) {
// special handling required for root node
- item = createNodeInstance((NodeState) state, rootNodeDef);
+ return new NodeData((NodeState) state, rootNodeDef);
} else if (state.isNode()) {
- item = createNodeInstance((NodeState) state);
+ NodeState nodeState = (NodeState) state;
+ return new NodeData(nodeState, getDefinition(nodeState));
} else {
- item = createPropertyInstance((PropertyState) state);
+ PropertyState propertyState = (PropertyState) state;
+ return new PropertyData(propertyState, getDefinition(propertyState));
}
- return item;
}
- NodeImpl createNodeInstance(NodeState state, NodeDefinition def)
- throws RepositoryException {
- NodeId id = state.getNodeId();
- // we want to be informed on life cycle changes of the new node object
- // in order to maintain item cache consistency
- ItemLifeCycleListener[] listeners = new ItemLifeCycleListener[]{this};
- NodeImpl node = null;
+ private ItemImpl createItemInstance(ItemData data) {
+ if (data.isNode()) {
+ return createNodeInstance((AbstractNodeData) data);
+ } else {
+ return createPropertyInstance((PropertyData) data);
+ }
+ }
+ private NodeImpl createNodeInstance(AbstractNodeData data) {
// check special nodes
+ final NodeState state = data.getNodeState();
if (state.getNodeTypeName().equals(NameConstants.NT_VERSION)) {
- node = createVersionInstance(id, state, def, listeners);
-
+ return new VersionImpl(this, session, data);
} else if (state.getNodeTypeName().equals(NameConstants.NT_VERSIONHISTORY)) {
- node = createVersionHistoryInstance(id, state, def, listeners);
-
+ return new VersionHistoryImpl(this, session, data);
} else {
// create node object
- node = new NodeImpl(this, session, id, state, def, listeners);
+ return new NodeImpl(this, session, data);
}
- node.notifyCreated();
- return node;
- }
-
- NodeImpl createNodeInstance(NodeState state) throws RepositoryException {
- // 1. get definition of the specified node
- NodeDefinition def = getDefinition(state);
- // 2. create instance
- return createNodeInstance(state, def);
}
- PropertyImpl createPropertyInstance(PropertyState state,
- PropertyDefinition def) {
- // we want to be informed on life cycle changes of the new property object
- // in order to maintain item cache consistency
- ItemLifeCycleListener[] listeners = new ItemLifeCycleListener[]{this};
- // create property object
- PropertyImpl property = new PropertyImpl(
- this, session, state.getPropertyId(), state, def, listeners);
- property.notifyCreated();
- return property;
- }
-
- PropertyImpl createPropertyInstance(PropertyState state)
- throws RepositoryException {
- // 1. get definition for the specified property
- PropertyDefinition def = getDefinition(state);
- // 2. create instance
- return createPropertyInstance(state, def);
- }
-
- /**
- * Create a version instance.
- * @param id node id
- * @param state node state
- * @param def node definition
- * @param listeners listeners
- * @return version instance
- * @throws RepositoryException if an error occurs
- */
- protected VersionImpl createVersionInstance(
- NodeId id, NodeState state, NodeDefinition def,
- ItemLifeCycleListener[] listeners) throws RepositoryException {
-
- return new VersionImpl(this, session, id, state, def, listeners);
- }
-
- /**
- * Create a version history instance.
- * @param id node id
- * @param state node state
- * @param def node definition
- * @param listeners listeners
- * @return version instance
- * @throws RepositoryException if an error occurs
- */
- protected VersionHistoryImpl createVersionHistoryInstance(
- NodeId id, NodeState state, NodeDefinition def,
- ItemLifeCycleListener[] listeners) throws RepositoryException {
-
- return new VersionHistoryImpl(this, session, id, state, def, listeners);
+ private PropertyImpl createPropertyInstance(PropertyData data) {
+ // check special nodes
+ return new PropertyImpl(this, session, data);
}
//---------------------------------------------------< item cache methods >
@@ -720,13 +683,31 @@
* @return the item reference stored in the corresponding cache entry
* or <code>null</code> if there's no corresponding cache entry.
*/
- private ItemImpl retrieveItem(ItemId id) {
+ private ItemData retrieveItem(ItemId id) {
synchronized (itemCache) {
- ItemImpl item = (ItemImpl) itemCache.get(id);
- if (item == null && id.denotesNode()) {
- item = shareableNodesCache.retrieve((NodeId) id);
+ ItemData data = (ItemData) itemCache.get(id);
+ if (data == null && id.denotesNode()) {
+ data = shareableNodesCache.retrieveFirst((NodeId) id);
}
- return item;
+ return data;
+ }
+ }
+
+ /**
+ * Return a node from the cache.
+ *
+ * @param id id of the node that should be retrieved.
+ * @param parentId parent id of the node that should be retrieved
+ * @return reference stored in the corresponding cache entry
+ * or <code>null</code> if there's no corresponding cache entry.
+ */
+ private AbstractNodeData retrieveItem(NodeId id, NodeId parentId) {
+ synchronized (itemCache) {
+ AbstractNodeData data = shareableNodesCache.retrieve(id, parentId);
+ if (data == null) {
+ data = (AbstractNodeData) itemCache.get(id);
+ }
+ return data;
}
}
@@ -736,35 +717,67 @@
*
* @param item the item to cache
*/
- private void cacheItem(ItemImpl item) {
+ private void cacheItem(ItemData data) {
synchronized (itemCache) {
- ItemId id = item.getId();
+ if (data.isNode()) {
+ AbstractNodeData nd = (AbstractNodeData) data;
+ if (nd.getPrimaryParentId() != null) {
+ shareableNodesCache.cache(nd);
+ return;
+ }
+ }
+ ItemId id = data.getId();
if (itemCache.containsKey(id)) {
log.warn("overwriting cached item " + id);
}
if (log.isDebugEnabled()) {
log.debug("caching item " + id);
}
- itemCache.put(id, item);
+ itemCache.put(id, data);
}
}
/**
- * Removes a cache entry for a specific item.
+ * Removes all cache entries with the given item id. If the item is
+ * shareable, there might be more than one cache entry for this item.
*
- * @param id id of the item to remove from the cache
+ * @param id id of the items to remove from the cache
* @return <code>true</code> if the item was contained in this cache,
* <code>false</code> otherwise.
*/
- private boolean evictItem(ItemId id) {
+ private void evictItems(ItemId id) {
if (log.isDebugEnabled()) {
- log.debug("removing item " + id + " from cache");
+ log.debug("removing items " + id + " from cache");
}
synchronized (itemCache) {
- return itemCache.remove(id) != null;
+ itemCache.remove(id);
+ if (id.denotesNode()) {
+ shareableNodesCache.evictAll((NodeId) id);
+ }
+ }
+ }
+
+ /**
+ * Removes a cache entry for a specific item.
+ *
+ * @param id id of the item to remove from the cache
+ */
+ private void evictItem(ItemData data) {
+ if (log.isDebugEnabled()) {
+ log.debug("removing item " + data.getId() + " from cache");
+ }
+ synchronized (itemCache) {
+ if (data.isNode()) {
+ shareableNodesCache.evict((AbstractNodeData) data);
+ }
+ ItemData cached = (ItemData) itemCache.get(data.getId());
+ if (cached == data) {
+ itemCache.remove(data.getId());
+ }
}
}
+
//-------------------------------------------------< misc. helper methods >
/**
* Failsafe conversion of internal <code>Path</code> to JCR path for use in
@@ -801,51 +814,27 @@
}
//------------------------------------------------< ItemLifeCycleListener >
- /**
- * {@inheritDoc}
- */
- public void itemCreated(ItemImpl item) {
- if (log.isDebugEnabled()) {
- log.debug("created item " + item.getId());
- }
- // add instance to cache
- if (item.isNode()) {
- NodeImpl node = (NodeImpl) item;
- if (node.isShareable()) {
- shareableNodesCache.cache(node);
- return;
- }
- }
- cacheItem(item);
- }
/**
* {@inheritDoc}
*/
- public void itemInvalidated(ItemId id, ItemImpl item) {
+ public void itemInvalidated(ItemId id, ItemData data) {
if (log.isDebugEnabled()) {
log.debug("invalidated item " + id);
}
- // remove instance from cache
- evictItem(id);
- if (item.isNode()) {
- shareableNodesCache.evict((NodeImpl) item);
- }
+ evictItem(data);
}
/**
* {@inheritDoc}
*/
- public void itemDestroyed(ItemId id, ItemImpl item) {
+ public void itemDestroyed(ItemId id, ItemData data) {
if (log.isDebugEnabled()) {
log.debug("destroyed item " + id);
}
- // we're no longer interested in this item
- item.removeLifeCycleListener(this);
- // remove instance from cache
- evictItem(id);
- if (item.isNode()) {
- shareableNodesCache.evict((NodeImpl) item);
+ synchronized (itemCache) {
+ // remove instance from cache
+ evictItems(id);
}
}
@@ -884,9 +873,9 @@
* {@inheritDoc}
*/
public void stateCreated(ItemState created) {
- ItemImpl item = retrieveItem(created.getId());
- if (item != null) {
- item.stateCreated(created);
+ ItemData data = retrieveItem(created.getId());
+ if (data != null) {
+ data.setStatus(ItemImpl.STATUS_NORMAL);
}
}
@@ -894,9 +883,20 @@
* {@inheritDoc}
*/
public void stateModified(ItemState modified) {
- ItemImpl item = retrieveItem(modified.getId());
- if (item != null) {
- item.stateModified(modified);
+ ItemData data = retrieveItem(modified.getId());
+ if (data != null && data.getState() == modified) {
+ data.setStatus(ItemImpl.STATUS_MODIFIED);
+ /*
+ if (modified.isNode()) {
+ NodeState state = (NodeState) modified;
+ if (state.isShareable()) {
+ //evictItem(modified.getId());
+ NodeData nodeData = (NodeData) data;
+ NodeData shareSibling = new NodeData(nodeData, state.getParentId());
+ shareableNodesCache.cache(shareSibling);
+ }
+ }
+ */
}
}
@@ -904,9 +904,13 @@
* {@inheritDoc}
*/
public void stateDestroyed(ItemState destroyed) {
- ItemImpl item = retrieveItem(destroyed.getId());
- if (item != null) {
- item.stateDestroyed(destroyed);
+ ItemData data = retrieveItem(destroyed.getId());
+ if (data != null) {
+ data.setStatus(ItemImpl.STATUS_DESTROYED);
+ if (data.getState() == destroyed) {
+ data.setState(null);
+ }
+ itemDestroyed(destroyed.getId(), data);
}
}
@@ -914,54 +918,74 @@
* {@inheritDoc}
*/
public void stateDiscarded(ItemState discarded) {
- ItemImpl item = retrieveItem(discarded.getId());
- if (item != null) {
- item.stateDiscarded(discarded);
- }
- }
-
- /**
- * Invoked by a shareable <code>NodeImpl</code> when it is has become
- * transient and has therefore replaced its state. Will inform all other
- * nodes in the shareable set about this change.
- *
- * @param node node that has changed its underlying state
- */
- public void becameTransient(NodeImpl node) {
- NodeState state = (NodeState) node.getItemState();
-
- NodeImpl n = (NodeImpl) retrieveItem(node.getId());
- if (n != null && n != node) {
- n.stateReplaced(state);
- }
- shareableNodesCache.stateReplaced(node);
- }
-
- /**
- * Invoked by a shareable <code>NodeImpl</code> when it is has become
- * persistent and has therefore replaced its state. Will inform all other
- * nodes in the shareable set about this change.
- *
- * @param node node that has changed its underlying state
- */
- public void persisted(NodeImpl node) {
- // item has possibly become shareable on this call: move it
- // from the main cache to the cache of shareable nodes
- if (evictItem(node.getNodeId())) {
- shareableNodesCache.cache(node);
- }
-
- NodeState state = (NodeState) node.getItemState();
+ ItemData data = retrieveItem(discarded.getId());
+ if (data != null && data.getState() == discarded) {
+ if (discarded.isTransient()) {
+ switch (discarded.getStatus()) {
+ /**
+ * persistent item that has been transiently removed
+ */
+ case ItemState.STATUS_EXISTING_REMOVED:
+ case ItemState.STATUS_EXISTING_MODIFIED:
+ case ItemState.STATUS_STALE_MODIFIED:
+ ItemState persistentState = discarded.getOverlayedState();
+ /**
+ * the state is a transient wrapper for the underlying
+ * persistent state, therefore restore the persistent state
+ * and resurrect this item instance if necessary
+ */
+ SessionItemStateManager stateMgr = session.getItemStateManager();
+ stateMgr.disconnectTransientItemState(discarded);
+ data.setState(persistentState);
+ return;
+
+ /**
+ * persistent item that has been transiently modified or
+ * removed and the underlying persistent state has been
+ * externally destroyed since the transient
+ * modification/removal.
+ */
+ case ItemState.STATUS_STALE_DESTROYED:
+ /**
+ * first notify the listeners that this instance has been
+ * permanently invalidated
+ */
+ itemDestroyed(discarded.getId(), data);
+ // now set state of this instance to 'destroyed'
+ data.setStatus(ItemImpl.STATUS_DESTROYED);
+ data.setState(null);
+ return;
+
+ /**
+ * new item that has been transiently added
+ */
+ case ItemState.STATUS_NEW:
+ /**
+ * first notify the listeners that this instance has been
+ * permanently invalidated
+ */
+ itemDestroyed(discarded.getId(), data);
+ // now set state of this instance to 'destroyed'
+ // finally dispose state
+ data.setStatus(ItemImpl.STATUS_DESTROYED);
+ data.setState(null);
+ return;
+ }
+ }
- NodeImpl n = (NodeImpl) retrieveItem(node.getId());
- if (n != null && n != node) {
- n.stateReplaced(state);
+ /**
+ * first notify the listeners that this instance has been
+ * invalidated
+ */
+ itemInvalidated(discarded.getId(), data);
+ // now render this instance 'invalid'
+ data.setStatus(ItemImpl.STATUS_INVALIDATED);
}
- shareableNodesCache.stateReplaced(node);
}
/**
- * Cache of shareable nodes.
+ * Cache of shareable nodes. For performance reasons, methods are not
+ * synchronized and thread-safety must be guaranteed by caller.
*/
class ShareableNodesCache {
@@ -993,15 +1017,19 @@
* @param id node id
* @return node or <code>null</code>
*/
- public synchronized NodeImpl retrieve(NodeId id) {
+ public AbstractNodeData retrieveFirst(NodeId id) {
ReferenceMap map = (ReferenceMap) cache.get(id);
if (map != null) {
Iterator iter = map.values().iterator();
- while (iter.hasNext()) {
- NodeImpl node = (NodeImpl) iter.next();
- if (node != null) {
- return node;
+ try {
+ while (iter.hasNext()) {
+ AbstractNodeData data = (AbstractNodeData) iter.next();
+ if (data != null) {
+ return data;
+ }
}
+ } finally {
+ iter = null;
}
}
return null;
@@ -1014,10 +1042,10 @@
* @param parentId parent id
* @return node or <code>null</code>
*/
- public synchronized NodeImpl retrieve(NodeId id, NodeId parentId) {
+ public AbstractNodeData retrieve(NodeId id, NodeId parentId) {
ReferenceMap map = (ReferenceMap) cache.get(id);
if (map != null) {
- return (NodeImpl) map.get(parentId);
+ return (AbstractNodeData) map.get(parentId);
}
return null;
}
@@ -1027,13 +1055,14 @@
*
* @param node node to cache
*/
- public synchronized void cache(NodeImpl node) {
- ReferenceMap map = (ReferenceMap) cache.get(node.getId());
+ public void cache(AbstractNodeData data) {
+ NodeId id = data.getNodeState().getNodeId();
+ ReferenceMap map = (ReferenceMap) cache.get(id);
if (map == null) {
map = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.WEAK);
- cache.put(node.getId(), map);
+ cache.put(id, map);
}
- Object old = map.put(node.getParentId(), node);
+ Object old = map.put(data.getPrimaryParentId(), data);
if (old != null) {
log.warn("overwriting cached item: " + old);
}
@@ -1044,10 +1073,10 @@
*
* @param node node to evict
*/
- public synchronized void evict(NodeImpl node) {
- ReferenceMap map = (ReferenceMap) cache.get(node.getId());
+ public void evict(AbstractNodeData data) {
+ ReferenceMap map = (ReferenceMap) cache.get(data.getId());
if (map != null) {
- map.remove(node.getParentId());
+ map.remove(data.getPrimaryParentId());
}
}
@@ -1058,27 +1087,6 @@
*/
public synchronized void evictAll(NodeId id) {
cache.remove(id);
- }
-
- /**
- * Replace the state of all nodes that are in the same shared set
- * as the given node.
- *
- * @param node node in shared set.
- */
- public synchronized void stateReplaced(NodeImpl node) {
- NodeState state = (NodeState) node.getItemState();
-
- ReferenceMap map = (ReferenceMap) cache.get(node.getId());
- if (map != null) {
- Iterator iter = map.values().iterator();
- while (iter.hasNext()) {
- NodeImpl n = (NodeImpl) iter.next();
- if (n != null && n != node) {
- n.stateReplaced(state);
- }
- }
- }
}
}
}
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeData.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeData.java?rev=647767&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeData.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeData.java Mon Apr 14 05:35:33 2008
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+import javax.jcr.nodetype.NodeDefinition;
+import org.apache.jackrabbit.core.state.NodeState;
+
+/**
+ * Data object representing a node. Used for non-shareable nodes or for the
+ * first node in a shared set. For every share-sibling, <code>NodeDataRef</code>
+ * is used instead.
+ */
+class NodeData extends AbstractNodeData {
+
+ /**
+ * Create a new instance of this class.
+ *
+ * @param state node state
+ * @param definition node definition
+ */
+ NodeData(NodeState state, NodeDefinition definition) {
+ super(state, definition);
+ }
+}
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeDataRef.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeDataRef.java?rev=647767&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeDataRef.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeDataRef.java Mon Apr 14 05:35:33 2008
@@ -0,0 +1,78 @@
+/*
+ * 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;
+
+import javax.jcr.nodetype.ItemDefinition;
+import org.apache.jackrabbit.core.state.ItemState;
+
+/**
+ * Data object representing a node. Used for share-siblings of a shareable node
+ * that is already loaded.
+ */
+class NodeDataRef extends AbstractNodeData {
+
+ /** Referenced data object */
+ private final AbstractNodeData data;
+
+ /**
+ * Create a new instance of this class.
+ *
+ * @param data data to reference
+ * @param primaryParentId primary parent id
+ */
+ protected NodeDataRef(AbstractNodeData data, NodeId primaryParentId) {
+ this.data = data;
+
+ setPrimaryParentId(primaryParentId);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * This implementation returns the state of the referenced data object.
+ */
+ public ItemState getState() {
+ return data.getState();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * This implementation sets the state of the referenced data object.
+ */
+ protected void setState(ItemState state) {
+ data.setState(state);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * This implementation returns the definition of the referenced data object.
+ */
+ public ItemDefinition getDefinition() {
+ return data.getDefinition();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * This implementation sets the definition of the referenced data object.
+ */
+ protected void setDefinition(ItemDefinition definition) {
+ data.setDefinition(definition);
+ }
+}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java?rev=647767&r1=647766&r2=647767&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java Mon Apr 14 05:35:33 2008
@@ -111,14 +111,12 @@
/** the definition of this node */
protected NodeDefinition definition;
- /**
- * Primary parent id, if this is a shareable node, <code>null</code> otherwise.
- */
- private NodeId primaryParentId;
-
// flag set in status passed to getOrCreateProperty if property was created
protected static final short CREATED = 0;
+ /** node data (avoids casting <code>ItemImpl.data</code>) */
+ private final AbstractNodeData data;
+
/**
* Protected constructor.
*
@@ -129,13 +127,12 @@
* @param definition definition of <i>this</i> <code>Node</code>
* @param listeners listeners on life cylce changes of this <code>NodeImpl</code>
*/
- protected NodeImpl(ItemManager itemMgr, SessionImpl session, NodeId id,
- NodeState state, NodeDefinition definition,
- ItemLifeCycleListener[] listeners) {
- super(itemMgr, session, id, state, listeners);
- this.definition = definition;
+ protected NodeImpl(ItemManager itemMgr, SessionImpl session, AbstractNodeData data) {
+ super(itemMgr, session, data);
+ this.data = data;
// paranoid sanity check
NodeTypeRegistry ntReg = session.getNodeTypeManager().getNodeTypeRegistry();
+ final NodeState state = data.getNodeState();
if (ntReg.isRegistered(state.getNodeTypeName())) {
primaryTypeName = state.getNodeTypeName();
} else {
@@ -147,25 +144,6 @@
+ state.getNodeTypeName() + "' of node " + safeGetJCRPath());
primaryTypeName = NameConstants.NT_UNSTRUCTURED;
}
- if (isShareable()) {
- this.primaryParentId = state.getParentId();
- }
- }
-
- /**
- * Protected constructor. Used when creating a node that is a shared
- * sibling of another node, and that has the same properties, children nodes,
- * etc. as the other node.
- */
- protected NodeImpl(NodeImpl sharedSibling, NodeId parentId,
- ItemLifeCycleListener[] listeners) {
-
- super(sharedSibling.itemMgr, sharedSibling.session,
- sharedSibling.id, sharedSibling.state, listeners);
-
- this.definition = sharedSibling.definition;
- this.primaryTypeName = sharedSibling.primaryTypeName;
- this.primaryParentId = parentId;
}
/**
@@ -190,7 +168,7 @@
if (relPath.indexOf('/') == -1) {
Name propName = session.getQName(relPath);
// check if property entry exists
- NodeState thisState = (NodeState) state;
+ NodeState thisState = data.getNodeState();
if (thisState.hasPropertyName(propName)) {
return new PropertyId(thisState.getNodeId(), propName);
} else {
@@ -235,7 +213,7 @@
Path.Element pe = p.getNameElement();
if (pe.denotesName()) {
// check if node entry exists
- NodeState thisState = (NodeState) state;
+ NodeState thisState = data.getNodeState();
int index = pe.getIndex();
if (index == 0) {
index = 1;
@@ -280,23 +258,24 @@
protected synchronized ItemState getOrCreateTransientItemState()
throws RepositoryException {
- if (!isTransient()) {
- try {
- // make transient (copy-on-write)
- NodeState transientState =
- stateMgr.createTransientNodeState((NodeState) state, ItemState.STATUS_EXISTING_MODIFIED);
- // replace persistent with transient state
- state = transientState;
- if (isShareable()) {
- itemMgr.becameTransient(this);
+
+ synchronized (data) {
+ if (!isTransient()) {
+ try {
+ // make transient (copy-on-write)
+ NodeState transientState =
+ stateMgr.createTransientNodeState(
+ data.getNodeState(), ItemState.STATUS_EXISTING_MODIFIED);
+ // replace persistent with transient state
+ data.setState(transientState);
+ } catch (ItemStateException ise) {
+ String msg = "failed to create transient state";
+ log.debug(msg);
+ throw new RepositoryException(msg, ise);
}
- } catch (ItemStateException ise) {
- String msg = "failed to create transient state";
- log.debug(msg);
- throw new RepositoryException(msg, ise);
}
+ return getItemState();
}
- return state;
}
/**
@@ -318,7 +297,7 @@
* (e.g. using a NodeTypeInstanceHandler interface)
*/
- NodeState thisState = (NodeState) state;
+ NodeState thisState = data.getNodeState();
// compute system generated values
NodeTypeImpl nt = (NodeTypeImpl) def.getDeclaringNodeType();
@@ -508,7 +487,7 @@
}
// create Property instance wrapping new property state
- PropertyImpl prop = itemMgr.createPropertyInstance(propState, def);
+ PropertyImpl prop = (PropertyImpl) itemMgr.getItem(propState.getId());
// modify the state of 'this', i.e. the parent node
NodeState thisState = (NodeState) getOrCreateTransientItemState();
@@ -543,7 +522,7 @@
// create Node instance wrapping new node state
NodeImpl node;
try {
- node = itemMgr.createNodeInstance(nodeState, def);
+ node = (NodeImpl) itemMgr.getItem(id);
} catch (RepositoryException re) {
// something went wrong
stateMgr.disposeTransientItemState(nodeState);
@@ -645,7 +624,7 @@
NodeState thisState = (NodeState) getOrCreateTransientItemState();
// set id of new definition
thisState.setDefinitionId(defId);
- definition = newDef;
+ data.setDefinition(newDef);
}
protected void onRemove(NodeId parentId) throws RepositoryException {
@@ -659,10 +638,10 @@
// leave the child node entries and properties
// set state of this instance to 'invalid'
- status = STATUS_INVALIDATED;
- // notify the listeners that this instance has been
+ data.setStatus(STATUS_INVALIDATED);
+ // notify the item manager that this instance has been
// temporarily invalidated
- notifyInvalidated();
+ itemMgr.itemInvalidated(id, data);
return;
}
}
@@ -800,7 +779,7 @@
}
// check for name collisions
- NodeState thisState = (NodeState) state;
+ NodeState thisState = data.getNodeState();
NodeState.ChildNodeEntry cne = thisState.getChildNodeEntry(nodeName, 1);
if (cne != null) {
// there's already a child node entry with that name;
@@ -816,6 +795,7 @@
}
// check protected flag of parent (i.e. this) node
+ final NodeDefinition definition = data.getNodeDefinition();
if (definition.isProtected()) {
String msg = safeGetJCRPath() + ": cannot add a child to a protected node";
log.debug(msg);
@@ -827,7 +807,7 @@
}
private void setMixinTypesProperty(Set mixinNames) throws RepositoryException {
- NodeState thisState = (NodeState) state;
+ NodeState thisState = data.getNodeState();
// get or create jcr:mixinTypes property
PropertyImpl prop;
if (thisState.hasPropertyName(NameConstants.JCR_MIXINTYPES)) {
@@ -862,7 +842,7 @@
* @return a set of the <code>Name</code>s of this node's mixin types.
*/
public Set getMixinTypeNames() {
- return ((NodeState) state).getMixinTypeNames();
+ return data.getNodeState().getMixinTypeNames();
}
/**
@@ -873,7 +853,7 @@
* @throws RepositoryException if an error occurs
*/
public EffectiveNodeType getEffectiveNodeType() throws RepositoryException {
- return getEffectiveNodeType(((NodeState) state).getMixinTypeNames());
+ return getEffectiveNodeType(data.getNodeState().getMixinTypeNames());
}
/**
@@ -965,7 +945,7 @@
return;
}
- NodeState transientState = (NodeState) state;
+ NodeState transientState = data.getNodeState();
NodeState persistentState = (NodeState) transientState.getOverlayedState();
if (persistentState == null) {
@@ -1002,16 +982,12 @@
// tell state manager to disconnect item state
stateMgr.disconnectTransientItemState(transientState);
// swap transient state with persistent state
- state = persistentState;
+ data.setState(persistentState);
// reset status
- status = STATUS_NORMAL;
+ data.setStatus(STATUS_NORMAL);
- if (isShareable()) {
- // if node has become shareable, set its primary parent id
- if (primaryParentId == null) {
- primaryParentId = state.getParentId();
- }
- itemMgr.persisted(this);
+ if (isShareable() && data.getPrimaryParentId() == null) {
+ data.setPrimaryParentId(persistentState.getParentId());
}
}
@@ -1052,6 +1028,7 @@
}
// check protected flag
+ final NodeDefinition definition = data.getNodeDefinition();
if (definition.isProtected()) {
String msg = safeGetJCRPath() + ": cannot add a mixin node type to a protected node";
log.debug(msg);
@@ -1078,7 +1055,7 @@
EffectiveNodeType entExisting;
try {
// existing mixin's
- HashSet set = new HashSet(((NodeState) state).getMixinTypeNames());
+ HashSet set = new HashSet(data.getNodeState().getMixinTypeNames());
// primary type
set.add(primaryTypeName);
// build effective node type representing primary type including existing mixin's
@@ -1164,6 +1141,7 @@
}
// check protected flag
+ NodeDefinition definition = data.getNodeDefinition();
if (definition.isProtected()) {
String msg = safeGetJCRPath()
+ ": cannot remove a mixin node type from a protected node";
@@ -1175,7 +1153,8 @@
checkLock();
// check if mixin is assigned
- if (!((NodeState) state).getMixinTypeNames().contains(mixinName)) {
+ final NodeState state = data.getNodeState();
+ if (!state.getMixinTypeNames().contains(mixinName)) {
throw new NoSuchNodeTypeException();
}
@@ -1183,7 +1162,7 @@
NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
// build effective node type of remaining mixin's & primary type
- Set remainingMixins = new HashSet(((NodeState) state).getMixinTypeNames());
+ Set remainingMixins = new HashSet(state.getMixinTypeNames());
// remove name of target mixin
remainingMixins.remove(mixinName);
EffectiveNodeType entRemaining;
@@ -1282,7 +1261,7 @@
if (ntName.equals(primaryTypeName)) {
return true;
}
- Set mixins = ((NodeState) state).getMixinTypeNames();
+ Set mixins = data.getNodeState().getMixinTypeNames();
if (mixins.contains(ntName)) {
return true;
}
@@ -1456,7 +1435,7 @@
// check state of this instance
sanityCheck();
- NodeState thisState = (NodeState) state;
+ NodeState thisState = data.getNodeState();
if (index == 0) {
index = 1;
}
@@ -1498,7 +1477,7 @@
// check state of this instance
sanityCheck();
- NodeState thisState = (NodeState) state;
+ NodeState thisState = data.getNodeState();
if (index == 0) {
index = 1;
}
@@ -1545,7 +1524,7 @@
// check state of this instance
sanityCheck();
- NodeState thisState = (NodeState) state;
+ NodeState thisState = data.getNodeState();
if (!thisState.hasPropertyName(name)) {
return false;
}
@@ -1830,6 +1809,7 @@
}
// check protected flag
+ final NodeDefinition definition = data.getNodeDefinition();
if (definition.isProtected()) {
String msg = safeGetJCRPath()
+ ": cannot change child node ordering of a protected node";
@@ -1840,7 +1820,7 @@
// check lock status
checkLock();
- ArrayList list = new ArrayList(((NodeState) state).getChildNodeEntries());
+ ArrayList list = new ArrayList(data.getNodeState().getChildNodeEntries());
int srcInd = -1, destInd = -1;
for (int i = 0; i < list.size(); i++) {
NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) list.get(i);
@@ -1930,12 +1910,13 @@
// child node entries (JCR-1055);
// => backup list of child node entries beforehand in order
// to restore it afterwards
- NodeState.ChildNodeEntry cneExisting = ((NodeState) state).getChildNodeEntry(id);
+ NodeState state = data.getNodeState();
+ NodeState.ChildNodeEntry cneExisting = state.getChildNodeEntry(id);
if (cneExisting == null) {
throw new ItemNotFoundException(safeGetJCRPath()
+ ": no child node entry with id " + id);
}
- List cneList = new ArrayList(((NodeState) state).getChildNodeEntries());
+ List cneList = new ArrayList(state.getChildNodeEntries());
// remove existing
existing.remove();
@@ -1948,21 +1929,24 @@
}
}
+ // fetch <code>state</code> again, as it changed while removing child
+ state = data.getNodeState();
+
// restore list of child node entries (JCR-1055)
if (cneExisting.getName().equals(nodeName)) {
// restore original child node list
- ((NodeState) state).setChildNodeEntries(cneList);
+ state.setChildNodeEntries(cneList);
} else {
// replace child node entry with different name
// but preserving original position
- ((NodeState) state).removeAllChildNodeEntries();
+ state.removeAllChildNodeEntries();
for (Iterator iter = cneList.iterator(); iter.hasNext();) {
NodeState.ChildNodeEntry cne = (NodeState.ChildNodeEntry) iter.next();
if (cne.getId().equals(id)) {
// replace entry with different name
- ((NodeState) state).addChildNodeEntry(nodeName, id);
+ state.addChildNodeEntry(nodeName, id);
} else {
- ((NodeState) state).addChildNodeEntry(cne.getName(), cne.getId());
+ state.addChildNodeEntry(cne.getName(), cne.getId());
}
}
}
@@ -2019,7 +2003,7 @@
log.debug(msg);
throw new ConstraintViolationException(msg, re);
}
- NodeState thisState = (NodeState) state;
+ NodeState thisState = data.getNodeState();
NodeState.ChildNodeEntry cne = thisState.getChildNodeEntry(name, 1);
if (cne != null) {
// there's already a child node entry with that name;
@@ -2035,6 +2019,7 @@
}
// (4) check protected flag of parent (i.e. this) node
+ final NodeDefinition definition = data.getNodeDefinition();
if (definition.isProtected()) {
String msg = safeGetJCRPath() + ": cannot add a child to a protected node";
log.debug(msg);
@@ -2069,6 +2054,7 @@
// check state of this instance
sanityCheck();
+ final NodeState state = data.getNodeState();
if (state.getParentId() == null) {
// this is the root node
return "";
@@ -2103,16 +2089,12 @@
// check state of this instance
sanityCheck();
- // check if shareable node
- NodeId parentId = this.primaryParentId;
+ // check if root node
+ NodeId parentId = getParentId();
if (parentId == null) {
- // check if root node
- parentId = state.getParentId();
- if (parentId == null) {
- String msg = "root node doesn't have a parent";
- log.debug(msg);
- throw new ItemNotFoundException(msg);
- }
+ String msg = "root node doesn't have a parent";
+ log.debug(msg);
+ throw new ItemNotFoundException(msg);
}
return (Node) itemMgr.getItem(parentId);
}
@@ -2627,7 +2609,7 @@
throw new PathNotFoundException(relPath);
}
try {
- if (((NodeState) state).hasChildNodeEntry(id)) {
+ if (data.getNodeState().hasChildNodeEntry(id)) {
return itemMgr.getNode(id, getNodeId());
}
return (NodeImpl) itemMgr.getItem(id);
@@ -2789,7 +2771,7 @@
// check state of this instance
sanityCheck();
- Set mixinNames = ((NodeState) state).getMixinTypeNames();
+ Set mixinNames = data.getNodeState().getMixinTypeNames();
if (mixinNames.isEmpty()) {
return new NodeType[0];
}
@@ -2844,7 +2826,7 @@
}
// check protected flag
- if (definition.isProtected()) {
+ if (data.getNodeDefinition().isProtected()) {
return false;
}
@@ -2879,7 +2861,7 @@
EffectiveNodeType entExisting;
try {
// existing mixin's
- HashSet set = new HashSet(((NodeState) state).getMixinTypeNames());
+ HashSet set = new HashSet(data.getNodeState().getMixinTypeNames());
// primary type
set.add(primaryTypeName);
// build effective node type representing primary type including existing mixin's
@@ -2927,7 +2909,7 @@
// check state of this instance
sanityCheck();
- return definition;
+ return data.getNodeDefinition();
}
/**
@@ -3104,7 +3086,7 @@
if (!isShareable()) {
list.add(this);
} else {
- NodeState state = (NodeState) this.state;
+ NodeState state = data.getNodeState();
Iterator iter = state.getSharedSet().iterator();
while (iter.hasNext()) {
NodeId parentId = (NodeId) iter.next();
@@ -3182,7 +3164,7 @@
* @see NodeState#isShareable()
*/
boolean isShareable() {
- return ((NodeState) state).isShareable();
+ return data.getNodeState().isShareable();
}
/**
@@ -3194,10 +3176,7 @@
* @return parent id
*/
NodeId getParentId() {
- if (primaryParentId != null) {
- return primaryParentId;
- }
- return state.getParentId();
+ return data.getParentId();
}
/**
@@ -3209,7 +3188,7 @@
* <code>false</code> otherwise.
*/
boolean hasShareParent(NodeId parentId) {
- return ((NodeState) state).containsShare(parentId);
+ return data.getNodeState().containsShare(parentId);
}
/**
@@ -3241,7 +3220,7 @@
// quickly verify whether the share is already contained before creating
// a transient state in vain
- NodeState state = (NodeState) this.state;
+ NodeState state = data.getNodeState();
if (!state.containsShare(parentId)) {
state = (NodeState) getOrCreateTransientItemState();
if (state.addShare(parentId)) {
@@ -3276,7 +3255,7 @@
NodeState.ChildNodeEntry entry = ((NodeState) parentNode.getItemState()).
getChildNodeEntry(getNodeId());
if (entry == null) {
- String msg = "failed to build path of " + state.getId() + ": "
+ String msg = "failed to build path of " + id + ": "
+ parentId + " has no child entry for "
+ id;
log.debug(msg);
@@ -3291,16 +3270,6 @@
return builder.getPath();
}
- /**
- * Invoked when another node in the same shared set has replaced the
- * node state.
- *
- * @param state state that is now stored as <code>NodeImpl</code>'s state
- */
- void stateReplaced(NodeState state) {
- this.state = state;
- }
-
//------------------------------< versioning support: public Node methods >
/**
* {@inheritDoc}
@@ -3765,7 +3734,7 @@
Set set = internalGetMergeFailed();
set.add(srcNode.getBaseVersion().getUUID());
internalSetMergeFailed(set);
- failedIds.add(state.getId());
+ failedIds.add(id);
return null;
} else {
String msg = "Unable to merge nodes. Violating versions. " + safeGetJCRPath();
@@ -4764,12 +4733,13 @@
}
// check protected flag
- if (definition.isProtected()) {
+ if (data.getDefinition().isProtected()) {
String msg = safeGetJCRPath() + ": cannot set primary type of a protected node";
log.debug(msg);
throw new ConstraintViolationException(msg);
}
+ final NodeState state = data.getNodeState();
if (state.getParentId() == null) {
String msg = "changing the primary type of the root node is not supported";
log.debug(msg);
@@ -4805,7 +4775,7 @@
entOld = ntReg.getEffectiveNodeType(primaryTypeName);
// existing mixin's
- HashSet set = new HashSet(((NodeState) state).getMixinTypeNames());
+ HashSet set = new HashSet(state.getMixinTypeNames());
// new primary type
set.add(ntName);
// try to build new effective node type (will throw in case of conflicts)
@@ -4825,7 +4795,7 @@
throw new ConstraintViolationException(msg, re);
}
- if (!defId.equals(((NodeState) state).getDefinitionId())) {
+ if (!defId.equals(state.getDefinitionId())) {
onRedefine(defId);
}
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyData.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyData.java?rev=647767&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyData.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyData.java Mon Apr 14 05:35:33 2008
@@ -0,0 +1,54 @@
+/*
+ * 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;
+
+import javax.jcr.nodetype.PropertyDefinition;
+import org.apache.jackrabbit.core.state.PropertyState;
+
+/**
+ * Data object representing a property.
+ */
+public class PropertyData extends ItemData {
+
+ /**
+ * Create a new instance of this class.
+ *
+ * @param state associated property state
+ * @param definition associated property definition
+ */
+ PropertyData(PropertyState state, PropertyDefinition definition) {
+ super(state, definition);
+ }
+
+ /**
+ * Return the associated property state.
+ *
+ * @return property state
+ */
+ public PropertyState getPropertyState() {
+ return (PropertyState) getState();
+ }
+
+ /**
+ * Return the associated property definition.
+ *
+ * @return property definition
+ */
+ public PropertyDefinition getPropertyDefinition() {
+ return (PropertyDefinition) getDefinition();
+ }
+}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java?rev=647767&r1=647766&r2=647767&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/PropertyImpl.java Mon Apr 14 05:35:33 2008
@@ -53,7 +53,8 @@
private static Logger log = LoggerFactory.getLogger(PropertyImpl.class);
- private final PropertyDefinition definition;
+ /** property data (avoids casting <code>ItemImpl.data</code>) */
+ private final PropertyData data;
/**
* Package private constructor.
@@ -65,11 +66,9 @@
* @param definition definition of <i>this</i> <code>Property</code>
* @param listeners listeners on life cylce changes of this <code>PropertyImpl</code>
*/
- PropertyImpl(ItemManager itemMgr, SessionImpl session, PropertyId id,
- PropertyState state, PropertyDefinition definition,
- ItemLifeCycleListener[] listeners) {
- super(itemMgr, session, id, state, listeners);
- this.definition = definition;
+ PropertyImpl(ItemManager itemMgr, SessionImpl session, PropertyData data) {
+ super(itemMgr, session, data);
+ this.data = data;
// value will be read on demand
}
@@ -90,20 +89,24 @@
protected synchronized ItemState getOrCreateTransientItemState()
throws RepositoryException {
- if (!isTransient()) {
- // make transient (copy-on-write)
- try {
- PropertyState transientState =
- stateMgr.createTransientPropertyState((PropertyState) state, ItemState.STATUS_EXISTING_MODIFIED);
- // swap persistent with transient state
- state = transientState;
- } catch (ItemStateException ise) {
- String msg = "failed to create transient state";
- log.debug(msg);
- throw new RepositoryException(msg, ise);
+
+ synchronized (data) {
+ if (!isTransient()) {
+ // make transient (copy-on-write)
+ try {
+ PropertyState transientState =
+ stateMgr.createTransientPropertyState(
+ data.getPropertyState(), ItemState.STATUS_EXISTING_MODIFIED);
+ // swap persistent with transient state
+ data.setState(transientState);
+ } catch (ItemStateException ise) {
+ String msg = "failed to create transient state";
+ log.debug(msg);
+ throw new RepositoryException(msg, ise);
+ }
}
+ return getItemState();
}
- return state;
}
protected void makePersistent() throws InvalidItemStateException {
@@ -112,7 +115,7 @@
return;
}
- PropertyState transientState = (PropertyState) state;
+ PropertyState transientState = data.getPropertyState();
PropertyState persistentState = (PropertyState) transientState.getOverlayedState();
if (persistentState == null) {
// this property is 'new'
@@ -139,9 +142,9 @@
// tell state manager to disconnect item state
stateMgr.disconnectTransientItemState(transientState);
// swap transient state with persistent state
- state = persistentState;
+ data.setState(persistentState);
// reset status
- status = STATUS_NORMAL;
+ data.setStatus(STATUS_NORMAL);
}
protected void restoreTransient(PropertyState transientState)
@@ -222,6 +225,7 @@
LockException, ConstraintViolationException,
RepositoryException {
NodeImpl parent = (NodeImpl) getParent();
+ PropertyDefinition definition = data.getPropertyDefinition();
// verify that parent node is checked-out
if (!parent.internalIsCheckedOut()) {
@@ -324,6 +328,7 @@
checkSetValue(false);
// check type according to definition of this property
+ final PropertyDefinition definition = data.getPropertyDefinition();
int reqType = definition.getRequiredType();
if (reqType == PropertyType.UNDEFINED) {
reqType = PropertyType.NAME;
@@ -373,6 +378,7 @@
checkSetValue(true);
// check type according to definition of this property
+ final PropertyDefinition definition = data.getPropertyDefinition();
int reqType = definition.getRequiredType();
if (reqType == PropertyType.UNDEFINED) {
reqType = PropertyType.NAME;
@@ -420,6 +426,7 @@
* @throws RepositoryException
*/
public InternalValue[] internalGetValues() throws RepositoryException {
+ final PropertyDefinition definition = data.getPropertyDefinition();
if (definition.isMultiple()) {
return getPropertyState().getValues();
} else {
@@ -438,6 +445,7 @@
* @throws RepositoryException
*/
public InternalValue internalGetValue() throws RepositoryException {
+ final PropertyDefinition definition = data.getPropertyDefinition();
if (definition.isMultiple()) {
throw new ValueFormatException(
this + " is a multi-valued property,"
@@ -583,6 +591,7 @@
checkSetValue(false);
// check type according to definition of this property
+ final PropertyDefinition definition = data.getPropertyDefinition();
int reqType = definition.getRequiredType();
if (reqType == PropertyType.UNDEFINED) {
if (value != null) {
@@ -652,6 +661,7 @@
}
}
+ final PropertyDefinition definition = data.getPropertyDefinition();
int reqType = definition.getRequiredType();
if (reqType == PropertyType.UNDEFINED) {
reqType = valueType; // use the given type as property type
@@ -705,7 +715,7 @@
// check state of this instance
sanityCheck();
- return definition;
+ return data.getPropertyDefinition();
}
public int getType() throws RepositoryException {