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/05/29 17:51:31 UTC
svn commit: r542571 [2/2] - in
/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi:
./ hierarchy/ nodetype/ operation/ state/ version/ xml/
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntryImpl.java?view=diff&rev=542571&r1=542570&r2=542571
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntryImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntryImpl.java Tue May 29 08:51:30 2007
@@ -22,7 +22,6 @@
import org.apache.jackrabbit.spi.NodeId;
import org.apache.jackrabbit.spi.Event;
import org.apache.jackrabbit.spi.ItemId;
-import org.apache.jackrabbit.spi.ChildInfo;
import org.apache.jackrabbit.spi.QNodeDefinition;
import org.apache.jackrabbit.spi.QPropertyDefinition;
import org.apache.jackrabbit.spi.IdFactory;
@@ -70,7 +69,7 @@
private String uniqueID;
/**
- * insertion-ordered collection of NodeEntry objects
+ * Insertion-ordered collection of NodeEntry objects.
*/
private ChildNodeEntries childNodeEntries;
@@ -81,16 +80,17 @@
private ChildNodeAttic childNodeAttic;
/**
- * Map of properties. Key = {@link QName} of property. Value = {@link
- * PropertyEntry}.
+ * Map of properties.<br>
+ * Key = {@link QName} of property,<br>
+ * Value = {@link PropertyEntry}.
*/
- private final HashMap properties = new HashMap();
+ private final ChildPropertyEntries properties;
/**
* Map of properties which are deleted and have been re-created as transient
* property with the same name.
*/
- private final HashMap propertiesInAttic = new HashMap();
+ private final Map propertiesInAttic;
/**
* Upon transient 'move' ('rename') or 'reorder' of SNSs this
@@ -112,10 +112,14 @@
* @param name the name of the child node.
* @param factory the entry factory.
*/
- NodeEntryImpl(NodeEntryImpl parent, QName name, String uniqueID, EntryFactory factory) {
+ private NodeEntryImpl(NodeEntryImpl parent, QName name, String uniqueID, EntryFactory factory) {
super(parent, name, factory);
this.uniqueID = uniqueID; // NOTE: don't use setUniqueID (for mod only)
- this.childNodeAttic = new ChildNodeAttic();
+
+ properties = new ChildPropertyEntriesImpl(this, factory);
+
+ propertiesInAttic = new HashMap();
+ childNodeAttic = new ChildNodeAttic();
factory.notifyEntryCreated(this);
}
@@ -128,6 +132,18 @@
return new NodeEntryImpl(null, QName.ROOT, null, factory);
}
+ /**
+ *
+ * @param parent
+ * @param name
+ * @param uniqueId
+ * @param factory
+ * @return
+ */
+ static NodeEntry createNodeEntry(NodeEntryImpl parent, QName name, String uniqueId, EntryFactory factory) {
+ return new NodeEntryImpl(parent, name, uniqueId, factory);
+ }
+
//-----------------------------------------------------< HierarchyEntry >---
/**
* Returns true.
@@ -147,7 +163,7 @@
if (recursive) {
// invalidate all child entries including properties present in the
// attic (removed props shadowed by a new property with the same name).
- for (Iterator it = getAllChildEntries(false, true); it.hasNext();) {
+ for (Iterator it = getAllChildEntries(true); it.hasNext();) {
HierarchyEntry ce = (HierarchyEntry) it.next();
ce.invalidate(recursive);
}
@@ -175,7 +191,7 @@
// did not cause this entry to be removed -> therefore check status.
if (recursive && !Status.isTerminal(getStatus())) {
// recursivly reload all entries including props that are in the attic.
- for (Iterator it = getAllChildEntries(true, true); it.hasNext();) {
+ for (Iterator it = getAllChildEntries(true); it.hasNext();) {
HierarchyEntry ce = (HierarchyEntry) it.next();
ce.reload(keepChanges, recursive);
}
@@ -194,7 +210,7 @@
public void revert() throws RepositoryException {
// move all properties from attic back to properties map
if (!propertiesInAttic.isEmpty()) {
- properties.putAll(propertiesInAttic);
+ properties.addAll(propertiesInAttic.values());
propertiesInAttic.clear();
}
@@ -208,14 +224,14 @@
* @see HierarchyEntry#transientRemove()
*/
public void transientRemove() throws RepositoryException {
- for (Iterator it = getAllChildEntries(true, false); it.hasNext();) {
+ for (Iterator it = getAllChildEntries(false); it.hasNext();) {
HierarchyEntry ce = (HierarchyEntry) it.next();
ce.transientRemove();
}
if (!propertiesInAttic.isEmpty()) {
// move all properties from attic back to properties map
- properties.putAll(propertiesInAttic);
+ properties.addAll(propertiesInAttic.values());
propertiesInAttic.clear();
}
@@ -240,7 +256,7 @@
// now traverse all child-entries and mark the attached states removed
// without removing the child-entries themselves. this is not required
// since this (i.e. the parent is removed as well).
- for (Iterator it = getAllChildEntries(true, true); it.hasNext();) {
+ for (Iterator it = getAllChildEntries(true); it.hasNext();) {
HierarchyEntryImpl ce = (HierarchyEntryImpl) it.next();
removeEntry(ce);
}
@@ -259,7 +275,7 @@
super.collectStates(changeLog, throwOnStale);
// collect transient child states including properties in attic.
- for (Iterator it = getAllChildEntries(true, true); it.hasNext();) {
+ for (Iterator it = getAllChildEntries(true); it.hasNext();) {
HierarchyEntry ce = (HierarchyEntry) it.next();
ce.collectStates(changeLog, throwOnStale);
}
@@ -363,31 +379,27 @@
if (elem.denotesRoot()) {
if (getParent() != null) {
throw new RepositoryException("NodeEntry out of 'hierarchy'" + path.toString());
- } else {
- continue;
}
+ continue;
}
int index = elem.getNormalizedIndex();
QName name = elem.getName();
- // first try to resolve to nodeEntry or property entry
- NodeEntry cne = (entry.childNodeEntries == null) ? null : entry.childNodeEntries.get(name, index);
+ // first try to resolve to known node or property entry
+ NodeEntry cne = (entry.childNodeEntries == null) ? null : entry.getNodeEntry(name, index, false);
if (cne != null) {
entry = (NodeEntryImpl) cne;
- } else if (index == Path.INDEX_DEFAULT && entry.properties.containsKey(name)
- && i == path.getLength() - 1) {
+ } else if (index == Path.INDEX_DEFAULT && i == path.getLength() - 1 && entry.properties.contains(name)) {
// property must not have index && must be final path element
- return (PropertyEntry) entry.properties.get(name);
+ return entry.properties.get(name);
} else {
// no valid entry
// -> check for moved child entry in node-attic
- // -> check if child points to a removed sns
- if (entry.childNodeAttic.contains(name, index)) {
- throw new PathNotFoundException(path.toString());
- } else if (entry.childNodeEntries != null) {
- int noSNS = entry.childNodeEntries.get(name).size() + entry.childNodeAttic.get(name).size();
- if (index <= noSNS) {
+ // -> check if child points to a removed/moved sns
+ if (entry.childNodeEntries != null) {
+ List siblings = entry.childNodeEntries.get(name);
+ if (entry.containsAtticChild(siblings, name, index)) {
throw new PathNotFoundException(path.toString());
}
}
@@ -414,23 +426,24 @@
throw new RepositoryException("Invalid path");
}
- NodeId anyId = entry.getId();
+ NodeId parentId = entry.getId();
IdFactory idFactory = entry.factory.getIdFactory();
- NodeId nodeId = idFactory.createNodeId(anyId, remainingPath);
- try {
- NodeState state = entry.factory.getItemStateFactory().createDeepNodeState(nodeId, entry);
- return state.getHierarchyEntry();
- } catch (ItemNotFoundException e) {
+
+ NodeId nodeId = idFactory.createNodeId(parentId, remainingPath);
+ NodeEntry ne = entry.loadNodeEntry(nodeId);
+ if (ne != null) {
+ return ne;
+ } else {
if (index != Path.INDEX_DEFAULT) {
- throw new PathNotFoundException(path.toString(), e);
+ throw new PathNotFoundException(path.toString());
}
- // possibly propstate
- try {
- nodeId = (remainingPath.getLength() == 1) ? anyId : idFactory.createNodeId(anyId, remainingPath.getAncestor(1));
- PropertyId id = idFactory.createPropertyId(nodeId, remainingPath.getNameElement().getName());
- PropertyState state = entry.factory.getItemStateFactory().createDeepPropertyState(id, entry);
- return state.getHierarchyEntry();
- } catch (ItemNotFoundException ise) {
+ // maybe a property entry exists
+ parentId = (remainingPath.getLength() == 1) ? parentId : idFactory.createNodeId(parentId, remainingPath.getAncestor(1));
+ PropertyId propId = idFactory.createPropertyId(parentId, remainingPath.getNameElement().getName());
+ PropertyEntry pe = entry.loadPropertyEntry(propId);
+ if (pe != null) {
+ return pe;
+ } else {
throw new PathNotFoundException(path.toString());
}
}
@@ -451,16 +464,15 @@
if (getParent() != null) {
log.warn("NodeEntry out of 'hierarchy'" + workspacePath.toString());
return null;
- } else {
- continue;
}
+ continue;
}
int index = elem.getNormalizedIndex();
QName childName = elem.getName();
// first try to resolve node
- NodeEntry cne = entry.lookupNodeEntry(childName, index);
+ NodeEntry cne = entry.lookupNodeEntry(null, childName, index);
if (cne != null) {
entry = (NodeEntryImpl) cne;
} else if (index == Path.INDEX_DEFAULT && i == workspacePath.getLength() - 1) {
@@ -483,11 +495,7 @@
if (namedEntries.isEmpty()) {
return false;
} else {
- // copy list since during validation the childNodeEntries may be
- // modified if upon NodeEntry.getItemState the entry is removed.
- List l = new ArrayList(namedEntries.size());
- l.addAll(namedEntries);
- return EntryValidation.containsValidNodeEntry(l.iterator());
+ return EntryValidation.containsValidNodeEntry(namedEntries.iterator());
}
} catch (RepositoryException e) {
log.debug("Unable to determine if a child node with name " + nodeName + " exists.");
@@ -501,7 +509,7 @@
*/
public synchronized boolean hasNodeEntry(QName nodeName, int index) {
try {
- return EntryValidation.isValidNodeEntry(childNodeEntries().get(nodeName, index));
+ return getNodeEntry(nodeName, index) != null;
} catch (RepositoryException e) {
log.debug("Unable to determine if a child node with name " + nodeName + " exists.");
return false;
@@ -513,37 +521,30 @@
* @see NodeEntry#getNodeEntry(QName, int)
*/
public synchronized NodeEntry getNodeEntry(QName nodeName, int index) throws RepositoryException {
- NodeEntry cne = childNodeEntries().get(nodeName, index);
- if (EntryValidation.isValidNodeEntry(cne)) {
- return cne;
- } else {
- return null;
- }
+ return getNodeEntry(nodeName, index, false);
}
-
/**
* @inheritDoc
- * @see NodeEntry#getNodeEntry(NodeId)
+ * @see NodeEntry#getNodeEntry(QName, int, boolean)
*/
- public synchronized NodeEntry getNodeEntry(NodeId childId) throws RepositoryException {
- String uid = childId.getUniqueID();
- Path path = childId.getPath();
- NodeEntry cne;
- if (uid != null && path == null) {
- // retrieve child-entry by uid
- cne = childNodeEntries().get(null, uid);
- } else {
- // retrieve child-entry by name and index
- Path.PathElement nameElement = path.getNameElement();
- cne = childNodeEntries().get(nameElement.getName(), nameElement.getIndex());
- }
-
- if (EntryValidation.isValidNodeEntry(cne)) {
- return cne;
- } else {
- return null;
+ public NodeEntry getNodeEntry(QName nodeName, int index, boolean loadIfNotFound) throws RepositoryException {
+ List entries = childNodeEntries().get(nodeName);
+ NodeEntry cne = null;
+ if (entries.size() >= index) {
+ // position of entry might differ from index-1 if a SNS with lower
+ // index has been transiently removed.
+ for (int i = index-1; i < entries.size() && cne == null; i++) {
+ NodeEntry ne = (NodeEntry) entries.get(i);
+ if (EntryValidation.isValidNodeEntry(ne)) {
+ cne = ne;
+ }
+ }
+ } else if (loadIfNotFound && !containsAtticChild(entries, nodeName, index)) {
+ NodeId cId = factory.getIdFactory().createNodeId(getId(), Path.create(nodeName, index));
+ cne = loadNodeEntry(cId);
}
+ return cne;
}
/**
@@ -552,11 +553,10 @@
*/
public synchronized Iterator getNodeEntries() throws RepositoryException {
Collection entries = new ArrayList();
- Object[] arr = childNodeEntries().toArray();
- for (int i = 0; i < arr.length; i++) {
- NodeEntry cne = (NodeEntry) arr[i];
- if (EntryValidation.isValidNodeEntry(cne)) {
- entries.add(cne);
+ for (Iterator it = childNodeEntries().iterator(); it.hasNext();) {
+ NodeEntry entry = (NodeEntry) it.next();
+ if (EntryValidation.isValidNodeEntry(entry)) {
+ entries.add(entry);
}
}
return Collections.unmodifiableCollection(entries).iterator();
@@ -598,9 +598,9 @@
*/
public NodeState addNewNodeEntry(QName nodeName, String uniqueID,
QName primaryNodeType, QNodeDefinition definition) throws RepositoryException {
- NodeEntryImpl entry = internalAddNodeEntry(nodeName, uniqueID, Path.INDEX_UNDEFINED, childNodeEntries());
+ NodeEntry entry = internalAddNodeEntry(nodeName, uniqueID, Path.INDEX_UNDEFINED, childNodeEntries());
NodeState state = factory.getItemStateFactory().createNewNodeState(entry, primaryNodeType, definition);
- entry.internalSetItemState(state);
+ ((NodeEntryImpl) entry).internalSetItemState(state);
return state;
}
@@ -612,9 +612,9 @@
* @param childEntries
* @return
*/
- private NodeEntryImpl internalAddNodeEntry(QName nodeName, String uniqueID,
+ private NodeEntry internalAddNodeEntry(QName nodeName, String uniqueID,
int index, ChildNodeEntries childEntries) {
- NodeEntryImpl entry = new NodeEntryImpl(this, nodeName, uniqueID, factory);
+ NodeEntry entry = factory.createNodeEntry(this, nodeName, uniqueID);
childEntries.add(entry, index);
return entry;
}
@@ -624,7 +624,7 @@
* @see NodeEntry#hasPropertyEntry(QName)
*/
public synchronized boolean hasPropertyEntry(QName propName) {
- PropertyEntry entry = (PropertyEntry) properties.get(propName);
+ PropertyEntry entry = properties.get(propName);
return EntryValidation.isValidPropertyEntry(entry);
}
@@ -633,7 +633,7 @@
* @see NodeEntry#getPropertyEntry(QName)
*/
public synchronized PropertyEntry getPropertyEntry(QName propName) {
- PropertyEntry entry = (PropertyEntry) properties.get(propName);
+ PropertyEntry entry = properties.get(propName);
if (EntryValidation.isValidPropertyEntry(entry)) {
return entry;
} else {
@@ -643,6 +643,21 @@
/**
* @inheritDoc
+ * @see NodeEntry#getPropertyEntry(QName, boolean)
+ */
+ public PropertyEntry getPropertyEntry(QName propName, boolean loadIfNotFound) throws RepositoryException {
+ PropertyEntry entry = properties.get(propName);
+ if (entry == null && loadIfNotFound) {
+ PropertyId propId = factory.getIdFactory().createPropertyId(getId(), propName);
+ entry = loadPropertyEntry(propId);
+ } else if (!EntryValidation.isValidPropertyEntry(entry)) {
+ entry = null;
+ }
+ return entry;
+ }
+
+ /**
+ * @inheritDoc
* @see NodeEntry#getPropertyEntries()
*/
public synchronized Iterator getPropertyEntries() {
@@ -651,7 +666,7 @@
// filter out removed properties
props = new ArrayList();
// use array since upon validation the entry might be removed.
- Object[] arr = properties.values().toArray();
+ Object[] arr = properties.getPropertyEntries().toArray();
for (int i = 0; i < arr.length; i++) {
PropertyEntry propEntry = (PropertyEntry) arr[i];
if (EntryValidation.isValidPropertyEntry(propEntry)) {
@@ -660,7 +675,7 @@
}
} else {
// no need to filter out properties, there are no removed properties
- props = properties.values();
+ props = properties.getPropertyEntries();
}
return Collections.unmodifiableCollection(props).iterator();
}
@@ -682,8 +697,8 @@
* @return
*/
private PropertyEntry internalAddPropertyEntry(QName propName) {
- PropertyEntry entry = PropertyEntryImpl.create(this, propName, factory);
- properties.put(propName, entry);
+ PropertyEntry entry = factory.createPropertyEntry(this, propName);
+ properties.add(entry);
// if property-name is jcr:uuid or jcr:mixin this affects this entry
// and the attached nodeState.
@@ -699,13 +714,13 @@
*/
public void addPropertyEntries(Collection propNames) throws ItemExistsException, RepositoryException {
Set diff = new HashSet();
- diff.addAll(properties.keySet());
+ diff.addAll(properties.getPropertyNames());
boolean containsExtra = diff.removeAll(propNames);
// add all entries that are missing
for (Iterator it = propNames.iterator(); it.hasNext();) {
QName propName = (QName) it.next();
- if (!properties.containsKey(propName)) {
+ if (!properties.contains(propName)) {
addPropertyEntry(propName);
}
}
@@ -717,7 +732,7 @@
if (containsExtra && (state == null || state.getStatus() == Status.INVALIDATED)) {
for (Iterator it = diff.iterator(); it.hasNext();) {
QName propName = (QName) it.next();
- PropertyEntry pEntry = (PropertyEntry) properties.get(propName);
+ PropertyEntry pEntry = properties.get(propName);
if (pEntry != null) {
pEntry.remove();
}
@@ -732,7 +747,7 @@
public PropertyState addNewPropertyEntry(QName propName, QPropertyDefinition definition)
throws ItemExistsException, RepositoryException {
// check for an existing property
- PropertyEntry existing = (PropertyEntry) properties.get(propName);
+ PropertyEntry existing = properties.get(propName);
if (existing != null) {
try {
PropertyState existingState = existing.getPropertyState();
@@ -759,8 +774,8 @@
}
// add the property entry
- PropertyEntry entry = PropertyEntryImpl.create(this, propName, factory);
- properties.put(propName, entry);
+ PropertyEntry entry = factory.createPropertyEntry(this, propName);
+ properties.add(entry);
PropertyState state = factory.getItemStateFactory().createNewPropertyState(entry, definition);
((PropertyEntryImpl) entry).internalSetItemState(state);
@@ -771,16 +786,14 @@
/**
* @param propName
*/
- PropertyEntry internalRemovePropertyEntry(QName propName) {
- PropertyEntry cpe = (PropertyEntry) properties.remove(propName);
- if (cpe == null) {
- cpe = (PropertyEntry) propertiesInAttic.remove(propName);
+ void internalRemovePropertyEntry(QName propName) {
+ if (!properties.remove(propName)) {
+ propertiesInAttic.remove(propName);
}
// special properties
if (StateUtility.isUuidOrMixin(propName)) {
notifyUUIDorMIXINRemoved(propName);
}
- return cpe;
}
/**
@@ -847,28 +860,36 @@
QName eventName = childEvent.getQPath().getNameElement().getName();
switch (childEvent.getType()) {
case Event.NODE_ADDED:
+ if (childNodeEntries == null) {
+ // childNodeEntries not yet loaded -> ignore
+ return;
+ }
+
int index = childEvent.getQPath().getNameElement().getNormalizedIndex();
String uniqueChildID = null;
if (childEvent.getItemId().getPath() == null) {
uniqueChildID = childEvent.getItemId().getUniqueID();
}
- // first check if no matching child entry exists.
+
// TODO: TOBEFIXED for SNSs
- if (childNodeEntries != null) {
- NodeEntry cne;
- if (uniqueChildID != null) {
- cne = childNodeEntries.get(eventName, uniqueChildID);
- } else {
- cne = childNodeEntries.get(eventName, index);
- }
+ // first check if no matching child entry exists.
+ NodeEntry cne;
+ if (uniqueChildID != null) {
+ cne = childNodeEntries.get(eventName, uniqueChildID);
if (cne == null) {
- internalAddNodeEntry(eventName, uniqueChildID, index, childNodeEntries);
- } else {
- // child already exists -> deal with NEW entries, that were
- // added by some other session.
- // TODO: TOBEFIXED
+ // entry may exist but without having uniqueID resolved
+ cne = childNodeEntries.get(eventName, index);
}
- } // else: childNodeEntries not yet loaded -> ignore
+ } else {
+ cne = childNodeEntries.get(eventName, index);
+ }
+ if (cne == null) {
+ internalAddNodeEntry(eventName, uniqueChildID, index, childNodeEntries);
+ } else {
+ // child already exists -> deal with NEW entries, that were
+ // added by some other session.
+ // TODO: TOBEFIXED
+ }
break;
case Event.PROPERTY_ADDED:
@@ -967,7 +988,7 @@
throw new RepositoryException("Invalid index " + index + " with nodeEntry " + nEntry);
}
- // TODO: check again. special treatment for index 0 for consistency with PathFormat.parse
+ // TODO: check again. special treatment for default index for consistency with PathFormat.parse
if (index == Path.INDEX_DEFAULT) {
builder.addLast(name);
} else {
@@ -986,7 +1007,7 @@
}
QName propName = propertyEntry.getQName();
if (propertiesInAttic.containsKey(propName)) {
- properties.put(propName, propertiesInAttic.remove(propName));
+ properties.add((PropertyEntry) propertiesInAttic.remove(propName));
} // else: propEntry has never been moved to the attic (see 'addPropertyEntry')
}
@@ -1027,6 +1048,36 @@
}
/**
+ *
+ * @param childId
+ * @return
+ */
+ private NodeEntry loadNodeEntry(NodeId childId) throws RepositoryException {
+ try {
+ NodeState state = factory.getItemStateFactory().createDeepNodeState(childId, this);
+ return state.getNodeEntry();
+ } catch (ItemNotFoundException e) {
+ return null;
+ }
+ }
+
+ /**
+ *
+ * @param childId
+ * @return
+ * @throws ItemNotFoundException
+ * @throws RepositoryException
+ */
+ private PropertyEntry loadPropertyEntry(PropertyId childId) throws RepositoryException {
+ try {
+ PropertyState state = factory.getItemStateFactory().createDeepPropertyState(childId, this);
+ return (PropertyEntry) state.getHierarchyEntry();
+ } catch (ItemNotFoundException e) {
+ return null;
+ }
+ }
+
+ /**
* Searches the child-entries of this NodeEntry for a matching child.
* Since {@link #refresh(Event)} must always be called on the parent
* NodeEntry, there is no need to check if a given event id would point
@@ -1038,44 +1089,37 @@
*/
private HierarchyEntry lookupEntry(ItemId eventId, Path eventPath) {
QName childName = eventPath.getNameElement().getName();
- HierarchyEntry child = null;
+ HierarchyEntry child;
if (eventId.denotesNode()) {
String uniqueChildID = (eventId.getPath() == null) ? eventId.getUniqueID() : null;
- // for external node-removal the attic must be consulted first
- // in order to be able to apply the changes to the proper node-entry.
- if (uniqueChildID != null) {
- child = childNodeAttic.get(uniqueChildID);
- if (child == null && childNodeEntries != null) {
- child = childNodeEntries.get(childName, uniqueChildID);
- }
- }
- if (child == null) {
- int index = eventPath.getNameElement().getNormalizedIndex();
- child = lookupNodeEntry(childName, index);
- }
+ int index = eventPath.getNameElement().getNormalizedIndex();
+ child = lookupNodeEntry(uniqueChildID, childName, index);
} else {
child = lookupPropertyEntry(childName);
}
- if (child != null) {
- // a NEW hierarchyEntry may never be affected by an external
- // modification -> return null.
- ItemState state = ((HierarchyEntryImpl) child).internalGetItemState();
- if (state != null && state.getStatus() == Status.NEW) {
- return null;
- }
- }
- return child;
+ // a NEW hierarchyEntry may never be affected by an external modification
+ // -> return null.
+ return (child == null || child.getStatus() == Status.NEW) ? null : child;
}
- private NodeEntryImpl lookupNodeEntry(QName childName, int index) {
- NodeEntryImpl child = (NodeEntryImpl) childNodeAttic.get(childName, index);
- if (child == null && childNodeEntries != null) {
- List namedChildren = childNodeEntries.get(childName);
- for (Iterator it = namedChildren.iterator(); it.hasNext(); ) {
- NodeEntryImpl c = (NodeEntryImpl) it.next();
- if (c.matches(childName, index)) {
- child = c;
- break;
+ private NodeEntry lookupNodeEntry(String uniqueChildId, QName childName, int index) {
+ NodeEntry child = null;
+ if (uniqueChildId != null) {
+ child = childNodeAttic.get(uniqueChildId);
+ if (child == null && childNodeEntries != null) {
+ child = childNodeEntries.get(childName, uniqueChildId);
+ }
+ }
+ if (child == null) {
+ child = childNodeAttic.get(childName, index);
+ if (child == null && childNodeEntries != null) {
+ List namedChildren = childNodeEntries.get(childName);
+ for (Iterator it = namedChildren.iterator(); it.hasNext(); ) {
+ NodeEntryImpl c = (NodeEntryImpl) it.next();
+ if (c.matches(childName, index)) {
+ child = c;
+ break;
+ }
}
}
}
@@ -1088,7 +1132,7 @@
// property with the same name.
PropertyEntry child = (PropertyEntry) propertiesInAttic.get(childName);
if (child == null) {
- child = (PropertyEntry) properties.get(childName);
+ child = properties.get(childName);
}
return child;
}
@@ -1136,17 +1180,17 @@
}
/**
- *
- * @return
+ * @return The <code>ChildNodeEntries</code> defined for this
+ * <code>NodeEntry</code>. Please note, that this method never returns
+ * <code>null</code>, since the child node entries are loaded/reloaded
+ * in case they have not been loaded yet.
*/
private ChildNodeEntries childNodeEntries() throws InvalidItemStateException, RepositoryException {
try {
if (childNodeEntries == null) {
- childNodeEntries = new ChildNodeEntries(this);
- loadChildNodeEntries();
+ childNodeEntries = new ChildNodeEntriesImpl(this, factory);
} else if (childNodeEntries.getStatus() == ChildNodeEntries.STATUS_INVALIDATED) {
- reloadChildNodeEntries(childNodeEntries);
- childNodeEntries.setStatus(ChildNodeEntries.STATUS_OK);
+ childNodeEntries.reload();
}
} catch (ItemNotFoundException e) {
log.debug("NodeEntry does not exist (anymore) -> remove.");
@@ -1156,68 +1200,6 @@
return childNodeEntries;
}
- private void loadChildNodeEntries() throws ItemNotFoundException, RepositoryException {
-
- if (getStatus() == Status.NEW || Status.isTerminal(getStatus())) {
- return; // cannot retrieve child-entries from persistent layer
- }
-
- NodeId id = getWorkspaceId();
- Iterator it = factory.getItemStateFactory().getChildNodeInfos(id);
- // simply add all child entries to the empty collection
- while (it.hasNext()) {
- ChildInfo ci = (ChildInfo) it.next();
- internalAddNodeEntry(ci.getName(), ci.getUniqueID(), ci.getIndex(), childNodeEntries);
- }
- }
-
- private void reloadChildNodeEntries(ChildNodeEntries cnEntries) throws ItemNotFoundException, RepositoryException {
- if (getStatus() == Status.NEW || Status.isTerminal(getStatus())) {
- // nothing to do
- return;
- }
- NodeId id = getWorkspaceId();
- Iterator it = factory.getItemStateFactory().getChildNodeInfos(id);
- // create list from all ChildInfos (for multiple loop)
- List cInfos = new ArrayList();
- while (it.hasNext()) {
- cInfos.add((ChildInfo) it.next());
- }
- // first make sure the ordering of all existing entries is ok
- NodeEntry entry = null;
- for (it = cInfos.iterator(); it.hasNext();) {
- ChildInfo ci = (ChildInfo) it.next();
- NodeEntry nextEntry = cnEntries.get(ci);
- if (nextEntry != null) {
- if (entry != null) {
- cnEntries.reorder(entry, nextEntry);
- }
- entry = nextEntry;
- }
- }
- // then insert the 'new' entries
- List newEntries = new ArrayList();
- for (it = cInfos.iterator(); it.hasNext();) {
- ChildInfo ci = (ChildInfo) it.next();
- NodeEntry beforeEntry = cnEntries.get(ci);
- if (beforeEntry == null) {
- NodeEntry ne = new NodeEntryImpl(this, ci.getName(), ci.getUniqueID(), factory);
- newEntries.add(ne);
- } else {
- // insert all new entries from the list BEFORE the existing
- // 'nextEntry'. Then clear the list.
- for (int i = 0; i < newEntries.size(); i++) {
- cnEntries.add((NodeEntry) newEntries.get(i), beforeEntry);
- }
- newEntries.clear();
- }
- }
- // deal with new entries at the end
- for (int i = 0; i < newEntries.size(); i++) {
- cnEntries.add((NodeEntry) newEntries.get(i));
- }
- }
-
/**
* Returns an Iterator over all children entries, that currently are loaded
* with this NodeEntry. NOTE, that if the childNodeEntries have not been
@@ -1229,26 +1211,23 @@
* @param includeAttic
* @return
*/
- private Iterator getAllChildEntries(boolean createNewList, boolean includeAttic) {
- Iterator[] its;
- if (createNewList) {
- List props = new ArrayList(properties.values());
- List children = (childNodeEntries == null) ? Collections.EMPTY_LIST : new ArrayList(childNodeEntries);
- if (includeAttic) {
- List attic = new ArrayList(propertiesInAttic.values());
- its = new Iterator[] {attic.iterator(), props.iterator(), children.iterator()};
- } else {
- its = new Iterator[] {props.iterator(), children.iterator()};
- }
- } else {
- Iterator children = (childNodeEntries == null) ? Collections.EMPTY_LIST.iterator() : childNodeEntries.iterator();
- if (includeAttic) {
- its = new Iterator[] {propertiesInAttic.values().iterator(), properties.values().iterator(), children};
- } else {
- its = new Iterator[] {properties.values().iterator(), children};
- }
+ private Iterator getAllChildEntries(boolean includeAttic) {
+ IteratorChain chain = new IteratorChain();
+ // attic
+ if (includeAttic) {
+ Collection attic = propertiesInAttic.values();
+ chain.addIterator(new ArrayList(attic).iterator());
+ }
+ // add props
+ synchronized (properties) {
+ Collection props = properties.getPropertyEntries();
+ chain.addIterator(props.iterator());
+ }
+ // add childNodeEntries
+ if (childNodeEntries != null) {
+ chain.addIterator(childNodeEntries.iterator());
}
- return new IteratorChain(its);
+ return chain;
}
/**
@@ -1278,6 +1257,33 @@
throw new ItemNotFoundException("No valid child entry for NodeEntry " + cne);
}
+ /**
+ * Returns true if the attic contains a matching child entry or if any of
+ * the remaining child entries present in the siblings list has been modified
+ * in a way that its original index is equal to the given child index.
+ *
+ * @param siblings
+ * @param childName
+ * @param childIndex
+ * @return
+ */
+ private boolean containsAtticChild(List siblings, QName childName, int childIndex) {
+ // check if a matching entry exists in the attic
+ if (childNodeAttic.contains(childName, childIndex)) {
+ return true;
+ }
+ // in case of reordered/moved SNSs we also have to look for a child
+ // entry, which hold the given index before
+ if (getStatus() == Status.EXISTING_MODIFIED) {
+ for (Iterator it = siblings.iterator(); it.hasNext();) {
+ NodeEntryImpl child = (NodeEntryImpl) it.next();
+ if (!EntryValidation.isValidNodeEntry(child) || (child.revertInfo != null && child.revertInfo.oldIndex == childIndex)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
/**
* If 'revertInfo' is null it gets created from the current information
* present on this entry.
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/NodeTypeRegistryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/NodeTypeRegistryImpl.java?view=diff&rev=542571&r1=542570&r2=542571
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/NodeTypeRegistryImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/NodeTypeRegistryImpl.java Tue May 29 08:51:30 2007
@@ -20,7 +20,7 @@
import org.apache.jackrabbit.jcr2spi.util.Dumpable;
import org.apache.jackrabbit.jcr2spi.state.NodeState;
import org.apache.jackrabbit.jcr2spi.state.Status;
-import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
+import org.apache.jackrabbit.jcr2spi.state.PropertyState;
import org.apache.jackrabbit.name.QName;
import org.apache.jackrabbit.spi.QNodeDefinition;
import org.apache.jackrabbit.spi.QPropertyDefinition;
@@ -334,18 +334,16 @@
// TODO: check if correct (and only used for creating new)
QName primaryType = nodeState.getNodeTypeName();
allNtNames = new QName[] { primaryType }; // default
- PropertyEntry mixins = nodeState.getNodeEntry().getPropertyEntry(QName.JCR_MIXINTYPES);
- if (mixins != null) {
- try {
- QValue[] values = mixins.getPropertyState().getValues();
- allNtNames = new QName[values.length + 1];
- for (int i = 0; i < values.length; i++) {
- allNtNames[i] = values[i].getQName();
- }
- allNtNames[values.length] = primaryType;
- } catch (RepositoryException e) {
- // ignore
+ try {
+ PropertyState mixins = nodeState.getPropertyState(QName.JCR_MIXINTYPES);
+ QValue[] values = mixins.getValues();
+ allNtNames = new QName[values.length + 1];
+ for (int i = 0; i < values.length; i++) {
+ allNtNames[i] = values[i].getQName();
}
+ allNtNames[values.length] = primaryType;
+ } catch (RepositoryException e) {
+ // ignore: apparently no jcr:mixinTypes property exists.
}
}
return getEffectiveNodeType(allNtNames);
@@ -390,7 +388,7 @@
return ent;
} catch (NodeTypeConflictException ntce) {
// should never get here as all known node types should be valid!
- String msg = "internal error: encountered invalid registered node type " + ntName;
+ String msg = "Internal error: encountered invalid registered node type " + ntName;
log.debug(msg);
throw new NoSuchNodeTypeException(msg, ntce);
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddLabel.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddLabel.java?view=diff&rev=542571&r1=542570&r2=542571
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddLabel.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddLabel.java Tue May 29 08:51:30 2007
@@ -79,7 +79,9 @@
try {
NodeEntry vhEntry = (NodeEntry) versionHistoryState.getHierarchyEntry();
NodeEntry lnEntry = vhEntry.getNodeEntry(QName.JCR_VERSIONLABELS, Path.INDEX_DEFAULT);
- lnEntry.invalidate(moveLabel);
+ if (lnEntry != null) {
+ lnEntry.invalidate(moveLabel);
+ }
} catch (RepositoryException e) {
log.debug(e.getMessage());
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java?view=diff&rev=542571&r1=542570&r2=542571
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java Tue May 29 08:51:30 2007
@@ -166,12 +166,14 @@
throw new ItemExistsException("Move destination already exists (Property).");
} else if (destEntry.hasNodeEntry(destName)) {
NodeEntry existing = destEntry.getNodeEntry(destName, Path.INDEX_DEFAULT);
- try {
- if (!existing.getNodeState().getDefinition().allowsSameNameSiblings()) {
- throw new ItemExistsException("Node existing at move destination does not allow same name siblings.");
+ if (existing != null) {
+ try {
+ if (!existing.getNodeState().getDefinition().allowsSameNameSiblings()) {
+ throw new ItemExistsException("Node existing at move destination does not allow same name siblings.");
+ }
+ } catch (ItemNotFoundException e) {
+ // existing apparent not valid any more -> probably no conflict
}
- } catch (ItemNotFoundException e) {
- // existing apparent not valid any more -> probably no conflict
}
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveLabel.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveLabel.java?view=diff&rev=542571&r1=542570&r2=542571
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveLabel.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveLabel.java Tue May 29 08:51:30 2007
@@ -76,7 +76,9 @@
try {
NodeEntry vhEntry = (NodeEntry) versionHistoryState.getHierarchyEntry();
NodeEntry lnEntry = vhEntry.getNodeEntry(QName.JCR_VERSIONLABELS, Path.INDEX_DEFAULT);
- lnEntry.invalidate(true);
+ if (lnEntry != null) {
+ lnEntry.invalidate(true);
+ }
} catch (RepositoryException e) {
log.debug(e.getMessage());
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/SetMixin.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/SetMixin.java?view=diff&rev=542571&r1=542570&r2=542571
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/SetMixin.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/SetMixin.java Tue May 29 08:51:30 2007
@@ -18,8 +18,6 @@
import org.apache.jackrabbit.name.QName;
import org.apache.jackrabbit.jcr2spi.state.NodeState;
-import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
-import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
import org.apache.jackrabbit.spi.NodeId;
import javax.jcr.RepositoryException;
@@ -46,13 +44,10 @@
addAffectedItemState(nodeState);
// add the jcr:mixinTypes property state as affected if it already exists
// and therefore gets modified by this operation.
- PropertyEntry pe = ((NodeEntry) nodeState.getHierarchyEntry()).getPropertyEntry(QName.JCR_MIXINTYPES);
- if (pe != null) {
- try {
- addAffectedItemState(pe.getPropertyState());
- } catch (RepositoryException e) {
- // should never occur
- }
+ try {
+ addAffectedItemState(nodeState.getPropertyState(QName.JCR_MIXINTYPES));
+ } catch (RepositoryException e) {
+ // jcr:mixinTypes does not exist -> ignore
}
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java?view=diff&rev=542571&r1=542570&r2=542571
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java Tue May 29 08:51:30 2007
@@ -58,6 +58,11 @@
private int status;
/**
+ * The hierarchy entry this state belongs to.
+ */
+ private HierarchyEntry hierarchyEntry;
+
+ /**
* Listeners (weak references)
*/
private final transient Collection listeners = new WeakIdentityCollection(5);
@@ -82,7 +87,8 @@
* @param isWorkspaceState
*/
protected ItemState(int initialStatus, boolean isWorkspaceState,
- ItemStateFactory isf, ItemDefinitionProvider definitionProvider) {
+ HierarchyEntry entry, ItemStateFactory isf,
+ ItemDefinitionProvider definitionProvider) {
switch (initialStatus) {
case Status.EXISTING:
case Status.NEW:
@@ -93,11 +99,15 @@
log.debug(msg);
throw new IllegalArgumentException(msg);
}
- overlayedState = null;
-
+ if (entry == null) {
+ throw new IllegalArgumentException("Cannot build ItemState from 'null' HierarchyEntry");
+ }
+ this.hierarchyEntry = entry;
this.isf = isf;
this.definitionProvider = definitionProvider;
this.isWorkspaceState = isWorkspaceState;
+
+ overlayedState = null;
}
/**
@@ -119,6 +129,10 @@
log.debug(msg);
throw new IllegalArgumentException(msg);
}
+ if (overlayedState.getHierarchyEntry() == null) {
+ throw new IllegalArgumentException("Cannot build ItemState from 'null' HierarchyEntry");
+ }
+ this.hierarchyEntry = overlayedState.getHierarchyEntry();
this.isf = isf;
this.isWorkspaceState = false;
this.definitionProvider = overlayedState.definitionProvider;
@@ -131,7 +145,9 @@
*
* @return The <code>HierarchyEntry</code> corresponding to this <code>ItemState</code>.
*/
- public abstract HierarchyEntry getHierarchyEntry();
+ public HierarchyEntry getHierarchyEntry() {
+ return hierarchyEntry;
+ }
/**
* Returns <code>true</code> if this item state is valid, that is its status
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java?view=diff&rev=542571&r1=542570&r2=542571
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/NodeState.java Tue May 29 08:51:30 2007
@@ -19,11 +19,9 @@
import org.apache.commons.collections.iterators.IteratorChain;
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.jcr2spi.util.StateUtility;
import org.apache.jackrabbit.jcr2spi.nodetype.ItemDefinitionProvider;
import org.apache.jackrabbit.name.QName;
-import org.apache.jackrabbit.name.Path;
import org.apache.jackrabbit.spi.NodeId;
import org.apache.jackrabbit.spi.ItemId;
import org.apache.jackrabbit.spi.QNodeDefinition;
@@ -47,8 +45,6 @@
private static Logger log = LoggerFactory.getLogger(NodeState.class);
- private final NodeEntry hierarchyEntry;
-
/**
* the name of this node's primary type
*/
@@ -75,8 +71,7 @@
QNodeDefinition definition, int initialStatus,
boolean isWorkspaceState,
ItemStateFactory isf, ItemDefinitionProvider definitionProvider) {
- super(initialStatus, isWorkspaceState, isf, definitionProvider);
- this.hierarchyEntry = entry;
+ super(initialStatus, isWorkspaceState, entry, isf, definitionProvider);
this.nodeTypeName = nodeTypeName;
setMixinTypeNames(mixinTypeNames);
this.definition = definition;
@@ -93,7 +88,6 @@
super(overlayedState, initialStatus, isf);
synchronized (overlayedState) {
- hierarchyEntry = overlayedState.hierarchyEntry;
nodeTypeName = overlayedState.nodeTypeName;
definition = overlayedState.definition;
if (mixinTypeNames != null) {
@@ -104,13 +98,6 @@
//----------------------------------------------------------< ItemState >---
/**
- * @see ItemState#getHierarchyEntry()
- */
- public HierarchyEntry getHierarchyEntry() {
- return hierarchyEntry;
- }
-
- /**
* Determines if this item state represents a node.
*
* @return always true
@@ -216,7 +203,7 @@
/**
* TODO improve
- * !! Used by NodeEntryImpl and NodeState only
+ * Used by NodeEntryImpl and NodeState only
*
* @param mixinTypeNames
*/
@@ -283,7 +270,8 @@
/**
* Utility
* Returns the child <code>NodeState</code> with the specified name
- * and index or <code>null</code> if there's no matching, valid entry.
+ * and index. Throws <code>ItemNotFoundException</code> if there's no
+ * matching, valid entry.
*
* @param nodeName <code>QName</code> object specifying a node name.
* @param index 1-based index if there are same-name child node entries.
@@ -292,11 +280,11 @@
* @throws RepositoryException
*/
public NodeState getChildNodeState(QName nodeName, int index) throws ItemNotFoundException, RepositoryException {
- NodeEntry child = getNodeEntry().getNodeEntry(nodeName, index);
- if (child != null) {
- return child.getNodeState();
+ NodeEntry ne = getNodeEntry().getNodeEntry(nodeName, index, true);
+ if (ne != null) {
+ return ne.getNodeState();
} else {
- // TODO: correct?
+ // does not exist (any more) or is a property
throw new ItemNotFoundException("Child node "+ nodeName +" with index " + index + " does not exist.");
}
}
@@ -313,7 +301,9 @@
}
/**
- * Utility method that returns the property state with the given name.
+ * Utility method that returns the property state with the given name or
+ * throws an <code>ItemNotFoundException</code> if no matching, valid
+ * property could be found.
*
* @param propertyName The name of the property state to return.
* @throws ItemNotFoundException If there is no (valid) property state
@@ -321,13 +311,13 @@
* @throws RepositoryException If an error occurs while retrieving the
* property state.
*
- * @see NodeEntry#getPropertyEntry(QName)
+ * @see NodeEntry#getPropertyEntry(QName, boolean)
* @see PropertyEntry#getPropertyState()
*/
public PropertyState getPropertyState(QName propertyName) throws ItemNotFoundException, RepositoryException {
- HierarchyEntry child = getNodeEntry().getDeepEntry(Path.create(propertyName, Path.INDEX_UNDEFINED));
- if (child != null && !child.denotesNode()) {
- return ((PropertyEntry) child).getPropertyState();
+ PropertyEntry pe = getNodeEntry().getPropertyEntry(propertyName, true);
+ if (pe != null) {
+ return pe.getPropertyState();
} else {
throw new ItemNotFoundException("Child Property with name " + propertyName + " does not exist.");
}
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java?view=diff&rev=542571&r1=542570&r2=542571
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/PropertyState.java Tue May 29 08:51:30 2007
@@ -28,7 +28,6 @@
import org.apache.jackrabbit.jcr2spi.nodetype.ValueConstraint;
import org.apache.jackrabbit.jcr2spi.nodetype.ItemDefinitionProvider;
import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
-import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,11 +41,6 @@
private static Logger log = LoggerFactory.getLogger(PropertyState.class);
/**
- * The PropertyEntry associated with the state
- */
- private final PropertyEntry hierarchyEntry;
-
- /**
* Property definition
*/
private QPropertyDefinition definition;
@@ -77,7 +71,6 @@
ItemStateFactory isf) {
super(overlayedState, initialStatus, isf);
- this.hierarchyEntry = overlayedState.hierarchyEntry;
this.definition = overlayedState.definition;
this.multiValued = overlayedState.multiValued;
@@ -94,9 +87,8 @@
protected PropertyState(PropertyEntry entry, boolean multiValued, QPropertyDefinition definition,
int initialStatus, boolean isWorkspaceState,
ItemStateFactory isf, ItemDefinitionProvider definitionProvider) {
- super(initialStatus, isWorkspaceState, isf, definitionProvider);
+ super(initialStatus, isWorkspaceState, entry, isf, definitionProvider);
- this.hierarchyEntry = entry;
this.definition = definition;
this.multiValued = multiValued;
init(PropertyType.UNDEFINED, QValue.EMPTY_ARRAY);
@@ -126,13 +118,6 @@
//----------------------------------------------------------< ItemState >---
- /**
- * @see ItemState#getHierarchyEntry()
- */
- public HierarchyEntry getHierarchyEntry() {
- return hierarchyEntry;
- }
-
/**
* Always returns false.
*
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=542571&r1=542570&r2=542571
==============================================================================
--- 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 May 29 08:51:30 2007
@@ -165,11 +165,9 @@
}
// create PropertyEntry for the last element if not existing yet
QName propName = missingElems[i].getName();
- PropertyEntry propEntry;
- if (!entry.hasPropertyEntry(propName)) {
+ PropertyEntry propEntry = entry.getPropertyEntry(propName);
+ if (propEntry == null) {
propEntry = entry.addPropertyEntry(propName);
- } else {
- propEntry = entry.getPropertyEntry(propName);
}
return createPropertyState(info, propEntry);
} catch (PathNotFoundException e) {
@@ -309,7 +307,7 @@
* @throws ItemNotFoundException
* @throws RepositoryException
*/
- private void assertMatchingPath(ItemInfo info, HierarchyEntry entry)
+ private static void assertMatchingPath(ItemInfo info, HierarchyEntry entry)
throws ItemNotFoundException, RepositoryException {
if (!info.getPath().equals(entry.getWorkspacePath())) {
throw new ItemNotFoundException("HierarchyEntry does not belong the given ItemInfo.");
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionHistoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionHistoryImpl.java?view=diff&rev=542571&r1=542570&r2=542571
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionHistoryImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionHistoryImpl.java Tue May 29 08:51:30 2007
@@ -64,11 +64,12 @@
super(itemMgr, session, state, listeners);
this.vhEntry = (NodeEntry) state.getHierarchyEntry();
- // retrieve nodestate of the jcr:versionLabels node
- if (vhEntry.hasNodeEntry(QName.JCR_VERSIONLABELS)) {
- labelNodeEntry = vhEntry.getNodeEntry(QName.JCR_VERSIONLABELS, Path.INDEX_DEFAULT);
- } else {
- throw new VersionException("nt:versionHistory requires a mandatory, autocreated child node jcr:versionLabels.");
+ // retrieve hierarchy entry of the jcr:versionLabels node
+ labelNodeEntry = vhEntry.getNodeEntry(QName.JCR_VERSIONLABELS, Path.INDEX_DEFAULT, true);
+ if (labelNodeEntry == null) {
+ String msg = "Unexpected error: nt:versionHistory requires a mandatory, autocreated child node jcr:versionLabels.";
+ log.error(msg);
+ throw new VersionException(msg);
}
}
@@ -92,14 +93,13 @@
*/
public Version getRootVersion() throws RepositoryException {
checkStatus();
- if (vhEntry.hasNodeEntry(QName.JCR_ROOTVERSION)) {
- NodeEntry vEntry = vhEntry.getNodeEntry(QName.JCR_ROOTVERSION, Path.INDEX_DEFAULT);
- return (Version) itemMgr.getItem(vEntry);
- } else {
+ NodeEntry vEntry = vhEntry.getNodeEntry(QName.JCR_ROOTVERSION, Path.INDEX_DEFAULT, true);
+ if (vEntry == null) {
String msg = "Unexpected error: VersionHistory state does not contain a root version child node entry.";
log.error(msg);
throw new RepositoryException(msg);
}
+ return (Version) itemMgr.getItem(vEntry);
}
/**
@@ -146,8 +146,7 @@
*/
public Version getVersionByLabel(String label) throws RepositoryException {
checkStatus();
- NodeState vState = getVersionStateByLabel(getQLabel(label));
- return (Version) itemMgr.getItem(vState.getHierarchyEntry());
+ return getVersionByLabel(getQLabel(label));
}
/**
@@ -177,7 +176,8 @@
public void removeVersionLabel(String label) throws VersionException, RepositoryException {
checkStatus();
QName qLabel = getQLabel(label);
- NodeState vState = getVersionStateByLabel(getQLabel(label));
+ Version version = getVersionByLabel(qLabel);
+ NodeState vState = getVersionState(version.getName());
// delegate to version manager that operates on workspace directely
session.getVersionManager().removeVersionLabel((NodeState) getItemState(), vState, qLabel);
}
@@ -218,7 +218,7 @@
QName[] qLabels = getQLabels();
for (int i = 0; i < qLabels.length; i++) {
if (qLabels[i].equals(l)) {
- String uuid = getVersionStateByLabel(qLabels[i]).getUniqueID();
+ String uuid = getVersionByLabel(qLabels[i]).getUUID();
return vUUID.equals(uuid);
}
}
@@ -263,7 +263,7 @@
List vlabels = new ArrayList();
QName[] qLabels = getQLabels();
for (int i = 0; i < qLabels.length; i++) {
- String uuid = getVersionStateByLabel(qLabels[i]).getUniqueID();
+ String uuid = getVersionByLabel(qLabels[i]).getUUID();
if (vUUID.equals(uuid)) {
try {
vlabels.add(NameFormat.format(qLabels[i], session.getNamespaceResolver()));
@@ -364,7 +364,7 @@
try {
QName vQName = NameFormat.parse(versionName, session.getNamespaceResolver());
refreshEntry(vhEntry);
- NodeEntry vEntry = vhEntry.getNodeEntry(vQName, Path.INDEX_DEFAULT);
+ NodeEntry vEntry = vhEntry.getNodeEntry(vQName, Path.INDEX_DEFAULT, true);
if (vEntry == null) {
throw new VersionException("Version '" + versionName + "' does not exist in this version history.");
} else {
@@ -376,22 +376,21 @@
}
/**
- *
+ *
* @param qLabel
* @return
* @throws VersionException
* @throws RepositoryException
*/
- private NodeState getVersionStateByLabel(QName qLabel) throws VersionException, RepositoryException {
- refreshEntry(labelNodeEntry);
- if (labelNodeEntry.hasPropertyEntry(qLabel)) {
- // retrieve reference property value -> and retrieve referenced node
- PropertyEntry pEntry = labelNodeEntry.getPropertyEntry(qLabel);
- Node version = ((Property) itemMgr.getItem(pEntry)).getNode();
- return getVersionState(version.getName());
- } else {
+ private Version getVersionByLabel(QName qLabel) throws VersionException, RepositoryException {
+ refreshEntry(labelNodeEntry);
+ // retrieve reference property value -> and retrieve referenced node
+ PropertyEntry pEntry = labelNodeEntry.getPropertyEntry(qLabel, true);
+ if (pEntry == null) {
throw new VersionException("Version with label '" + qLabel + "' does not exist.");
}
+ Node version = ((Property) itemMgr.getItem(pEntry)).getNode();
+ return (Version) version;
}
/**
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManagerImpl.java?view=diff&rev=542571&r1=542570&r2=542571
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManagerImpl.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionManagerImpl.java Tue May 29 08:51:30 2007
@@ -86,7 +86,7 @@
try {
// NOTE: since the hierarchy might not be completely loaded or some
// entry might even not be accessible, the check may not detect
- // a checked-in parent. ok, as long as the 'server' find out upon
+ // a checked-in parent. ok, as long as the 'server' finds out upon
// save or upon executing the workspace operation.
while (!nodeEntry.hasPropertyEntry(QName.JCR_ISCHECKEDOUT)) {
NodeEntry parent = nodeEntry.getParent();
Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/SessionImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/SessionImporter.java?view=diff&rev=542571&r1=542570&r2=542571
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/SessionImporter.java (original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/xml/SessionImporter.java Tue May 29 08:51:30 2007
@@ -475,6 +475,7 @@
}
// and set mixin types
+ // TODO: missing validation
Operation sm = SetMixin.create(childState, nodeInfo.getMixinNames());
stateMgr.execute(sm);
return childState;