You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by md...@apache.org on 2011/06/17 19:33:39 UTC

svn commit: r1136956 - in /jackrabbit/sandbox/spi2microkernel/src: main/java/org/apache/jackrabbit/spi2microkernel/ test/java/org/apache/jackrabbit/spi2microkernel/

Author: mduerig
Date: Fri Jun 17 17:33:38 2011
New Revision: 1136956

URL: http://svn.apache.org/viewvc?rev=1136956&view=rev
Log:
spi2microkernel prototype (WIP)
observation: started implementation (WIP)

Added:
    jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SubscriptionImpl.java
Modified:
    jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/RepositoryServiceImpl.java
    jackrabbit/sandbox/spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/RepositoryTest.java

Modified: jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/RepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/RepositoryServiceImpl.java?rev=1136956&r1=1136955&r2=1136956&view=diff
==============================================================================
--- jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/RepositoryServiceImpl.java (original)
+++ jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/RepositoryServiceImpl.java Fri Jun 17 17:33:38 2011
@@ -24,6 +24,8 @@ import org.apache.jackrabbit.mk.json.Jso
 import org.apache.jackrabbit.mk.util.PathUtils;
 import org.apache.jackrabbit.spi.Batch;
 import org.apache.jackrabbit.spi.ChildInfo;
+import org.apache.jackrabbit.spi.EventBundle;
+import org.apache.jackrabbit.spi.EventFilter;
 import org.apache.jackrabbit.spi.ItemId;
 import org.apache.jackrabbit.spi.ItemInfo;
 import org.apache.jackrabbit.spi.ItemInfoCache;
@@ -37,7 +39,9 @@ import org.apache.jackrabbit.spi.QNodeDe
 import org.apache.jackrabbit.spi.QNodeTypeDefinition;
 import org.apache.jackrabbit.spi.QValue;
 import org.apache.jackrabbit.spi.SessionInfo;
+import org.apache.jackrabbit.spi.Subscription;
 import org.apache.jackrabbit.spi.commons.AbstractRepositoryService;
+import org.apache.jackrabbit.spi.commons.EventFilterImpl;
 import org.apache.jackrabbit.spi.commons.ItemInfoCacheImpl;
 import org.apache.jackrabbit.spi.commons.batch.ConsolidatingChangeLog;
 import org.apache.jackrabbit.spi2microkernel.util.JsonHandlerBase;
@@ -56,9 +60,11 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.Callable;
 
 import static javax.jcr.Repository.*;
@@ -73,6 +79,7 @@ public class RepositoryServiceImpl exten
 
         put(NODE_TYPE_MANAGEMENT_SAME_NAME_SIBLINGS_SUPPORTED, FALSE);
         put(OPTION_WORKSPACE_MANAGEMENT_SUPPORTED, TRUE);
+        put(OPTION_OBSERVATION_SUPPORTED, TRUE);
         put(LEVEL_2_SUPPORTED, TRUE);
     }};
 
@@ -329,8 +336,49 @@ public class RepositoryServiceImpl exten
         namespaces.removeMapping(uri);
     }
 
+    //------------------------------------------< Observation >---
+
+    @Override
+    public EventFilter createEventFilter(SessionInfo sessionInfo, int eventTypes, Path absPath, boolean isDeep,
+             String[] uuid, Name[] nodeTypeName, boolean noLocal) throws RepositoryException {
+
+        Set<Name> ntNames = new HashSet<Name>();
+        if (nodeTypeName != null) {
+            Collections.addAll(ntNames, nodeTypeName);
+        }
+        return new EventFilterImpl(eventTypes, absPath, isDeep, uuid, ntNames, noLocal);
+    }
+
+    @Override
+    public Subscription createSubscription(SessionInfo sessionInfo, EventFilter[] filters) throws RepositoryException {
+        SubscriptionImpl subscription = new SubscriptionImpl(microKernel, sessionState(sessionInfo));
+        subscription.setEventFilters(filters);
+        return subscription;    
+    }
+
+    @Override
+    public void updateEventFilters(Subscription subscription, EventFilter[] filters) throws RepositoryException {
+        subscription(subscription).setEventFilters(filters);
+    }
+
+    @Override
+    public EventBundle[] getEvents(Subscription subscription, long timeout)
+            throws RepositoryException, InterruptedException {
+        
+        return subscription(subscription).getEvents(timeout);
+    }
+
     //------------------------------------------< private >---
 
