jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r467956 [3/3] - in /jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi: ./ state/ version/
Date Thu, 26 Oct 2006 11:02:04 GMT
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=467956&r1=467955&r2=467956
==============================================================================
--- 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
Thu Oct 26 04:02:02 2006
@@ -59,6 +59,8 @@
     private final SessionInfo sessionInfo;
     private final WorkspaceManager wspManager;
 
+    private ItemStateCache cache;
+
     public WorkspaceItemStateFactory(RepositoryService service, SessionInfo sessionInfo,
WorkspaceManager wspManager) {
         this.service = service;
         this.sessionInfo = sessionInfo;
@@ -93,7 +95,11 @@
             NodeId parentId = (info.getParentId() != null) ? info.getParentId() : null;
             NodeState parent = (parentId != null) ? (NodeState) ism.getItemState(parentId)
: null;
 
-            return createNodeState(info, parent);
+            if (parent != null) {
+                return parent.getChildNodeEntry(info.getQName(), info.getIndex()).getNodeState();
+            } else {
+                return createNodeState(info, parent);
+            }
         } catch (ItemNotFoundException e) {
             throw new NoSuchItemStateException(e.getMessage(), e);
         } catch (RepositoryException e) {
@@ -157,7 +163,7 @@
                 if (childInfo.getId().getPath() == null) {
                     childUUID = childInfo.getId().getUUID();
                 }
-                childNodeEntries.add(new CNE(childInfo.getQName(), childUUID));
+                childNodeEntries.add(new CNE(childInfo.getQName(), childInfo.getIndex(),
childUUID));
             }
 
             // names of child property entries
@@ -167,29 +173,24 @@
                 propNames.add(pId.getQName());
             }
 
-            // If the uuid is not null, the state could include mix:referenceable.
-            // Therefore build a NodeReference instance and add it to the state.
-            NodeReferences nodeRefs = null;
-            if (uuid != null) {
-                PropertyId[] references = info.getReferences();
-                nodeRefs = new NodeReferencesImpl(info.getId(), references);
-            }
+            // Build node-references object even if the state is not refereceable yet.
+            PropertyId[] references = info.getReferences();
+            NodeReferences nodeRefs = new NodeReferencesImpl(state, references);
 
             state.init(info.getMixins(), childNodeEntries, propNames, nodeRefs);
 
