Return-Path: X-Original-To: apmail-jackrabbit-commits-archive@www.apache.org Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id F2E1C4058 for ; Tue, 21 Jun 2011 15:19:22 +0000 (UTC) Received: (qmail 45625 invoked by uid 500); 21 Jun 2011 15:19:22 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 45595 invoked by uid 500); 21 Jun 2011 15:19:22 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 45588 invoked by uid 99); 21 Jun 2011 15:19:22 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 21 Jun 2011 15:19:22 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 21 Jun 2011 15:19:18 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 3CC9123889E0; Tue, 21 Jun 2011 15:18:57 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1138045 - in /jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel: RepositoryServiceImpl.java SessionState.java SubscriptionImpl.java Date: Tue, 21 Jun 2011 15:18:57 -0000 To: commits@jackrabbit.apache.org From: mduerig@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110621151857.3CC9123889E0@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: mduerig Date: Tue Jun 21 15:18:56 2011 New Revision: 1138045 URL: http://svn.apache.org/viewvc?rev=1138045&view=rev Log: spi2microkernel prototype (WIP) observation (WIP) Modified: jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/RepositoryServiceImpl.java jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SessionState.java 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 URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/RepositoryServiceImpl.java?rev=1138045&r1=1138044&r2=1138045&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 Tue Jun 21 15:18:56 2011 @@ -401,7 +401,7 @@ public class RepositoryServiceImpl exten private void createSessionState(SessionInfo sessionInfo) throws RepositoryException { try { - sessions.put(sessionInfo, new SessionState(microKernel.getHeadRevision())); + sessions.put(sessionInfo, new SessionState(sessionInfo, microKernel.getHeadRevision())); } catch (MicroKernelException e) { throw new RepositoryException(e.getMessage(), e); Modified: jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SessionState.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SessionState.java?rev=1138045&r1=1138044&r2=1138045&view=diff ============================================================================== --- jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SessionState.java (original) +++ jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SessionState.java Tue Jun 21 15:18:56 2011 @@ -19,6 +19,8 @@ package org.apache.jackrabbit.spi2microkernel; +import org.apache.jackrabbit.spi.SessionInfo; + import javax.jcr.RepositoryException; import java.util.ArrayList; import java.util.List; @@ -26,9 +28,11 @@ import java.util.concurrent.Callable; public class SessionState { private final String initialRevision; - private final List commitLog = new ArrayList(); + private final SessionInfo sessionInfo; + private final List commitLog = new ArrayList(); - public SessionState(String initialRevision) { + public SessionState(SessionInfo sessionInfo, String initialRevision) { + this.sessionInfo = sessionInfo; this.initialRevision = initialRevision; } @@ -38,15 +42,19 @@ public class SessionState { } else { synchronized (commitLog) { - return commitLog.get(commitLog.size() - 1); + return commitLog.get(commitLog.size() - 1).getRevisionId(); } } } + public SessionInfo getSessionInfo() { + return sessionInfo; + } + public void commitWithLock(Callable commit) throws RepositoryException { try { synchronized (this) { - commitLog.add(commit.call()); + commitLog.add(new RevisionInfo(commit.call(), sessionInfo.getUserID(), null/* fixme: need accessors sessionInfo.getUserInfo()) */)); } } catch (Exception e) { @@ -58,12 +66,36 @@ public class SessionState { * Snapshot of this session state's commit log at the time of the call * @return */ - public List getCommitLog() { - List commitLog = new ArrayList(this.commitLog.size()); + public List getRevisionInfos() { + List commitLog = new ArrayList(this.commitLog.size()); synchronized (this.commitLog) { commitLog.addAll(this.commitLog); } return commitLog; } + public static class RevisionInfo { + private final String revisionId; + private final String userId; + private final String userData; + + public RevisionInfo(String revisionId, String userId, String userData) { + this.revisionId = revisionId; + this.userId = userId; + this.userData = userData; + } + + public String getRevisionId() { + return revisionId; + } + + public String getUserId() { + return userId; + } + + public String getUserData() { + return userData; + } + } + } Modified: 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=1138045&r1=1138044&r2=1138045&view=diff ============================================================================== --- jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SubscriptionImpl.java (original) +++ jackrabbit/sandbox/spi2microkernel/src/main/java/org/apache/jackrabbit/spi2microkernel/SubscriptionImpl.java Tue Jun 21 15:18:56 2011 @@ -20,9 +20,19 @@ package org.apache.jackrabbit.spi2microkernel; import org.apache.jackrabbit.mk.api.MicroKernel; +import org.apache.jackrabbit.mk.json.JsopTokenizer; +import org.apache.jackrabbit.spi.Event; import org.apache.jackrabbit.spi.EventBundle; import org.apache.jackrabbit.spi.EventFilter; +import org.apache.jackrabbit.spi.ItemId; +import org.apache.jackrabbit.spi.Name; +import org.apache.jackrabbit.spi.NodeId; +import org.apache.jackrabbit.spi.Path; +import org.apache.jackrabbit.spi.QValue; import org.apache.jackrabbit.spi.Subscription; +import org.apache.jackrabbit.spi.commons.EventBundleImpl; +import org.apache.jackrabbit.spi.commons.EventImpl; +import org.apache.jackrabbit.spi2microkernel.SessionState.RevisionInfo; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; @@ -35,6 +45,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Queue; public class SubscriptionImpl implements Subscription { @@ -49,8 +60,8 @@ public class SubscriptionImpl implements public void setEventFilters(EventFilter[] eventFilters) throws RepositoryException { synchronized (eventSources) { - List commitLog = sessionState.getCommitLog(); - eventSources.add(new EventSource(eventFilters, sessionState.getHeadRevision(), commitLog)); + List revisionInfos = sessionState.getRevisionInfos(); + eventSources.add(new EventSource(eventFilters, sessionState.getHeadRevision(), revisionInfos)); } } @@ -101,12 +112,12 @@ public class SubscriptionImpl implements private class EventSource { private final EventFilter[] eventFilters; private final String startRevision; - private final List commitLog; + private final List revisionInfos; - public EventSource(EventFilter[] eventFilters, String startRevision, List commitLog) { + public EventSource(EventFilter[] eventFilters, String startRevision, List revisionInfos) { this.eventFilters = eventFilters; this.startRevision = startRevision; - this.commitLog = commitLog; + this.revisionInfos = revisionInfos; } public String getStartRevision() { @@ -115,19 +126,18 @@ public class SubscriptionImpl implements public Collection getEventsBundles(String endRevision) throws RepositoryException { String journal = microKernel.getJournal(startRevision, endRevision); + List eventBundles = new ArrayList(); 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); + for (Object o : jsonArray) { + JSONObject jsonObject = jsonObject(o); + EventBundle eventBundle = createEventBundle(jsonObject); + if (eventBundle != null) { + eventBundles.add(eventBundle); + } } - - - return Collections.emptyList(); // todo implement getEventsBundles + return eventBundles; } catch (ParseException e) { throw new RepositoryException(e.getMessage(), e); @@ -136,7 +146,204 @@ public class SubscriptionImpl implements } public EventSource update(String startRevision) { - return new EventSource(eventFilters, startRevision, commitLog); + return new EventSource(eventFilters, startRevision, revisionInfos); + } + + //------------------------------------------< private >--- + + private EventBundle createEventBundle(JSONObject jsonObject) { + String revisionId = getString(jsonObject, "id"); + + // revisionInfo = revisionInfos.find(_.getRevisionId == revisionId) + RevisionInfo revisionInfo = null; + for (RevisionInfo info : revisionInfos) { + if (info.getRevisionId().equals(revisionId)) { // todo performance: use map!? + revisionInfo = info; + break; + } + } + + EventTemplate eventTemplate = new EventTemplate() + .setTimestamp(getLong(jsonObject, "ts")) + .setUserId(revisionInfo.getUserId()) + .setUserData(revisionInfo.getUserData()); + + String changes = getString(jsonObject, "changes"); + Collection events = getEvents(changes, eventTemplate); + + // fixme: revisionInfos.map(_.getRevisionId) + boolean isLocal = revisionInfos.contains(revisionId); // todo performance: this does a linear search on the list + + // events.filter(event => eventFilters.all(_.accept(event, isLocal)) + for (Iterator it = events.iterator(); it.hasNext(); ) { + for (EventFilter filter : eventFilters) { + if (!filter.accept(it.next(), isLocal)) { + it.remove(); + break; + } + } + } + + return new EventBundleImpl(events, isLocal); + } + + private Collection getEvents(String changes, EventTemplate eventTemplate) { + Collection events = new ArrayList(); + JsopTokenizer jsopTokenizer = new JsopTokenizer(changes); + + while (jsopTokenizer.read() != JsopTokenizer.END) { + int tokenType = jsopTokenizer.getTokenType(); + switch(tokenType) { + case '+': addNode(jsopTokenizer, eventTemplate, events); break; + case '-': removeNode(jsopTokenizer, eventTemplate, events); break; + case '^': setProperty(jsopTokenizer, eventTemplate, events); break; + case '>': moveNode(jsopTokenizer, eventTemplate, events); break; + default: throw new IllegalArgumentException("Invalid token: " + tokenType); + } + } + + return events; + } + + // Event#NODE_ADDED} Event#NODE_REMOVED} Event#PROPERTY_ADDED} Event#PROPERTY_REMOVED} + // Event#PROPERTY_CHANGED} Event#NODE_MOVED} Event#PERSIST} + private Event addNode(JsopTokenizer jsopTokenizer, EventTemplate eventTemplate, Collection events) { + // todo implement addNode + Path path = null; + ItemId itemId = null; + NodeId parentId = null; + + Name primaryNodeTypeName = null; + Name[] mixinTypeNames = null; + + String userId = null; + + String userData = null; + + return eventTemplate.buildEvent(); + } + + private Event removeNode(JsopTokenizer jsopTokenizer, EventTemplate eventTemplate, Collection events) { + return null; // todo implement removeNode + } + + private Event setProperty(JsopTokenizer jsopTokenizer, EventTemplate eventTemplate, Collection events) { + return null; // todo implement setProperty + } + + private Event moveNode(JsopTokenizer jsopTokenizer, EventTemplate eventTemplate, Collection events) { + return null; // todo implement moveNode + } + + private String getString(JSONObject jsonObject, String key) { + Object o = jsonObject.get(key); + if (o instanceof String) { + return (String) o; + } + else { + throw new IllegalArgumentException("Not a string: " + jsonObject); + } + } + + private long getLong(JSONObject jsonObject, String key) { + Object o = jsonObject.get(key); + if (o instanceof Long) { + return (Long) o; + } + else { + throw new IllegalArgumentException("Not a long: " + jsonObject); + } + } + + } + + private static class EventTemplate { + private int type; + private Path path; + private ItemId itemId; + private NodeId parentId; + private Name primaryNodeType; + private Name[] mixinTypes; + private String userId; + private String userData; + private long timestamp; + private Map info = Collections.emptyMap(); + + public EventTemplate() {} + + private EventTemplate(int type, Path path, ItemId itemId, NodeId parentId, Name primaryNodeType, Name[] mixinTypes, + String userId, String userData, long timestamp, Map info) { + + this.type = type; + this.path = path; + this.itemId = itemId; + this.parentId = parentId; + this.primaryNodeType = primaryNodeType; + this.mixinTypes = mixinTypes; + this.userId = userId; + this.userData = userData; + this.timestamp = timestamp; + this.info = info; + } + + public EventTemplate setType(int type) { + this.type = type; + return this; + } + + public EventTemplate setPath(Path path) { + this.path = path; + return this; + } + + public EventTemplate setItemId(ItemId itemId) { + this.itemId = itemId; + return this; + } + + public EventTemplate setParentId(NodeId parentId) { + this.parentId = parentId; + return this; + } + + public EventTemplate setPrimaryNodeType(Name primaryNodeType) { + this.primaryNodeType = primaryNodeType; + return this; + } + + public EventTemplate setMixinType(Name[] mixinTypes) { + this.mixinTypes = mixinTypes; + return this; + } + + public EventTemplate setUserId(String userId) { + this.userId = userId; + return this; + } + + public EventTemplate setUserData(String userData) { + this.userData = userData; + return this; + } + + public EventTemplate setTimestamp(long timestamp) { + this.timestamp = timestamp; + return this; + } + + public EventTemplate setInfo(Map info) { + this.info = info; + return this; + } + + public EventTemplate copy() { + return new EventTemplate(type, path, itemId, parentId, primaryNodeType, mixinTypes, userId, userData, + timestamp, info); + } + + public Event buildEvent() { + return new EventImpl(type, path, itemId, parentId, primaryNodeType, mixinTypes, userId, userData, + timestamp, info); } } }