+    private static SubscriptionImpl subscription(Subscription subscription) throws RepositoryException {
+        if (subscription instanceof SubscriptionImpl) {
+            return (SubscriptionImpl) subscription;
+        }
+        else {
+            throw new RepositoryException("Invalid subscription " + subscription);
+        }
+    }
+    
     private static ChangeLog changeLog(Batch batch) throws RepositoryException {
         if (batch instanceof ChangeLog) {
             return (ChangeLog) batch;

Added: jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SubscriptionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SubscriptionImpl.java?rev=1136956&view=auto
==============================================================================
--- jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SubscriptionImpl.java (added)
+++ jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SubscriptionImpl.java Fri Jun 17 17:33:38 2011
@@ -0,0 +1,150 @@
+/*
+ * 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.spi2microkernel;
+
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.spi.EventBundle;
+import org.apache.jackrabbit.spi.EventFilter;
+import org.apache.jackrabbit.spi.Subscription;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+
+import javax.jcr.RepositoryException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+public class SubscriptionImpl implements Subscription {
+    private final MicroKernel microKernel;
+    private final SessionState sessionState;
+    private final List<EventSource> eventSources = new LinkedList<EventSource>();
+
+    public SubscriptionImpl(MicroKernel microKernel, SessionState sessionState) {
+        this.microKernel = microKernel;
+        this.sessionState = sessionState;
+    }
+
+    public void setEventFilters(EventFilter[] eventFilters) throws RepositoryException {
+        synchronized (eventSources) {
+            SessionState frozen = sessionState.freeze();
+            if (!eventSources.isEmpty()) {
+                eventSources.get(eventSources.size() - 1).setLastRevision(frozen.getHeadRevision());
+            }
+            eventSources.add(new EventSource(eventFilters, frozen));
+        }
+    }
+
+    public EventBundle[] getEvents(long timeout) throws RepositoryException, InterruptedException {
+        Thread.sleep(timeout);
+
+        List<EventBundle> eventBundles = new ArrayList<EventBundle>();
+        synchronized (eventSources) {
+            for (Iterator<EventSource> it = eventSources.iterator(); it.hasNext(); ) {
+                EventSource eventSource = it.next();
+                eventBundles.addAll(eventSource.getEventsBundles());
+                if (eventSource.isEmpty()) {
+                    it.remove();
+                }
+            }
+        }
+
+        return eventBundles.toArray(new EventBundle[eventBundles.size()]);
+    }
+
+    //------------------------------------------< private >---
+
+    private static JSONArray jsonArray(Object jsonArray) {
+        if (jsonArray instanceof JSONArray) {
+            return (JSONArray) jsonArray;
+        }
+        else {
+            throw new IllegalArgumentException("Not a JSONArray: " + jsonArray);
+        }
+    }
+
+    private static JSONObject jsonObject(Object jsonObject) {
+        if (jsonObject instanceof JSONObject) {
+            return (JSONObject) jsonObject;
+        }
+        else {
+            throw new IllegalArgumentException("Not a JSONObject: " + jsonObject);
+        }
+    }
+
+    private class EventSource {
+        private final EventFilter[] eventFilters;
+        private final SessionState sessionState;
+
+        private String startRevision;
+        private String lastRevision;
+        private boolean isEmpty;
+
+        public EventSource(EventFilter[] eventFilters, SessionState sessionState) {
+            this.eventFilters = eventFilters;
+            this.sessionState = sessionState;
+            startRevision = sessionState.getHeadRevision();
+        }
+
+        /**
+         * Set the last revision from which events should be included
+         * @param lastRevision
+         */
+        public void setLastRevision(String lastRevision) {
+            this.lastRevision = lastRevision;
+        }
+
+        public Collection<? extends EventBundle> getEventsBundles() throws RepositoryException {
+            String endRevision = lastRevision == null
+                ? microKernel.getHeadRevision()
+                : lastRevision;
+
+            String journal = microKernel.getJournal(startRevision, endRevision);
+
+            try {
+                List<?> jsonArray = jsonArray(new JSONParser().parse(journal));
+                EventBundle[] eventBundles = new EventBundle[jsonArray.size()];
+                Iterator<?> jsonObjects = jsonArray.iterator();
+                for (int k = 0; k < eventBundles.length; k++) {
+                    JSONObject jsonObject = jsonObject(jsonObjects.next());
+                    // todo:
+//                    eventBundles[k] = new EventBundleImpl(jsonObject, eventFilters, sessionState);
+                }
+
+                startRevision = endRevision;
+                isEmpty = lastRevision != null;
+
+                return Collections.emptyList(); // todo implement getEventsBundles
+            }
+            catch (ParseException e) {
+                throw new RepositoryException(e.getMessage(), e);
+            }
+
+        }
+
+        public boolean isEmpty() {
+            return isEmpty;    
+        }
+    }
+}

Modified: jackrabbit/sandbox/spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/RepositoryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/RepositoryTest.java?rev=1136956&r1=1136955&r2=1136956&view=diff
==============================================================================
--- jackrabbit/sandbox/spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/RepositoryTest.java (original)
+++ jackrabbit/sandbox/spi2microkernel/src/test/java/org/apache/jackrabbit/spi2microkernel/RepositoryTest.java Fri Jun 17 17:33:38 2011
@@ -44,6 +44,10 @@ import javax.jcr.Value;
 import javax.jcr.nodetype.NodeType;
 import javax.jcr.nodetype.NodeTypeManager;
 import javax.jcr.nodetype.NodeTypeTemplate;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.EventListener;
+import javax.jcr.observation.ObservationManager;
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.math.BigDecimal;
@@ -902,6 +906,29 @@ public class RepositoryTest {
         }
     }
 
+    @Test
+    public void observation() throws RepositoryException, InterruptedException {
+        ObservationManager obsMgr = getSession().getWorkspace().getObservationManager();
+        obsMgr.addEventListener(new EventListener(){
+                public void onEvent(EventIterator events) {
+                    while (events.hasNext()) {
+                        System.out.println(events.next());
+                    }
+                }
+            },
+            Event.NODE_ADDED | Event.NODE_MOVED | Event.NODE_MOVED | Event.PROPERTY_ADDED |
+            Event.PROPERTY_REMOVED | Event.PROPERTY_CHANGED | Event.PERSIST, "/", true, null, null, false);
+
+        Node n = getNode(testPath);
+        n.addNode("1");
+        n.addNode("2");
+        getSession().save();
+        n.addNode("3");
+        n.addNode("4");
+        getSession().save();
+        Thread.sleep(10000);
+    }
+
     //------------------------------------------< private >---
 
     private void addProperty(Node parentNode, String name, Value value) throws RepositoryException {