-            // copied from local-state-mgr TODO... check
-            // register as listener
-            // TODO check if needed
-            //state.addListener(this);
+            state.addListener(cache);
+            cache.created(state);
+
             return state;
         } catch (PathNotFoundException e) {
             throw new NoSuchItemStateException(e.getMessage(), e);
         } catch (NodeTypeConflictException e) {
-            String msg = "internal error: failed to retrieve node definition.";
+            String msg = "Internal error: failed to retrieve node definition.";
             log.debug(msg);
             throw new ItemStateException(msg, e);
         } catch (ConstraintViolationException e) {
-            String msg = "internal error: failed to retrieve node definition.";
+            String msg = "Internal error: failed to retrieve node definition.";
             log.debug(msg);
             throw new ItemStateException(msg, e);
         } catch (NoSuchNodeTypeException e) {
@@ -231,9 +232,8 @@
      * @throws ItemStateException if an error occurs while retrieving the
      *                            <code>PropertyState</code>.
      */
-    private PropertyState createPropertyState(PropertyInfo info,
-                                              NodeState parent)
-            throws ItemStateException {
+    private PropertyState createPropertyState(PropertyInfo info, NodeState parent)
+        throws ItemStateException {
         try {
 
             // retrieve property definition
@@ -242,7 +242,7 @@
 
             // build the PropertyState
             PropertyState state = new PropertyState(info.getQName(), parent,
-                def, Status.EXISTING, service.getIdFactory(), true);
+                def, Status.EXISTING, this, service.getIdFactory(), true);
 
             QValue[] qValues;
             if (info.getType() == PropertyType.BINARY) {
@@ -260,37 +260,42 @@
             }
 
             state.init(info.getType(), qValues);
+            state.addListener(cache);
+            cache.created(state);
 
-            // register as listener
-            // TODO check if needed
-            // state.addListener(this);
             return state;
         } catch (IOException e) {
             throw new ItemStateException(e.getMessage(), e);
         } catch (NodeTypeConflictException e) {
-            String msg = "internal error: failed to retrieve property definition.";
-            log.debug(msg);
-            throw new ItemStateException(msg, e);
-        } catch (ConstraintViolationException e) {
-            String msg = "internal error: failed to retrieve property definition.";
+            String msg = "internal error: failed to build property state.";
             log.debug(msg);
             throw new ItemStateException(msg, e);
-        } catch (NoSuchNodeTypeException e) {
-            String msg = "internal error: failed to retrieve property definition.";
+        } catch (RepositoryException e) {
+            String msg = "internal error: failed to build property state.";
             log.debug(msg);
             throw new ItemStateException(msg, e);
         }
     }
 
+    /**
+     *
+     * @param cache
+     * @see ItemStateFactory#setCache(ItemStateCache)
+     */
+    public void setCache(ItemStateCache cache) {
+        this.cache = cache;
+    }
 
     //------------------------------------------------------< ChildNodeEntry >---
     private class CNE implements ChildNodeEntry {
 
         private final QName name;
+        private final int index;
         private final String uuid;
 
-        private CNE(QName name, String uuid) {
+        private CNE(QName name, int index, String uuid) {
             this.name = name;
+            this.index = index;
             this.uuid = uuid;
         }
 
@@ -307,7 +312,7 @@
         }
 
         public int getIndex() {
-            throw new UnsupportedOperationException();
+            return index;
         }
 
         public NodeState getNodeState() throws NoSuchItemStateException, ItemStateException
{
@@ -325,21 +330,16 @@
      */
     private class NodeReferencesImpl implements NodeReferences {
 
-        /**
-         * Identifier of this <code>NodeReferences</code> instance. Since the
-         * id of target state consists of a UUID and contains not relative
-         * path, the id will be stable and can be stored.
-         */
-        private NodeId nodeId;
+        private NodeState nodeState;
 
         /**
          * Private constructor
          *
-         * @param nodeId
+         * @param nodeState
          * @param referenceIds
          */
-        private NodeReferencesImpl(NodeId nodeId, PropertyId[] referenceIds) {
-            this.nodeId = nodeId;
+        private NodeReferencesImpl(NodeState nodeState, PropertyId[] referenceIds) {
+            this.nodeState = nodeState;
 
             // TODO: modify in order to make usage of the references returned
             // with NodeInfo that was just retrieved and implement a notification
@@ -352,8 +352,14 @@
          * @see NodeReferences#isEmpty()
          */
         public boolean isEmpty() {
+            // shortcut
+            if (nodeState.getUUID() == null) {
+                return true;
+            }
+            // nodestate has a uuid and is potentially mix:referenceable
+            // => try to retrieve references
             try {
-                NodeInfo info = service.getNodeInfo(sessionInfo, nodeId);
+                NodeInfo info = service.getNodeInfo(sessionInfo, nodeState.getNodeId());
                 return info.getReferences().length > 0;
             } catch (RepositoryException e) {
                 log.error("Internal error.",e);
@@ -365,8 +371,14 @@
          * @see NodeReferences#iterator()
          */
         public Iterator iterator() {
+            // shortcut
+            if (nodeState.getUUID() == null) {
+                return Collections.EMPTY_SET.iterator();
+            }
+            // nodestate has a uuid and is potentially mix:referenceable
+            // => try to retrieve references
             try {
-                NodeInfo info = service.getNodeInfo(sessionInfo, nodeId);
+                NodeInfo info = service.getNodeInfo(sessionInfo, nodeState.getNodeId());
                 if (info.getReferences().length > 0) {
                     Set referenceIds = new HashSet();
                     referenceIds.addAll(Arrays.asList(info.getReferences()));
@@ -375,7 +387,7 @@
                     return Collections.EMPTY_SET.iterator();
                 }
             } catch (RepositoryException e) {
-                log.error("Internal error.",e);
+                log.error("Internal error.", e);
                 return Collections.EMPTY_SET.iterator();
             }
         }

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateManager.java?view=diff&rev=467956&r1=467955&r2=467956
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateManager.java
(original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateManager.java
Thu Oct 26 04:02:02 2006
@@ -18,17 +18,17 @@
 
 import org.apache.jackrabbit.jcr2spi.observation.InternalEventListener;
 import org.apache.jackrabbit.spi.EventIterator;
-import org.apache.jackrabbit.spi.Event;
 import org.apache.jackrabbit.spi.IdFactory;
-import org.apache.jackrabbit.spi.PropertyId;
+import org.apache.jackrabbit.spi.Event;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.Set;
 import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Collection;
 import java.util.List;
 import java.util.ArrayList;
-import java.util.Iterator;
 
 /**
  * <code>WorkspaceItemStateManager</code>
@@ -54,47 +54,83 @@
      * @param isLocal
      */
     public void onEvent(EventIterator events, boolean isLocal) {
-        onEvent(events, isLocal, null);
+        pushEvents(getEventCollection(events));
     }
 
+    /**
+     *
+     * @param events
+     * @param changeLog
+     */
     public void onEvent(EventIterator events, ChangeLog changeLog) {
         if (changeLog == null) {
             throw new IllegalArgumentException("ChangeLog must not be null.");
         }
-        // inform all transient states, that they have been persisted and must
-        // connect to their workspace state (and eventually reload the data).
-        // TODO: TOBEFIXED. only used to set status to EXISTING in order (which is probably
wrong)
-        changeLog.persisted();
-
-        // inform all existing workspace states about the transient modifications
-        // that have been persisted now.
-        onEvent(events, true, changeLog);
+        Collection evs = getEventCollection(events);
+        // TODO: make sure, that events only contain events related to the modifications
submitted with the changelog.
+
+        // inform the changelog target state about the transient modifications
+        // that have been persisted now: NEW-states will be connected to their
+        // overlayed state, EXISTING_REMOVED states will be definitely removed,
+        // EXISTING_MODIFIED states are merged with their workspace-state.
+        changeLog.getTarget().refresh(evs, changeLog);
+        // all events not covered by the changelog must not be handled on the
+        // session-states -> treat the same way as events returned by
+        // workspace operations.
+        pushEvents(evs);
     }
 
-    private void onEvent(EventIterator events, boolean isLocal, ChangeLog changeLog) {
+    private void pushEvents(Collection events) {
+        if (events.isEmpty()) {
+            return;
+        }
         // collect set of removed node ids
-        Set removedNodeIds = new HashSet();
-        List addEventList = new ArrayList();
-        List eventList = new ArrayList();
-        while (events.hasNext()) {
-            Event event = events.nextEvent();
+        Set removedEvents = new HashSet();
+        // separately collect the add events
+        Set addEvents = new HashSet();
+
+        for (Iterator it = events.iterator(); it.hasNext();) {
+            Event event = (Event) it.next();
             int type = event.getType();
-            if (type == Event.NODE_ADDED || event.getType() == Event.PROPERTY_ADDED) {
-                addEventList.add(event);
-            } else if (type == Event.NODE_REMOVED) {
+            if (type == Event.NODE_REMOVED) {
                 // remember removed nodes separately for proper handling later on.
-                removedNodeIds.add(event.getItemId());
-                eventList.add(event);
-            } else {
-                eventList.add(event);
+                removedEvents.add(event.getItemId());
+            } else if (type == Event.NODE_ADDED || type == Event.PROPERTY_ADDED) {
+                addEvents.add(event);
+                it.remove();
             }
         }
-        if (eventList.isEmpty() && addEventList.isEmpty()) {
-            return;
+
+        /* Process ADD-events.
+           In case of persisting transients modifications, the event-set may
+           still contain events that are not covered by the changeLog such as
+           new version-history or other autocreated properties and nodes.
+
+           Add events need to be processed hierarchically, since its not possible
+           to add a new child reference to a state that is not yet present in
+           the state manager.
+           The 'progress' flag is used to make sure, that during each loop at
+           least one event has been processed and removed from the iterator.
+           If this is not the case, there are not parent states present in the
+           state manager that need to be updated and the remaining events may
+           be ignored.
+         */
+        boolean progress = true;
+        while (!addEvents.isEmpty() && progress) {
+            progress = false;
+            for (Iterator it = addEvents.iterator(); it.hasNext();) {
+                Event ev = (Event) it.next();
+                NodeState parent = (ev.getParentId() != null) ? (NodeState) lookup(ev.getParentId())
: null;
+                if (parent != null) {
+                    parent.refresh(ev);
+                    it.remove();
+                    progress = true;
+                }
+            }
         }
 
-        /* process remove and change events */
-        for (Iterator it = eventList.iterator(); it.hasNext(); ) {
+        /* process all other events (removal, property changed) */
+        for (Iterator it = events.iterator(); it.hasNext(); ) {
             Event event = (Event) it.next();
             int type = event.getType();
 
@@ -103,62 +139,35 @@
 
             if (type == Event.NODE_REMOVED || type == Event.PROPERTY_REMOVED) {
                 if (state != null) {
-                    state.refresh(event, changeLog);
+                    state.refresh(event);
                 }
                 if (parent != null) {
                     // invalidate parent only if it has not been removed
                     // with the same event bundle.
-                    if (!removedNodeIds.contains(event.getParentId())) {
-                        parent.refresh(event, changeLog);
+                    if (!removedEvents.contains(event.getParentId())) {
+                        parent.refresh(event);
                     }
                 }
             } else if (type == Event.PROPERTY_CHANGED) {
                 if (state != null) {
-                    try {
-                        // TODO: improve.
-                        /* retrieve property value and type from server even if
-                           changes were issued from this session (changelog).
-                           this is currently the only way to update the workspace
-                           state, which is not connected to its overlaying session-state.
-                        */
-                        PropertyState tmp = getItemStateFactory().createPropertyState((PropertyId)
state.getId(), state.getParent());
-                        ((PropertyState) state).init(tmp.getType(), tmp.getValues());
-                        state.refresh(event, changeLog);
-                    } catch (ItemStateException e) {
-                        log.error("Unexpected error while updating modified property state.",
e);
-                    }
+                    state.refresh(event);
                 }
                 // TODO: check again. parent must be notified if mixintypes or jcr:uuid prop
is changed.
                 if (parent != null) {
-                    parent.refresh(event, changeLog);
+                    parent.refresh(event);
                 }
             } else {
                 // should never occur
                 throw new IllegalArgumentException("Invalid event type: " + event.getType());
             }
         }
+    }
 
-        /* Add events need to be processed hierarchically, since its not possible
-           to add a new child reference to a state that is not yet present in
-           the state manager.
-           The 'progress' flag is used to make sure, that during each loop at
-           least one event has been processed and removed from the iterator.
-           If this is not the case, there are not parent states present in the
-           state manager that need to be updated and the remaining events may
-           be ignored.
-         */
-        boolean progress = true;
-        while (!addEventList.isEmpty() && progress) {
-            progress = false;
-            for (Iterator it = addEventList.iterator(); it.hasNext();) {
-                Event event = (Event) it.next();
-                NodeState parent = (NodeState) lookup(event.getParentId());
-                if (parent != null) {
-                    parent.refresh(event, changeLog);
-                    it.remove();
-                    progress = true;
-                }
-            }
+    private static Collection getEventCollection(EventIterator events) {
+        List evs = new ArrayList();
+        while (events.hasNext()) {
+           evs.add(events.nextEvent());
         }
+        return evs;
     }
 }

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=467956&r1=467955&r2=467956
==============================================================================
--- 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
Thu Oct 26 04:02:02 2006
@@ -45,6 +45,7 @@
 import javax.jcr.Node;
 import javax.jcr.Property;
 import javax.jcr.nodetype.NodeDefinition;
+import javax.jcr.nodetype.ConstraintViolationException;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ArrayList;
@@ -311,6 +312,18 @@
             return vhState.getUUID().equals(other.vhState.getUUID());
         }
         return false;
+    }
+
+    //-----------------------------------------------------------< ItemImpl >---
+    /**
+     *
+     * @throws UnsupportedRepositoryOperationException
+     * @throws ConstraintViolationException
+     * @throws RepositoryException
+     */
+    protected void checkIsWritable() throws UnsupportedRepositoryOperationException, ConstraintViolationException,
RepositoryException {
+        super.checkIsWritable();
+        throw new ConstraintViolationException("VersionHistory is protected");
     }
 
     //------------------------------------------------------------< private >---

Modified: jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionImpl.java?view=diff&rev=467956&r1=467955&r2=467956
==============================================================================
--- jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionImpl.java
(original)
+++ jackrabbit/trunk/contrib/spi/jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionImpl.java
Thu Oct 26 04:02:02 2006
@@ -31,7 +31,9 @@
 import javax.jcr.Value;
 import javax.jcr.Node;
 import javax.jcr.Item;
+import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.jcr.nodetype.NodeDefinition;
+import javax.jcr.nodetype.ConstraintViolationException;
 import java.util.Calendar;
 
 /**
@@ -108,6 +110,19 @@
         }
         return false;
     }
+
+    //-----------------------------------------------------------< ItemImpl >---
+    /**
+     *
+     * @throws UnsupportedRepositoryOperationException
+     * @throws ConstraintViolationException
+     * @throws RepositoryException
+     */
+    protected void checkIsWritable() throws UnsupportedRepositoryOperationException, ConstraintViolationException,
RepositoryException {
+        super.checkIsWritable();
+        throw new ConstraintViolationException("Version is protected");
+    }
+
     //------------------------------------------------------------< private >---
     /**
      *



Mime
View raw message