jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mdue...@apache.org
Subject svn commit: r1212018 [2/7] - in /jackrabbit/sandbox/jackrabbit-microkernel: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/jackrabbit/ src/main/java/org/apache/jackrabbit/configuration/ src/main/j...
Date Thu, 08 Dec 2011 18:18:45 GMT
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionContext.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionContext.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionContext.java Thu Dec  8 18:18:42 2011
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+import org.apache.jackrabbit.security.CredentialsInfo;
+import org.apache.jackrabbit.state.TransientSpace;
+import org.apache.jackrabbit.mk.api.MicroKernel;
+
+import javax.jcr.Session;
+import javax.jcr.ValueFactory;
+
+public interface SessionContext<T extends Session> {
+    T getSession();
+    GlobalContext getGlobalContext();
+    CredentialsInfo getCredentialsInfo();
+    String getWorkspaceName();
+    MicroKernel getMicrokernel();
+    String getRevision();
+    ValueFactory getValueFactory();
+    TransientSpace getTransientSpace();
+}

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionContext.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionFactory.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionFactory.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionFactory.java Thu Dec  8 18:18:42 2011
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+import javax.jcr.Credentials;
+import javax.jcr.LoginException;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.Session;
+
+public interface SessionFactory {
+    Session createSession(GlobalContext context, Credentials credentials, String workspaceName)
+            throws LoginException, NoSuchWorkspaceException;
+}

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionFactory.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionImpl.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionImpl.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionImpl.java Thu Dec  8 18:18:42 2011
@@ -0,0 +1,436 @@
+/*
+ * 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;
+
+import org.apache.jackrabbit.security.Authenticator;
+import org.apache.jackrabbit.security.CredentialsInfo;
+import org.apache.jackrabbit.state.TransientSpace;
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+import javax.jcr.Credentials;
+import javax.jcr.Item;
+import javax.jcr.LoginException;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.ValueFactory;
+import javax.jcr.Workspace;
+import javax.jcr.retention.RetentionManager;
+import javax.jcr.security.AccessControlManager;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.AccessControlException;
+
+public class SessionImpl implements Session {
+    private final GlobalContext globalContext;
+    private final CredentialsInfo credentialsInfo;
+    private final String workspaceName;
+    private final MicroKernel microKernel;
+    private final TransientSpace transientSpace;
+
+    private String revision;
+    private boolean live = true;
+
+    interface Context extends SessionContext<SessionImpl>{}
+
+    private final Context sessionContext = new Context() {
+        @Override
+        public SessionImpl getSession() {
+            return SessionImpl.this;
+        }
+
+        @Override
+        public GlobalContext getGlobalContext() {
+            return globalContext;
+        }
+
+        @Override
+        public CredentialsInfo getCredentialsInfo() {
+            return credentialsInfo;
+        }
+        
+        @Override
+        public String getWorkspaceName() {
+            return workspaceName;
+        }
+
+        @Override
+        public MicroKernel getMicrokernel() {
+            return microKernel;
+        }
+
+        @Override
+        public String getRevision() {
+            return revision;
+        }
+
+        @Override
+        public ValueFactory getValueFactory() {
+            return globalContext.getInstance(ValueFactory.class);
+        }
+
+        @Override
+        public TransientSpace getTransientSpace() {
+            return transientSpace;
+        }
+    };
+
+    public static final SessionFactory FACTORY = new SessionFactory() {
+        @Override
+        public Session createSession(GlobalContext globalContext, Credentials credentials,
+                String workspaceName) throws LoginException, NoSuchWorkspaceException {
+
+            Authenticator authenticator = globalContext.getInstance(Authenticator.class);
+            CredentialsInfo credentialsInfo = authenticator.authenticate(credentials);
+            MicroKernel microKernel = globalContext.getInstance(MicroKernel.class);
+            String revision = microKernel.getHeadRevision();
+
+            if (workspaceName == null) {
+                workspaceName = WorkspaceImpl.DEFAULT_WORKSPACE_NAME;
+            }
+
+            if (!microKernel.nodeExists('/' + workspaceName, revision)) {
+                if (WorkspaceImpl.DEFAULT_WORKSPACE_NAME.equals(workspaceName)) {
+                    WorkspaceImpl.createWorkspace(microKernel, workspaceName);
+                    revision = microKernel.getHeadRevision();
+                }
+                else {
+                    throw new NoSuchWorkspaceException(workspaceName);
+                }
+            }
+
+            return new SessionImpl(globalContext, credentialsInfo, workspaceName, revision);
+        }
+    };
+
+    private SessionImpl(GlobalContext globalContext, CredentialsInfo credentialsInfo, String workspaceName,
+                        String revision) {
+
+        this.globalContext = globalContext;
+        this.credentialsInfo = credentialsInfo;
+        this.workspaceName = workspaceName;
+        this.revision = revision;
+        microKernel = globalContext.getInstance(MicroKernel.class);
+        transientSpace = new TransientSpace(microKernel,  revision, Path.create(workspaceName));
+    }
+
+    //------------------------------------------< Session >--- 
+
+    @Override
+    public Repository getRepository() {
+        return globalContext.getInstance(Repository.class);
+    }
+
+    @Override
+    public String getUserID() {
+        return credentialsInfo.getUserId();
+    }
+
+    @Override
+    public String[] getAttributeNames() {
+        return credentialsInfo.getAttributeNames();
+    }
+
+    @Override
+    public Object getAttribute(String name) {
+        return credentialsInfo.getAttribute(name);
+    }
+
+    @Override
+    public Workspace getWorkspace() {
+        return WorkspaceImpl.create(sessionContext);
+    }
+
+    @Override
+    public Session impersonate(Credentials credentials) throws RepositoryException {
+        checkLive();
+
+        return getRepository().login(credentials, workspaceName);
+    }
+
+    @Override
+    public ValueFactory getValueFactory() throws RepositoryException {
+        checkLive();
+        return sessionContext.getValueFactory();
+    }
+
+    //------------------------------------------< Reading >---
+
+    @Override
+    public Node getRootNode() throws RepositoryException {
+        return NodeImpl.create(sessionContext, Path.create(workspaceName));
+    }
+
+    @Override
+    public Item getItem(String absPath) throws RepositoryException {
+        if (nodeExists(absPath)) {
+            return getNode(absPath);
+        }
+        else {
+            return getProperty(absPath);
+        }
+    }
+
+    @Override
+    public boolean itemExists(String absPath) throws RepositoryException {
+        return nodeExists(absPath) || propertyExists(absPath);
+    }
+
+    @Override
+    public Node getNode(String absPath) throws RepositoryException {
+        return NodeImpl.create(sessionContext, Path.create(workspaceName, absPath));
+    }
+
+    @Override
+    public boolean nodeExists(String absPath) throws RepositoryException {
+        return nodeExists(Path.create(workspaceName, absPath));
+    }
+
+    @Override
+    public Property getProperty(String absPath) throws RepositoryException {
+        if ("/".equals(absPath)) {
+            throw new PathNotFoundException(absPath);
+        }
+
+        return PropertyImpl.create(sessionContext, Path.create(workspaceName, absPath));
+    }
+
+    @Override
+    public boolean propertyExists(String absPath) throws RepositoryException {
+        return propertyExists(Path.create(workspaceName, absPath));
+    }
+
+    @Override
+    public Node getNodeByUUID(String uuid) throws RepositoryException {
+        return getNodeByIdentifier(uuid);
+    }
+
+    @Override
+    public Node getNodeByIdentifier(String id) throws RepositoryException {
+        // todo implement getNodeByIdentifier
+        throw new UnsupportedRepositoryOperationException("getNodeByIdentifier");
+    }
+
+    //------------------------------------------< Writing >---
+
+    @Override
+    public void move(String srcAbsPath, String destAbsPath) throws RepositoryException {
+        checkLive();
+        // todo implement move
+        throw new UnsupportedRepositoryOperationException("move");
+    }
+
+    @Override
+    public void removeItem(String absPath) throws RepositoryException {
+        checkLive();
+        getItem(absPath).remove();
+    }
+
+    //------------------------------------------< state >---
+    
+    @Override
+    public void save() throws RepositoryException {
+        checkLive();
+        revision = transientSpace.save();
+    }
+
+    @Override
+    public void refresh(boolean keepChanges) throws RepositoryException {
+        checkLive();
+        revision = transientSpace.refresh(keepChanges);
+    }
+
+    @Override
+    public boolean hasPendingChanges() throws RepositoryException {
+        checkLive();
+        return transientSpace.isDirty();
+    }
+
+    //------------------------------------------< Lifecycle >--- 
+
+    @Override
+    public void logout() {
+        live = false;
+    }
+
+    @Override
+    public boolean isLive() {
+        return live;
+    }
+
+    //------------------------------------------< Import / Export >---
+
+    @Override
+    public ContentHandler getImportContentHandler(String parentAbsPath, int uuidBehavior) throws RepositoryException {
+        checkLive();
+        // todo implement getImportContentHandler
+        throw new UnsupportedRepositoryOperationException("getImportContentHandler");
+    }
+
+    @Override
+    public void importXML(String parentAbsPath, InputStream in, int uuidBehavior) throws IOException, RepositoryException {
+        checkLive();
+        // todo implement importXML
+    }
+
+    @Override
+    public void exportSystemView(String absPath, ContentHandler contentHandler, boolean skipBinary, boolean noRecurse)
+            throws SAXException, RepositoryException {
+
+        checkLive();
+        // todo implement exportSystemView
+    }
+
+    @Override
+    public void exportSystemView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse)
+            throws IOException, RepositoryException {
+
+        checkLive();
+        // todo implement exportSystemView
+    }
+
+    @Override
+    public void exportDocumentView(String absPath, ContentHandler contentHandler, boolean skipBinary, boolean noRecurse)
+            throws SAXException, RepositoryException {
+
+        checkLive();
+        // todo implement exportDocumentView
+    }
+
+    @Override
+    public void exportDocumentView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse)
+            throws IOException, RepositoryException {
+
+        checkLive();
+        // todo implement exportDocumentView
+    }
+
+    //------------------------------------------< Namespaces >---
+
+    @Override
+    public void setNamespacePrefix(String prefix, String uri) throws RepositoryException {
+        checkLive();
+        // todo implement setNamespacePrefix
+    }
+
+    @Override
+    public String[] getNamespacePrefixes() throws RepositoryException {
+        checkLive();
+        // todo implement getNamespacePrefixes
+        throw new UnsupportedRepositoryOperationException("getNamespacePrefix");
+    }
+
+    @Override
+    public String getNamespaceURI(String prefix) throws RepositoryException {
+        checkLive();
+        // todo implement getNamespaceURI
+        throw new UnsupportedRepositoryOperationException("getNamespaceURI");
+    }
+
+    @Override
+    public String getNamespacePrefix(String uri) throws RepositoryException {
+        checkLive();
+        // todo implement getNamespacePrefix
+        throw new UnsupportedRepositoryOperationException("getNamespacePrefix");
+    }
+
+    //------------------------------------------< Locking >---
+
+    @Override
+    public void addLockToken(String lt) {
+        // todo implement addLockToken
+    }
+
+    @Override
+    public String[] getLockTokens() {
+        // todo implement getLockTokens
+        return new String[0];
+    }
+
+    @Override
+    public void removeLockToken(String lt) {
+        // todo implement removeLockToken
+    }
+
+    //------------------------------------------< AccessControl >---
+
+    @Override
+    public boolean hasPermission(String absPath, String actions) throws RepositoryException {
+        checkLive();
+        // todo implement hasPermission
+        return true;
+    }
+
+    @Override
+    public void checkPermission(String absPath, String actions) throws AccessControlException, RepositoryException {
+        checkLive();
+        // todo implement checkPermission
+    }
+
+    @Override
+    public boolean hasCapability(String methodName, Object target, Object[] arguments) throws RepositoryException {
+        checkLive();
+        // todo implement hasCapability
+        return false;
+    }
+
+    @Override
+    public AccessControlManager getAccessControlManager() throws RepositoryException {
+        checkLive();
+        // todo implement getAccessControlManager
+        throw new UnsupportedRepositoryOperationException("getAccessControlManager");
+    }
+
+    //------------------------------------------< Retention >---
+
+    @Override
+    public RetentionManager getRetentionManager() throws RepositoryException {
+        checkLive();
+        // todo implement getRetentionManager
+        throw new UnsupportedRepositoryOperationException("getRetentionManager");
+    }
+
+    //------------------------------------------< internal >---
+
+    boolean nodeExists(Path absPath) throws RepositoryException {
+        return absPath.isRoot() || NodeImpl.exist(sessionContext, absPath);
+    }
+
+    boolean propertyExists(Path absPath) throws RepositoryException {
+        return !absPath.isRoot() && PropertyImpl.exist(sessionContext, absPath);
+    }
+
+    //------------------------------------------< private >---
+
+    private void checkLive() throws RepositoryException {
+        if (!isLive()) {
+            throw new RepositoryException("Session has already been closed");
+        }
+    }
+
+}

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionImpl.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/WorkspaceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/WorkspaceImpl.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/WorkspaceImpl.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/WorkspaceImpl.java Thu Dec  8 18:18:42 2011
@@ -0,0 +1,190 @@
+/*
+ * 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;
+
+import org.apache.jackrabbit.SessionImpl.Context;
+import org.apache.jackrabbit.json.FullJsonParser;
+import org.apache.jackrabbit.json.JsonValue;
+import org.apache.jackrabbit.json.JsonValue.JsonObject;
+import org.apache.jackrabbit.json.JsonValue.Type;
+import org.apache.jackrabbit.json.UnescapingJsonTokenizer;
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.xml.sax.ContentHandler;
+
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.Workspace;
+import javax.jcr.lock.LockManager;
+import javax.jcr.nodetype.NodeTypeManager;
+import javax.jcr.observation.ObservationManager;
+import javax.jcr.query.QueryManager;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionManager;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+
+public class WorkspaceImpl implements Workspace {
+    public static final String DEFAULT_WORKSPACE_NAME = "default";
+
+    private final Context sessionContext;
+
+    private WorkspaceImpl(Context sessionContext) {
+        this.sessionContext = sessionContext;
+    }
+
+    public static Workspace create(Context sessionContext) {
+        return new WorkspaceImpl(sessionContext);
+    }
+
+    @Override
+    public Session getSession() {
+        return sessionContext.getSession();
+    }
+
+    @Override
+    public String getName() {
+        return sessionContext.getWorkspaceName();
+    }
+
+    @Override
+    public void copy(String srcAbsPath, String destAbsPath) throws RepositoryException {
+        // todo implement copy
+    }
+
+    @Override
+    public void copy(String srcWorkspace, String srcAbsPath, String destAbsPath) throws RepositoryException {
+        // todo implement copy
+    }
+
+    @Override
+    public void clone(String srcWorkspace, String srcAbsPath, String destAbsPath, boolean removeExisting)
+            throws RepositoryException {
+        
+        // todo implement clone
+    }
+
+    @Override
+    public void move(String srcAbsPath, String destAbsPath) throws RepositoryException {
+        // todo implement move
+    }
+
+    @Override
+    public void restore(Version[] versions, boolean removeExisting) throws RepositoryException {
+        // todo implement restore
+    }
+
+    @Override
+    public LockManager getLockManager() throws RepositoryException {
+        // todo implement getLockManager
+        throw new UnsupportedRepositoryOperationException("getLockManager");
+    }
+
+    @Override
+    public QueryManager getQueryManager() throws RepositoryException {
+        // todo implement getQueryManager
+        throw new UnsupportedRepositoryOperationException("getQueryManager");
+    }
+
+    @Override
+    public NamespaceRegistry getNamespaceRegistry() throws RepositoryException {
+        // todo implement getNamespaceRegistry
+        throw new UnsupportedRepositoryOperationException("getNamespaceRegistry");
+    }
+
+    @Override
+    public NodeTypeManager getNodeTypeManager() throws RepositoryException {
+        // todo implement getNodeTypeManager
+        throw new UnsupportedRepositoryOperationException("getNodeTypeManager");
+    }
+
+    @Override
+    public ObservationManager getObservationManager() throws RepositoryException {
+        // todo implement getObservationManager
+        throw new UnsupportedRepositoryOperationException("getObservationManager");
+    }
+
+    @Override
+    public VersionManager getVersionManager() throws RepositoryException {
+        // todo implement getVersionManager
+        throw new UnsupportedRepositoryOperationException("getVersionManager");
+    }
+
+    @Override
+    public String[] getAccessibleWorkspaceNames() throws RepositoryException {
+        MicroKernel microKernel = sessionContext.getMicrokernel();
+        String revision = sessionContext.getRevision();
+        String json = microKernel.getNodes("/", revision, 0, 0, -1);
+        JsonObject jsonObject = FullJsonParser.parseObject(new UnescapingJsonTokenizer(json));
+
+        List<String> workspaces = new ArrayList<String>();
+        for (Entry<String, JsonValue> entry : jsonObject.value().entrySet()) {
+            if (entry.getValue().type() == Type.OBJECT) {
+                workspaces.add(entry.getKey());
+            }
+        }
+
+        return workspaces.toArray(new String[workspaces.size()]);
+    }
+
+    @Override
+    public ContentHandler getImportContentHandler(String parentAbsPath, int uuidBehavior)
+            throws RepositoryException {
+        
+        // todo implement getImportContentHandler
+        throw new UnsupportedRepositoryOperationException("getImportContentHandler");
+    }
+
+    @Override
+    public void importXML(String parentAbsPath, InputStream in, int uuidBehavior) throws IOException,
+            RepositoryException {
+        
+        // todo implement importXML
+    }
+
+    @Override
+    public void createWorkspace(String name) throws RepositoryException {
+        createWorkspace(sessionContext.getMicrokernel(), name);
+    }
+
+    @Override
+    public void createWorkspace(String name, String srcWorkspace) throws RepositoryException {
+        // todo implement createWorkspace
+    }
+
+    @Override
+    public void deleteWorkspace(String name) throws RepositoryException {
+        MicroKernel microKernel = sessionContext.getMicrokernel();
+        String revision = microKernel.getHeadRevision();
+        microKernel.commit("/", "- \"" + name + '\"', revision, null);
+    }
+
+    //------------------------------------------< internal >---
+
+    static void createWorkspace(MicroKernel microKernel,String name) {
+        String revision = microKernel.getHeadRevision();
+        microKernel.commit("/", "+ \"" + name + "\" : {}", revision, null);
+    }
+
+}

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/WorkspaceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/WorkspaceImpl.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfiguration.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfiguration.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfiguration.java Thu Dec  8 18:18:42 2011
@@ -0,0 +1,30 @@
+/*
+ * 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.configuration;
+
+import javax.jcr.RepositoryException;
+import java.util.Map;
+
+public interface RepositoryConfiguration {
+    String MICROKERNEL_URL = RepositoryConfiguration.class.getName() + ".microkernel-url";
+
+    Map<String, String> getParameterMap();
+    String getMicrokernelUrl() throws RepositoryException;
+}

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfiguration.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfiguration.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfigurationImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfigurationImpl.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfigurationImpl.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfigurationImpl.java Thu Dec  8 18:18:42 2011
@@ -0,0 +1,54 @@
+/*
+ * 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.configuration;
+
+import javax.jcr.RepositoryException;
+import java.util.Collections;
+import java.util.Map;
+
+import static java.text.MessageFormat.format;
+
+public class RepositoryConfigurationImpl implements RepositoryConfiguration {
+    private final Map<String, String> parameters;
+
+    private RepositoryConfigurationImpl(Map<String, String> parameters) {
+        this.parameters = Collections.unmodifiableMap(parameters);
+    }
+
+    public static RepositoryConfiguration create(Map<String, String> parameters) {
+        return new RepositoryConfigurationImpl(parameters);
+    }
+
+    @Override
+    public Map<String, String> getParameterMap() {
+        return parameters;
+    }
+
+    @Override
+    public String getMicrokernelUrl() throws RepositoryException {
+        String microkernelUrl = getParameterMap().get(RepositoryConfiguration.MICROKERNEL_URL);
+        if (microkernelUrl == null) {
+            throw new RepositoryException(
+                    format("Missing configuration value for {0}", RepositoryConfiguration.MICROKERNEL_URL));
+        }
+
+        return microkernelUrl;
+    }
+}

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfigurationImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfigurationImpl.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/DefaultJsonTokenizer.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/DefaultJsonTokenizer.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/DefaultJsonTokenizer.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/DefaultJsonTokenizer.java Thu Dec  8 18:18:42 2011
@@ -0,0 +1,214 @@
+/*
+ * 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.json;
+
+import org.apache.jackrabbit.json.Token.Type;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * This JSON tokenizer operates on a string as its input. For maximal performance
+ * it <em>does not</em> unescape JSON string values.
+ * Use {@link JsonValue#unescape(String)} to unescape the text of {@link Token}s
+ * of type {@link Type#STRING}.
+ * 
+ * @see UnescapingJsonTokenizer
+ */
+public class DefaultJsonTokenizer extends JsonTokenizer {
+    private final String json;
+
+    private int pos;
+
+    /**
+     * Create a tokenizer for the given input string
+     * @param json
+     */
+    public DefaultJsonTokenizer(String json) {
+        this.json = json;
+    }
+
+    /**
+     * @see JsonTokenizer#JsonTokenizer(JsonTokenizer)
+     */
+    protected DefaultJsonTokenizer(DefaultJsonTokenizer tokenizer) {
+        super(tokenizer);
+        json = tokenizer.json;
+        pos = tokenizer.pos;
+    }
+
+    @Override
+    protected Token nextToken() {
+        skipWhiteSpace();
+        if (pos >= json.length()) {
+            return createToken(Type.EOF, "", pos);
+        }
+
+        switch (json.charAt(pos)) {
+            case '{': return createToken(Type.BEGIN_OBJECT, "{", pos++);
+            case '}': return createToken(Type.END_OBJECT, "}", pos++);
+            case '[': return createToken(Type.BEGIN_ARRAY, "[", pos++);
+            case ']': return createToken(Type.END_ARRAY, "]", pos++);
+            case ':': return createToken(Type.COLON, ":", pos++);
+            case ',': return createToken(Type.COMMA, ",", pos++);
+            case 't': return readLiteral(Type.TRUE, "true");
+            case 'f': return readLiteral(Type.FALSE, "false");
+            case 'n': return readLiteral(Type.NULL, "null");
+            case '"': return readString();
+            default:  return isNumber() ? readNumber() : readUnknown();
+        }
+    }
+
+    @Override
+    public int pos() {
+        return peek().pos();
+    }
+
+    @Override
+    public void setPos(int pos) {
+        currentToken = null;
+        this.pos = pos;
+    }
+
+    @Override
+    public String toString() {
+        return (currentToken == null ? "" : currentToken) + " " + json.substring(pos);
+    }
+
+    @Override
+    public DefaultJsonTokenizer copy() {
+        return new DefaultJsonTokenizer(this);
+    }
+
+    //------------------------------------------< protected >---
+
+    /**
+     * Advance {@link #pos()} until the current character is not a
+     * whitespace character.
+     */
+    protected void skipWhiteSpace() {
+        while (pos < json.length() && Character.isWhitespace(json.charAt(pos))) {
+            pos++;
+        }
+    }
+
+    /**
+     * Factory method for creating {@link Token}s
+     * @param type
+     * @param text
+     * @param pos
+     * @return a new token
+     */
+    protected Token createToken(Type type, String text, int pos) {
+        return new Token(type, text, pos);
+    }
+
+    /**
+     * Read the literal {@code text} and create a token of the given {@code type}
+     * @param type
+     * @param text
+     * @return a new token
+     * @throws ParseException  if {@code text} cannot be read at the current position
+     */
+    protected Token readLiteral(Type type, String text) {
+        if (json.substring(pos).startsWith(text)) {
+            Token token = createToken(type, text, pos);
+            pos += text.length();
+            return token;
+        }
+        else {
+            throw new ParseException(pos, "Expected '" + text + ",' found: " + excerpt(json, pos, 40));
+        }
+    }
+
+    /**
+     * Read a JSON string and create a {@link Token.Type#STRING} token.
+     * @return a new token
+     * @throws ParseException  if no string can be read at the current position
+     */
+    protected Token readString() {
+        int i;
+        boolean found = false;
+        boolean even = true;
+
+        // starting at pos + 1, find index i of the first quote character in json which
+        // is preceded by an even number of backslash characters
+        for (i = pos + 1; i < json.length() && !(found = json.charAt(i) == '"' && even); i++) {
+            even = json.charAt(i) != '\\' || !even;
+        }
+
+        if (found) {
+            Token token = createToken(Type.STRING, json.substring(pos + 1, i), pos);
+            pos = i + 1;
+            return token;
+        }
+        else {
+            throw new ParseException(pos, "Expected string, found. " + excerpt(json, pos, 40));
+        }
+    }
+    
+    private static final Pattern NUMBER_PATTERN = Pattern.compile(
+            "(\\+|-)?(\\d+)((\\.)(\\d+))?(((e|E)(\\+|-)?)(\\d+))?");
+
+    /**
+     * Read a JSON number and create a {@link Token.Type#NUMBER} token.
+     * @return a new token
+     * @throws ParseException  if no number can be read at the current position
+     */
+    protected Token readNumber() {
+        Matcher matcher = NUMBER_PATTERN.matcher(json.substring(pos));
+        if (matcher.lookingAt()) {
+            Token token = createToken(Type.NUMBER, matcher.group(), pos);
+            pos += matcher.end();
+            return token;
+        }
+        else {
+            throw new ParseException(pos, "Expected number, found. " + excerpt(json, pos, 40));
+        }
+    }
+
+    /**
+     * Read from the current position until a new token starts and create a
+     * {@link Token.Type#UNKNOWN} token.
+     * @return a new token
+     */
+    protected Token readUnknown() {
+        int start = pos++;
+        while (pos < json.length() && "{}[]:,tfn+-0123456789\" ".indexOf(json.charAt(pos)) == -1)  {
+            pos++;
+        }
+        return new Token(Type.UNKNOWN, json.substring(start, pos), start);
+    }
+
+    //------------------------------------------< private >---
+
+    private boolean isNumber() {
+        // true if first character is a digit or a sign and second character is a digit
+        char first = json.charAt(pos);
+        return !(!Character.isDigit(first) &&
+                ('+' != first && '-' != first || pos + 1 >= json.length() ||
+                 !Character.isDigit(json.charAt(pos + 1))));
+    }
+
+    private static String excerpt(String string, int pos, int len) {
+        return string.substring(pos, Math.min(string.length(), pos + len)) + "...";
+    }
+
+}

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/DefaultJsonTokenizer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/DefaultJsonTokenizer.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/FullJsonParser.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/FullJsonParser.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/FullJsonParser.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/FullJsonParser.java Thu Dec  8 18:18:42 2011
@@ -0,0 +1,117 @@
+/*
+ * 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.json;
+
+import org.apache.jackrabbit.json.JsonValue.JsonArray;
+import org.apache.jackrabbit.json.JsonValue.JsonAtom;
+import org.apache.jackrabbit.json.JsonValue.JsonObject;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+
+/**
+ * Utility class for parsing JSON objects and arrays into
+ * {@link JsonObject}s and {@link JsonArray}s, respectively.
+ *
+ * @see LevelOrderJsonParser
+ */
+public class FullJsonParser {
+    private FullJsonParser() { }
+
+    /**
+     * Parse a JSON object from {@code tokenizer}
+     * @param tokenizer
+     * @return a {@code JsonObject}
+     * @throws ParseException
+     */
+    public static JsonObject parseObject(JsonTokenizer tokenizer) {
+        ObjectHandler objectHandler = new ObjectHandler();
+        new JsonParser(objectHandler).parseObject(tokenizer);
+        return objectHandler.getObject();
+    }
+
+    /**
+     * Parse a JSON array from {@code tokenizer}
+     * @param tokenizer
+     * @return a {@code JsonArray}
+     * @throws ParseException
+     */
+    public static JsonArray parseArray(JsonTokenizer tokenizer) {
+        ArrayHandler arrayHandler = new ArrayHandler();
+        new JsonParser(arrayHandler).parseArray(tokenizer);
+        return arrayHandler.getArray();
+    }
+
+    /**
+     * This implementation of a {@code JsonHandler} builds up a {@code JsonObject}
+     * by recursively descending into its constituents.  
+     */
+    public static class ObjectHandler extends JsonHandler {
+        private final JsonObject object = new JsonObject(new LinkedHashMap<String, JsonValue>());
+
+        @Override
+        public void atom(Token key, Token value) {
+            object.put(key.text(), new JsonAtom(value));
+        }
+
+        @Override
+        public void object(JsonParser parser, Token key, JsonTokenizer tokenizer) {
+            object.put(key.text(), parseObject(tokenizer));
+        }
+
+        @Override
+        public void array(JsonParser parser, Token key, JsonTokenizer tokenizer) {
+            object.put(key.text(), parseArray(tokenizer));
+        }
+
+        public JsonObject getObject() {
+            return object;
+        }
+
+    }
+
+    /**
+     * This implementation of a {@code JsonHandler} builds up a {@code JsonArray}
+     * by recursively descending into its constituents.
+     */
+    public static class ArrayHandler extends JsonHandler {
+        private final JsonArray array = new JsonArray(new ArrayList<JsonValue>());
+
+        @Override
+        public void atom(Token key, Token value) {
+            array.add(new JsonAtom(value));
+        }
+
+        @Override
+        public void object(JsonParser parser, Token key, JsonTokenizer tokenizer) {
+            array.add(parseObject(tokenizer));
+        }
+
+        @Override
+        public void array(JsonParser parser, Token key, JsonTokenizer tokenizer) {
+            array.add(parseArray(tokenizer));
+        }
+
+        public JsonArray getArray() {
+            return array;
+        }
+    }
+
+}

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/FullJsonParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/FullJsonParser.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonHandler.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonHandler.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonHandler.java Thu Dec  8 18:18:42 2011
@@ -0,0 +1,84 @@
+/*
+ * 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.json;
+
+/**
+ * Handler for semantic actions of a {@link JsonParser}.
+ * This class provides a handler which fully parses a JSON
+ * document by recursive decent without executing any actions.
+ * <p/>
+ * Override this class to add semantic actions as needed. 
+ */
+public class JsonHandler {
+
+    /**
+     * Default instance which can be used to skip any part of a
+     * JSON document. 
+     */
+    public static final JsonHandler INSTANCE = new JsonHandler();
+
+    /**
+     * A primitive JSON value (ATOM) has been parsed.
+     * @param key
+     * @param value
+     */
+    public void atom(Token key, Token value) { }
+
+    /**
+     * A COMMA has been parsed
+     * @param token
+     */
+    public void comma(Token token) { }
+
+    /**
+     * Parser PAIR. This implementation simply delegates back
+     * to {@link JsonParser#parsePair(JsonTokenizer)}
+     * 
+     * @param parser
+     * @param tokenizer
+     */
+    public void pair(JsonParser parser, JsonTokenizer tokenizer) {
+        parser.parsePair(tokenizer);
+    }
+
+    /**
+     * Parser OBJECT. This implementation simply delegates back
+     * to {@link JsonParser#parseObject(JsonTokenizer)}
+     *
+     * @param parser
+     * @param key
+     * @param tokenizer
+     */
+    public void object(JsonParser parser, Token key, JsonTokenizer tokenizer) {
+        parser.parseObject(tokenizer);
+    }
+
+    /**
+     * Parser ARRAY. This implementation simply delegates back
+     * to {@link JsonParser#parseArray(JsonTokenizer)} 
+     *
+     * @param parser
+     * @param key
+     * @param tokenizer
+     */
+    public void array(JsonParser parser, Token key, JsonTokenizer tokenizer) {
+        parser.parseArray(tokenizer);
+    }
+}

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonHandler.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonParser.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonParser.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonParser.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonParser.java Thu Dec  8 18:18:42 2011
@@ -0,0 +1,171 @@
+/*
+ * 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.json;
+
+import org.apache.jackrabbit.json.Token.Type;
+
+/**
+ * A parser for the JSON format accepting the following grammar:
+ *
+ * <pre>
+ * OBJECT    ::= { (PAIR (, PAIR)*)? }
+ * PAIR      ::= STRING : VALUE
+ * VALUE     ::= OBJECT | ARRAY | STRING | NUMBER | true | false | null
+ * ARRAY     ::= [ (VALUE (, VALUE)*)? ]
+ * </pre>
+ *
+ * Semantic actions are attached through a {@link JsonHandler} instance
+ * which is passed to the constructor. For each of the above productions
+ * the parser provides a corresponding method which take a {@link JsonTokenizer}
+ * for reading the JSON input. These methods call the respective call back on the
+ * {@code JsonHandler} for each of the constituents of the production.
+ * <p/>
+ * Note: In contrast to conventional parsers, this parser <em>does not</em>
+ * recursively decent into nested structures (OBJECT, ARRAY and PAIR, that is).
+ * Instead it calls the respective method on the {@code JsonHandler} which
+ * is can use this parser instance or any other parser to continue parsing.
+ *
+ * @see <a href="http://www.json.org/">json.org</a>
+ */
+public final class JsonParser {
+    private final JsonHandler jsonHandler;
+
+    public JsonParser(JsonHandler jsonHandler) {
+        this.jsonHandler = jsonHandler;
+    }
+
+    /**
+     * Parses
+     * <pre>
+     * OBJECT ::= { (PAIR (, PAIR)*)? }
+     * </pre>
+     * Calls {@link JsonHandler#comma(Token)}
+     * @param tokenizer
+     * @throws ParseException
+     */
+    public void parseObject(JsonTokenizer tokenizer) {
+        tokenizer.read(Type.BEGIN_OBJECT);
+
+        if (tryParsePair(tokenizer)) {
+            while (tokenizer.peek(Type.COMMA)) {
+                jsonHandler.comma(tokenizer.read());
+                if (!tryParsePair(tokenizer)) {
+                    throw new ParseException(tokenizer.pos(),  "Expected pair, found: " + tokenizer.peek());
+                }
+            }
+        }
+        tokenizer.read(Type.END_OBJECT);
+    }
+
+    /**
+     * Parses
+     * <pre>
+     * PAIR ::= STRING: VALUE
+     * </pre>
+     * @param tokenizer
+     * @throws ParseException
+     */
+    public void parsePair(JsonTokenizer tokenizer) {
+        if (!tokenizer.peek(Type.STRING)) {
+            throw new ParseException(tokenizer.pos(), "Expected string, found: " + tokenizer.peek());
+        }
+
+        Token key = tokenizer.read();
+        tokenizer.read(Type.COLON);
+        parseValue(key, tokenizer);
+    }
+
+    /**
+     * Parses
+     * <pre>
+     * VALUE ::= OBJECT | ARRAY | STRING | NUMBER | true | false | null
+     * </pre>
+     * Calls one of {@link JsonHandler#object(JsonParser, Token, JsonTokenizer)},
+     * {@link JsonHandler#array(JsonParser, Token, JsonTokenizer)} and
+     * {@link JsonHandler#atom(Token, Token)}
+     * @param tokenizer
+     * @throws ParseException
+     */
+    public void parseValue(Token key, JsonTokenizer tokenizer) {
+        switch (tokenizer.peek().type()) {
+            case BEGIN_OBJECT:
+                jsonHandler.object(this, key, tokenizer);
+                break;
+            case BEGIN_ARRAY:
+                jsonHandler.array(this, key, tokenizer);
+                break;
+            case STRING:
+            case NUMBER:
+            case TRUE:
+            case FALSE:
+            case NULL:
+                jsonHandler.atom(key, tokenizer.read());
+                break;
+            default:
+                throw new ParseException(tokenizer.pos(), "Expected value, found: " + tokenizer.peek());
+        }
+    }
+
+    /**
+     * Parses
+     * <pre>
+     * ARRAY ::= [ (VALUE (, VALUE)*)? ]
+     * </pre>
+     * Calls {@link JsonHandler#comma(Token)}
+     * @param tokenizer
+     * @throws ParseException
+     */
+    public void parseArray(JsonTokenizer tokenizer) {
+        tokenizer.read(Type.BEGIN_ARRAY);
+
+        if (tryParseValue(tokenizer)) {
+            while (tokenizer.peek(Type.COMMA)) {
+                jsonHandler.comma(tokenizer.read());
+                if (!tryParseValue(tokenizer)) {
+                    throw new ParseException(tokenizer.pos(), "Expected value, found: " + tokenizer.peek()); 
+                }
+            }
+        }
+        tokenizer.read(Type.END_ARRAY);
+    }
+
+    //------------------------------------------< private >---
+    
+    private boolean tryParsePair(JsonTokenizer tokenizer) {
+        if (tokenizer.peek(Type.STRING)) {
+            jsonHandler.pair(this, tokenizer);
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    private boolean tryParseValue(JsonTokenizer tokenizer) {
+        if (tokenizer.peek(Type.END_ARRAY)) {
+            return false;
+        }
+        else {
+            parseValue(null, tokenizer);
+            return true;
+        }
+    }
+
+}

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonParser.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonTokenizer.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonTokenizer.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonTokenizer.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonTokenizer.java Thu Dec  8 18:18:42 2011
@@ -0,0 +1,138 @@
+/*
+ * 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.json;
+
+import org.apache.jackrabbit.json.Token.Type;
+
+/**
+ * Abstract base class for JSON tokenizers.
+ * A JSON tokenizer breaks a stream of character into {@link Token}s. It has
+ * a current {@link #pos() position} and methods for inspecting, reading and
+ * skipping the token at the current position.
+ */
+public abstract class JsonTokenizer {
+
+    /**
+     * The current token which has been read ahead, if any.
+     * {@code null} otherwise.
+     */
+    protected Token currentToken;
+
+    /**
+     * Copy constructor. To be used in conjunction with {@link #copy()}
+     * @param tokenizer
+     */
+    protected JsonTokenizer(JsonTokenizer tokenizer) {
+        currentToken = tokenizer.currentToken;
+    }
+
+    protected JsonTokenizer() { }
+
+    /**
+     * Returns the current token without advancing the {@link #pos() position}
+     * @return  current token
+     */
+    public Token peek() {
+        if (currentToken == null) {
+            currentToken = nextToken();
+        }
+
+        return currentToken;
+    }
+
+    /**
+     * @param type
+     * @return  {@code true} if and only if the current token is of the given {@code type}
+     */
+    public boolean peek(Type type) {
+        return peek().type() == type;
+    }
+
+    /**
+     * Returns the current token and advances the {@link #pos() position}
+     * @return  current token
+     */
+    public Token read() {
+        if (currentToken == null) {
+            return nextToken();
+        }
+        else {
+            Token token = currentToken;
+            currentToken = null;
+            return token;
+        }
+    }
+
+    /**
+     * Returns the current token and advances the {@link #pos() position} if the token
+     * is of the given {@code type}.
+     * @param type
+     * @return  current token
+     * @throws ParseException  if the token is not of the given {@code type}.
+     */
+    public Token read(Type type) {
+        Token token = peek();
+        if (token.type() == type) {
+            return read();
+        }
+        else {
+            throw new ParseException(token.pos(), "Expected token type " + type + ", found: " + token); 
+        }
+    }
+
+    /**
+     * Advances the {@link #pos() position} if the token is of the given {@code type}.
+     * @param type
+     * @return  {@code true} if and only if the is token is of the given {@code type}.
+     */
+    public boolean skip(Type type) {
+        if (peek(type)) {
+            read();
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    /**
+     * @return the current position
+     */
+    public abstract int pos();
+
+    /**
+     * Set the current position
+     * @param pos
+     */
+    public abstract void setPos(int pos);
+
+    /**
+     * Create a copy of this tokenizer with the same state. Implementations usually
+     * create a new instance by calling the (overriden) {@link #JsonTokenizer(JsonTokenizer) copy constructor}.
+     * @return copy of this tokenizer
+     */
+    public abstract JsonTokenizer copy();
+
+    /**
+     * Read the next token from the input and advance the current {@link #pos() positon}.
+     * @return  next token
+     */
+    protected abstract Token nextToken();
+}

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonTokenizer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonTokenizer.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonValue.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonValue.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonValue.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonValue.java Thu Dec  8 18:18:42 2011
@@ -0,0 +1,515 @@
+/*
+ * 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.json;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * A {@code JsonValue} represents either an {@link JsonArray array}, an
+ * {@link JsonObject object} or a {@link JsonAtom primitive value} (atom)
+ * of a JSON document.
+ */
+public abstract class JsonValue {
+    public enum Type {
+        STRING(false),
+        NUMBER(false),
+        BOOLEAN(false),
+        NULL(false),
+        OBJECT(true),
+        ARRAY(true);
+
+        private final boolean compound;
+
+        Type(boolean compound) {
+            this.compound = compound;
+        }
+
+        /**
+         * @return {@code true} for {@link Type#ARRAY} and {@link Type#OBJECT},
+         * {@code false} otherwise.
+         */
+        public boolean compound() {
+            return compound;
+        }
+    }
+
+    /**
+     * Visitor for dispatching compound {@code JsonValue}s.
+     */
+    public abstract static class Visitor {
+        public void visit(JsonAtom atom) { }
+        public void visit(JsonArray array) { }
+        public void visit(JsonObject object) { }
+    }
+
+    /**
+     * Convert {@code jsonValue} to its JSON representation.
+     * @param jsonValue
+     * @return a JSON representation of {@code jsonValue}
+     */
+    public static String toJson(JsonValue jsonValue) {
+        final StringBuilder sb = new StringBuilder();
+        jsonValue.accept(new Visitor() {
+            @Override
+            public void visit(JsonAtom atom) {
+                sb.append(toJson(atom));
+            }
+
+            @Override
+            public void visit(JsonArray array) {
+                sb.append('[');
+                String comma = "";
+                for (JsonValue value : array.value()) {
+                    sb.append(comma);
+                    comma = ",";
+                    value.accept(this);
+                }
+                sb.append(']');
+            }
+
+            @Override
+            public void visit(JsonObject object) {
+                sb.append('{');
+                String comma = "";
+                for (Entry<String, JsonValue> entry : object.value().entrySet()) {
+                    sb.append(comma);
+                    comma = ",";
+                    sb.append(quote(entry.getKey())).append(':');
+                    entry.getValue().accept(this);
+                }
+                sb.append('}');
+            }
+        });
+        return sb.toString();
+    }
+
+    /**
+     * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters
+     * (U+0000 through U+001F) in {@code text}.
+     * @param text
+     * @return {@code text} with control characters escaped
+     */
+    public static String escape(String text) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < text.length(); i++) {
+            char ch = text.charAt(i);
+            switch (ch) {
+                case '"':
+                    sb.append("\\\"");
+                    break;
+                case '\\':
+                    sb.append("\\\\");
+                    break;
+                case '\b':
+                    sb.append("\\b");
+                    break;
+                case '\f':
+                    sb.append("\\f");
+                    break;
+                case '\n':
+                    sb.append("\\n");
+                    break;
+                case '\r':
+                    sb.append("\\r");
+                    break;
+                case '\t':
+                    sb.append("\\t");
+                    break;
+                default:
+                    //Reference: http://www.unicode.org/versions/Unicode5.1.0/
+                    if (ch >= '\u0000' && ch <= '\u001F' ||
+                        ch >= '\u007F' && ch <= '\u009F' ||
+                        ch >= '\u2000' && ch <= '\u20FF') {
+
+                        String ss = Integer.toHexString(ch);
+                        sb.append("\\u");
+                        for (int k = 0; k < 4 - ss.length(); k++) {
+                            sb.append('0');
+                        }
+                        sb.append(ss.toUpperCase());
+                    }
+                    else {
+                        sb.append(ch);
+                    }
+            }
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Unescape escaped control characters in {@code text}
+     * @param text
+     * @return {@code text} with control characters escaped
+     * @throws StringIndexOutOfBoundsException  on unterminated escape sequences
+     * @throws NumberFormatException  on invalid escape sequences
+     */
+    public static String unescape(String text) {
+        if (text.isEmpty()) {
+            return text;
+        }
+
+        StringBuilder sb = new StringBuilder();
+        for (int k = 0; k < text.length(); k++) {
+            char c = text.charAt(k);
+            if (c == '\\') {
+                c = text.charAt(++k);
+                switch (c) {
+                    case 'b':
+                        sb.append('\b');
+                        break;
+                    case 't':
+                        sb.append('\t');
+                        break;
+                    case 'n':
+                        sb.append('\n');
+                        break;
+                    case 'f':
+                        sb.append('\f');
+                        break;
+                    case 'r':
+                        sb.append('\r');
+                        break;
+                    case 'u':
+                        String u = text.substring(++k, k += 4);
+                        sb.append((char) Integer.parseInt(u, 16));
+                        break;
+                    case 'x':
+                        String x = text.substring(++k, k += 2);
+                        sb.append((char) Integer.parseInt(x, 16));
+                        break;
+                    default:
+                        sb.append(c);
+                }
+            }
+            else {
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * @return the value carried by this {@code JsonValue}
+     */
+    public abstract Object value();
+
+    /**
+     * @return the type of this {@code JsonValue}
+     */
+    public abstract Type type();
+
+    /**
+     * Dispatch this {@code JsonValue} using {@code visitor}
+     * @param visitor
+     */
+    public abstract void accept(Visitor visitor);
+
+    /**
+     * @return {@code this} as {@code JsonAtom}
+     * @throws UnsupportedOperationException if {@code this} is not an instance of {@code JsonAtom}
+     */
+    public JsonAtom asAtom() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @return {@code this} as {@code JsonArray}
+     * @throws UnsupportedOperationException if {@code this} is not an instance of {@code JsonArray}
+     */
+    public JsonArray asArray() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @return {@code this} as {@code JsonObject}
+     * @throws UnsupportedOperationException if {@code this} is not an instance of {@code JsonObject}
+     */
+    public JsonObject asObject() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Convert this {@code JsonValue} to its JSON representation.
+     * @return a JSON representation of this {@code JsonValue}
+     */
+    public String toJson() {
+        return toJson(this);
+    }
+
+    /**
+     * This class represents primitive JSON values (atoms). These are values of type
+     * {@link Type#STRING} {@link Type#NUMBER} {@link Type#BOOLEAN} and {@link Type#NULL}.
+     */
+    public static class JsonAtom extends JsonValue {
+        public static JsonAtom NULL = new JsonAtom("null", Type.NULL);
+        public static JsonAtom TRUE = new JsonAtom("true", Type.BOOLEAN);
+        public static JsonAtom FALSE = new JsonAtom("false", Type.BOOLEAN);
+
+        private final String value;
+        private final Type type;
+
+        public JsonAtom(String value, Type type) {
+            this.value = value;
+            this.type = type;
+        }
+
+        /**
+         * Create a new {@code JsonAtom} from {@code token}.
+         * @param token
+         * @throws IllegalArgumentException  if {@code token} does not represent
+         * an primitive type (atom).
+         */
+        public JsonAtom(Token token) {
+            this(token.text(), valueType(token.type()));
+        }
+
+        @Override
+        public JsonAtom asAtom() {
+            return this;
+        }
+
+        @Override
+        public String value() {
+            return value;
+        }
+
+        @Override
+        public Type type() {
+            return type;
+        }
+
+        @Override
+        public void accept(Visitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public String toString() {
+            return value + ": " + type;
+        }
+
+        @Override
+        public int hashCode() {
+            return 37 * (37 * (17 + value().hashCode()) + type().hashCode());
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other instanceof JsonAtom) {
+                JsonAtom that = (JsonAtom) other;
+                return that.value().equals(value()) && that.type() == type();
+            }
+            else {
+                return false;
+            }
+        }
+
+        //------------------------------------------< private >---
+
+        private static JsonValue.Type valueType(Token.Type type) {
+            switch (type) {
+                case TRUE:
+                case FALSE:
+                    return JsonValue.Type.BOOLEAN;
+                case NULL:
+                    return JsonValue.Type.NULL;
+                case STRING:
+                    return JsonValue.Type.STRING;
+                case NUMBER:
+                    return JsonValue.Type.NUMBER;
+                default:
+                    throw new IllegalArgumentException("Cannot map token type " + type + " to value type");
+            }
+        }
+    }
+
+    /**
+     * This class represents JSON arrays.
+     */
+    public static class JsonArray extends JsonValue {
+        public static JsonArray EMPTY = new JsonArray(Collections.<JsonValue>emptyList());
+        
+        private final List<JsonValue> values;
+
+        public JsonArray(List<JsonValue> values) {
+            this.values = values;
+        }
+
+        /**
+         * Append {@code value} to the end of this array.
+         * @param value
+         */
+        public void add(JsonValue value) {
+            values.add(value);
+        }
+
+        /**
+         * Removes a value from this array
+         * @param value
+         * @return  {@code true} iff the array contains {@code value}
+         */
+        public boolean remove(JsonValue value) {
+            return values.remove(value);
+        }
+
+        /**
+         * @param index
+         * @return the {@code JsonValue} at {@code index}.
+         * @throws IndexOutOfBoundsException  if {@code index} is out of range
+         */
+        public JsonValue get(int index) {
+            return values.get(index);
+        }
+
+        @Override
+        public JsonArray asArray() {
+            return this;
+        }
+
+        @Override
+        public List<JsonValue> value() {
+            return values;
+        }
+
+        @Override
+        public Type type() {
+            return Type.ARRAY;
+        }
+
+        @Override
+        public void accept(Visitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public String toString() {
+            return values.toString();
+        }
+
+        @Override
+        public int hashCode() {
+            return value().hashCode();
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other instanceof JsonArray) {
+                JsonArray that = (JsonArray) other;
+                return that.value().equals(value());
+            }
+            else {
+                return false;
+            }
+        }
+    }
+
+    /**
+     * This class represents JSON objects.
+     */
+    public static class JsonObject extends JsonValue {
+        public static final JsonObject EMPTY = new JsonObject(Collections.<String, JsonValue>emptyMap());
+
+        private final Map<String, JsonValue> values;
+
+        public JsonObject(Map<String, JsonValue> values) {
+            this.values = values;
+        }
+
+        /**
+         * Put {@code value} into this object
+         * @param key
+         * @param value
+         */
+        public void put(String key, JsonValue value) {
+            values.put(key, value);
+        }
+
+        /**
+         * @param key
+         * @return  the {@code JsonValue} identified by {@code key} or {@code null}
+         * if no value exists for {@code key}.
+         */
+        public JsonValue get(String key) {
+            return values.get(key);
+        }
+
+        public boolean isEmpty() {
+            return values.isEmpty();
+        }
+
+        @Override
+        public JsonObject asObject() {
+            return this;
+        }
+
+        @Override
+        public Map<String, JsonValue> value() {
+            return values;
+        }
+
+        @Override
+        public Type type() {
+            return Type.OBJECT;
+        }
+
+        @Override
+        public void accept(Visitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public String toString() {
+            return values.toString();
+        }
+
+        @Override
+        public int hashCode() {
+            return value().hashCode();
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other instanceof JsonObject) {
+                JsonObject that = (JsonObject) other;
+                return that.value().equals(value());
+            }
+            else {
+                return false;
+            }
+        }
+    }
+
+    //------------------------------------------< private >---
+
+    private static String toJson(JsonAtom atom) {
+        return atom.type() == Type.STRING
+            ? quote(escape(atom.value()))
+            : atom.value();
+    }
+
+    private static String quote(String text) {
+        return '\"' + text + '\"';
+    }
+
+}

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonValue.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsonValue.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopHandler.java?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopHandler.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopHandler.java Thu Dec  8 18:18:42 2011
@@ -0,0 +1,48 @@
+/*
+ * 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.json;
+
+public class JsopHandler {
+
+    public void add(Token path, JsonTokenizer value) {
+        new JsonParser(JsonHandler.INSTANCE).parseObject(value);
+    }
+
+    public void add(Token path, Token value) { }
+    public void add(Token path, Token[] values) { }
+    public void remove(Token path) { }
+    public void set(Token path, Token value) { }
+    public void set(Token path, Token[] values) { }
+    public void reorder(Token path, Token position, Token target) { }
+    public void move(Token path, Token target) { }
+    public void test(Token path, Token value) { }
+    public void test(Token path, Token[] values) { }
+
+    public void metaData(JsonTokenizer value) {
+        new JsonParser(JsonHandler.INSTANCE).parseObject(value);
+    }
+
+    public void extension(char op, Token path, JsonTokenizer value) {
+        new JsonParser(JsonHandler.INSTANCE).parseObject(value);
+    }
+
+    public void extension(char op, Token[] values) { }
+    public void extension(char op, Token value) { }
+}

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopHandler.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopHandler.java.orig
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopHandler.java.orig?rev=1212018&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopHandler.java.orig (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/json/JsopHandler.java.orig Thu Dec  8 18:18:42 2011
@@ -0,0 +1,35 @@
+/*
+ * 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 michid.jcr.json;
+
+public class JsopHandler {
+
+    public void add(Token path, JsonTokenizer value) {
+        new JsonParser(JsonHandler.INSTANCE).parseObject(value);
+    }
+
+    public void add(Token path, Token value) { }
+    public void add(Token path, Token[] values) { }
+    public void remove(Token path) { }
+    public void set(Token path, Token value) { }
+    public void set(Token path, Token[] values) { }
+    public void reorder(Token path, Token position, Token target) { }
+    public void move(Token path, Token target) { }
+}



Mime
View raw message