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 {