You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-dev@jackrabbit.apache.org by an...@apache.org on 2012/03/14 18:00:52 UTC

svn commit: r1300636 - in /jackrabbit/oak/trunk/oak-jcr: ./ src/main/java/org/apache/jackrabbit/oak/jcr/ src/main/java/org/apache/jackrabbit/oak/jcr/util/

Author: angela
Date: Wed Mar 14 17:00:52 2012
New Revision: 1300636

URL: http://svn.apache.org/viewvc?rev=1300636&view=rev
Log:
JCR-5: JCR bindings for Oak 

- implementation of some trivial parts and shortcuts

Added:
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/RepositoryImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/util/
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/util/LogUtil.java
Modified:
    jackrabbit/oak/trunk/oak-jcr/pom.xml

Modified: jackrabbit/oak/trunk/oak-jcr/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/pom.xml?rev=1300636&r1=1300635&r2=1300636&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-jcr/pom.xml Wed Mar 14 17:00:52 2012
@@ -40,18 +40,33 @@
       <version>2.0</version>
     </dependency>
 
-    <!-- Test dependencies -->
     <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
+      <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>jackrabbit-api</artifactId>
+      <version>2.4.0</version>
     </dependency>
     <dependency>
       <groupId>org.apache.jackrabbit</groupId>
       <artifactId>jackrabbit-jcr-commons</artifactId>
       <version>2.4.0</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>1.6.4</version>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <version>1.6.4</version>
+    </dependency>
+
+    <!-- Test dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
   </dependencies>
-
 </project>

Added: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java?rev=1300636&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java Wed Mar 14 17:00:52 2012
@@ -0,0 +1,184 @@
+/*
+ * 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.oak.jcr;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.Item;
+import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.Node;
+import javax.jcr.ReferentialIntegrityException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.ValueFactory;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.version.VersionException;
+
+/**
+ * <code>ItemImpl</code>...
+ */
+abstract class ItemImpl implements Item {
+
+    /**
+     * logger instance
+     */
+    private static final Logger log = LoggerFactory.getLogger(ItemImpl.class);
+
+    private final SessionImpl session = null;
+
+    @Override
+    public String getPath() throws RepositoryException {
+        // TODO
+        return null;
+    }
+
+    @Override
+    public String getName() throws RepositoryException {
+        // TODO
+        return null;
+    }
+
+    @Override
+    public Item getAncestor(int depth) throws ItemNotFoundException, AccessDeniedException, RepositoryException {
+        // TODO
+        return null;
+    }
+
+    @Override
+    public Node getParent() throws ItemNotFoundException, AccessDeniedException, RepositoryException {
+        // TODO
+        return null;
+    }
+
+    @Override
+    public int getDepth() throws RepositoryException {
+        // TODO
+        return 0;
+    }
+
+    @Override
+    public Session getSession() throws RepositoryException {
+        // TODO
+        return null;
+    }
+
+    @Override
+    public boolean isNew() {
+        // TODO
+        return false;
+    }
+
+    @Override
+    public boolean isModified() {
+        // TODO
+        return false;
+    }
+
+    /**
+     * @see Item#isSame(javax.jcr.Item)
+     */
+    @Override
+    public boolean isSame(Item otherItem) throws RepositoryException {
+        if (this == otherItem) {
+            return true;
+        }
+
+        // The objects are either both Node objects or both Property objects.
+        if (isNode() != otherItem.isNode()) {
+            return false;
+        }
+
+        // Test if both items belong to the same repository
+        // created by the same Repository object
+        if (!getSession().getRepository().equals(otherItem.getSession().getRepository())) {
+            return false;
+        }
+
+        // Both objects were acquired through Session objects bound to the same
+        // repository workspace.
+        if (!getSession().getWorkspace().getName().equals(otherItem.getSession().getWorkspace().getName())) {
+            return false;
+        }
+
+        if (isNode()) {
+            return ((Node) this).getIdentifier().equals(((Node) otherItem).getIdentifier());
+        } else {
+            return getName().equals(otherItem.getName()) && getParent().isSame(otherItem.getParent());
+        }
+    }
+
+    /**
+     * @see javax.jcr.Item#save()
+     */
+    @Override
+    public void save() throws AccessDeniedException, ItemExistsException, ConstraintViolationException, InvalidItemStateException, ReferentialIntegrityException, VersionException, LockException, NoSuchNodeTypeException, RepositoryException {
+        throw new UnsupportedRepositoryOperationException("Use Session#save");
+    }
+
+    /**
+     * @see Item#refresh(boolean)
+     */
+    @Override
+    public void refresh(boolean keepChanges) throws InvalidItemStateException, RepositoryException {
+        throw new UnsupportedRepositoryOperationException("Use Session#refresh");
+    }
+
+    @Override
+    public void remove() throws VersionException, LockException, ConstraintViolationException, AccessDeniedException, RepositoryException {
+        // TODO
+    }
+
+    //--------------------------------------------------------------------------
+    /**
+     * Performs a sanity check on this item and the associated session.
+     *
+     * @throws RepositoryException if this item has been rendered invalid for some reason
+     */
+    void checkStatus() throws RepositoryException {
+        // check session status
+        session.checkIsAlive();
+
+        // TODO: validate item state.
+    }
+
+    /**
+     * Checks if the associated session has pending changes.
+     *
+     * @throws InvalidItemStateException if this nodes session has pending changes
+     * @throws RepositoryException
+     */
+    void checkSessionHasPendingChanges() throws RepositoryException {
+        session.checkHasPendingChanges();
+    }
+
+    /**
+     * Returns the value factory associated with the editing session.
+     *
+     * @return the value factory
+     * @throws RepositoryException
+     */
+    ValueFactory getValueFactory() throws RepositoryException {
+        return session.getValueFactory();
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java?rev=1300636&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java Wed Mar 14 17:00:52 2012
@@ -0,0 +1,699 @@
+/*
+ * 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.oak.jcr;
+
+import org.apache.jackrabbit.oak.jcr.util.LogUtil;
+import org.apache.jackrabbit.value.ValueHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Binary;
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.InvalidLifecycleTransitionException;
+import javax.jcr.Item;
+import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.ItemVisitor;
+import javax.jcr.MergeException;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
+import javax.jcr.lock.Lock;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.nodetype.NodeDefinition;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.version.ActivityViolationException;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionException;
+import javax.jcr.version.VersionHistory;
+import javax.jcr.version.VersionManager;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.util.Calendar;
+
+/**
+ * <code>NodeImpl</code>...
+ */
+public class NodeImpl extends ItemImpl implements Node  {
+
+    /**
+     * logger instance
+     */
+    private static final Logger log = LoggerFactory.getLogger(NodeImpl.class);
+
+    //---------------------------------------------------------------< Item >---
+    /**
+     * @see javax.jcr.Item#isNode()
+     */
+    @Override
+    public boolean isNode() {
+        return true;
+    }
+
+    /**
+     * @see Item#accept(javax.jcr.ItemVisitor)
+     */
+    @Override
+    public void accept(ItemVisitor visitor) throws RepositoryException {
+        checkStatus();
+        visitor.visit(this);
+    }
+
+    //---------------------------------------------------------------< Node >---
+    /**
+     * @see Node#addNode(String)
+     */
+    @Override
+    public Node addNode(String relPath) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException {
+        return addNode(relPath, null);
+    }
+
+    @Override
+    public Node addNode(String relPath, String primaryNodeTypeName) throws ItemExistsException, PathNotFoundException, NoSuchNodeTypeException, LockException, VersionException, ConstraintViolationException, RepositoryException {
+        checkStatus();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public void orderBefore(String srcChildRelPath, String destChildRelPath) throws UnsupportedRepositoryOperationException, VersionException, ConstraintViolationException, ItemNotFoundException, LockException, RepositoryException {
+        checkStatus();
+
+        // TODO
+    }
+
+    /**
+     * @see Node#setProperty(String, javax.jcr.Value)
+     */
+    @Override
+    public Property setProperty(String name, Value value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        int type = PropertyType.UNDEFINED;
+        if (value != null) {
+            type = value.getType();
+        }
+        return setProperty(name, value, type);
+    }
+
+    /**
+     * @see Node#setProperty(String, javax.jcr.Value, int)
+     */
+    @Override
+    public Property setProperty(String name, Value value, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        checkStatus();
+
+        // TODO
+        return null;
+    }
+
+    /**
+     * @see Node#setProperty(String, javax.jcr.Value[])
+     */
+    @Override
+    public Property setProperty(String name, Value[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        int type;
+        if (values == null || values.length == 0 || values[0] == null) {
+            type = PropertyType.UNDEFINED;
+        } else {
+            type = values[0].getType();
+        }
+        return setProperty(name, values, type);
+    }
+
+    @Override
+    public Property setProperty(String name, Value[] values, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        checkStatus();
+
+        // TODO
+        return null;
+    }
+
+    /**
+     * @see Node#setProperty(String, String[])
+     */
+    @Override
+    public Property setProperty(String name, String[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        return setProperty(name, values, PropertyType.UNDEFINED);
+    }
+
+    /**
+     * @see Node#setProperty(String, String[], int)
+     */
+    @Override
+    public Property setProperty(String name, String[] values, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        Value[] vs;
+        if (type == PropertyType.UNDEFINED) {
+            vs = ValueHelper.convert(values, PropertyType.STRING, getValueFactory());
+        } else {
+            vs = ValueHelper.convert(values, type, getValueFactory());
+        }
+        return setProperty(name, vs, type);
+    }
+
+    /**
+     * @see Node#setProperty(String, String)
+     */
+    @Override
+    public Property setProperty(String name, String value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        Value v = (value == null) ? null : getValueFactory().createValue(value, PropertyType.STRING);
+        return setProperty(name, v, PropertyType.UNDEFINED);
+    }
+
+    /**
+     * @see Node#setProperty(String, String, int)
+     */
+    @Override
+    public Property setProperty(String name, String value, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        Value v = (value == null) ? null : getValueFactory().createValue(value, type);
+        return setProperty(name, v, type);
+    }
+
+    /**
+     * @see Node#setProperty(String, InputStream)
+     */
+    @Override
+    public Property setProperty(String name, InputStream value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        Value v = (value == null ? null : getValueFactory().createValue(value));
+        return setProperty(name, v, PropertyType.BINARY);
+    }
+
+    /**
+     * @see Node#setProperty(String, Binary)
+     */
+    @Override
+    public Property setProperty(String name, Binary value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        Value v = (value == null ? null : getValueFactory().createValue(value));
+        return setProperty(name, v, PropertyType.BINARY);
+    }
+
+    /**
+     * @see Node#setProperty(String, boolean)
+     */
+    @Override
+    public Property setProperty(String name, boolean value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        return setProperty(name, getValueFactory().createValue(value), PropertyType.BOOLEAN);
+
+    }
+
+    /**
+     * @see Node#setProperty(String, double)
+     */
+    @Override
+    public Property setProperty(String name, double value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        return setProperty(name, getValueFactory().createValue(value), PropertyType.DOUBLE);
+    }
+
+    /**
+     * @see Node#setProperty(String, BigDecimal)
+     */
+    @Override
+    public Property setProperty(String name, BigDecimal value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        Value v = (value == null ? null : getValueFactory().createValue(value));
+        return setProperty(name, v, PropertyType.DECIMAL);
+    }
+
+    /**
+     * @see Node#setProperty(String, long)
+     */
+    @Override
+    public Property setProperty(String name, long value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        return setProperty(name, getValueFactory().createValue(value), PropertyType.LONG);
+    }
+
+    /**
+     * @see Node#setProperty(String, Calendar)
+     */
+    @Override
+    public Property setProperty(String name, Calendar value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        Value v = (value == null ? null : getValueFactory().createValue(value));
+        return setProperty(name, v, PropertyType.DATE);
+    }
+
+    /**
+     * @see Node#setProperty(String, Node)
+     */
+    @Override
+    public Property setProperty(String name, Node value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        Value v = (value == null) ? null : getValueFactory().createValue(value);
+        return setProperty(name, v, PropertyType.REFERENCE);
+    }
+
+    @Override
+    public Node getNode(String relPath) throws PathNotFoundException, RepositoryException {
+        // TODO
+        return null;
+    }
+
+    @Override
+    public NodeIterator getNodes() throws RepositoryException {
+        checkStatus();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public NodeIterator getNodes(String namePattern) throws RepositoryException {
+        checkStatus();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public NodeIterator getNodes(String[] nameGlobs) throws RepositoryException {
+        checkStatus();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public Property getProperty(String relPath) throws PathNotFoundException, RepositoryException {
+        checkStatus();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public PropertyIterator getProperties() throws RepositoryException {
+        checkStatus();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public PropertyIterator getProperties(String namePattern) throws RepositoryException {
+        checkStatus();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public PropertyIterator getProperties(String[] nameGlobs) throws RepositoryException {
+        // TODO
+        return null;
+    }
+
+    /**
+     * @see javax.jcr.Node#getPrimaryItem()
+     */
+    @Override
+    public Item getPrimaryItem() throws ItemNotFoundException, RepositoryException {
+        checkStatus();
+        String name = getPrimaryNodeType().getPrimaryItemName();
+        if (name == null) {
+            throw new ItemNotFoundException("No primary item present on node " + LogUtil.safeGetJCRPath(this));
+        }
+        if (hasProperty(name)) {
+            return getProperty(name);
+        } else if (hasNode(name)) {
+            return getNode(name);
+        } else {
+            throw new ItemNotFoundException("Primary item " + name + " does not exist on node " + LogUtil.safeGetJCRPath(this));
+        }
+    }
+
+    @Override
+    public String getUUID() throws UnsupportedRepositoryOperationException, RepositoryException {
+        checkStatus();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public String getIdentifier() throws RepositoryException {
+        checkStatus();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public int getIndex() throws RepositoryException {
+        // TODO
+        return 0;
+    }
+
+    /**
+     * @see javax.jcr.Node#getReferences()
+     */
+    @Override
+    public PropertyIterator getReferences() throws RepositoryException {
+        return getReferences(null);
+    }
+
+    @Override
+    public PropertyIterator getReferences(String name) throws RepositoryException {
+        checkStatus();
+
+        // TODO
+        return null;
+    }
+
+    /**
+     * @see javax.jcr.Node#getWeakReferences()
+     */
+    @Override
+    public PropertyIterator getWeakReferences() throws RepositoryException {
+        return getWeakReferences(null);
+    }
+
+    @Override
+    public PropertyIterator getWeakReferences(String name) throws RepositoryException {
+        checkStatus();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public boolean hasNode(String relPath) throws RepositoryException {
+        checkStatus();
+
+        // TODO
+        return false;
+    }
+
+    @Override
+    public boolean hasProperty(String relPath) throws RepositoryException {
+        checkStatus();
+
+        // TODO
+        return false;
+    }
+
+    @Override
+    public boolean hasNodes() throws RepositoryException {
+        checkStatus();
+
+        // TODO
+        return false;
+    }
+
+    @Override
+    public boolean hasProperties() throws RepositoryException {
+        checkStatus();
+
+        // TODO
+        return false;
+    }
+
+    @Override
+    public NodeType getPrimaryNodeType() throws RepositoryException {
+        checkStatus();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public NodeType[] getMixinNodeTypes() throws RepositoryException {
+        checkStatus();
+
+        // TODO
+        return new NodeType[0];
+    }
+
+    @Override
+    public boolean isNodeType(String nodeTypeName) throws RepositoryException {
+        checkStatus();
+
+        // TODO
+        return false;
+    }
+
+    @Override
+    public void setPrimaryType(String nodeTypeName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
+        checkStatus();
+
+        // TODO
+
+    }
+
+    @Override
+    public void addMixin(String mixinName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
+        checkStatus();
+
+        // TODO
+    }
+
+    @Override
+    public void removeMixin(String mixinName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
+        checkStatus();
+
+        // TODO
+    }
+
+    @Override
+    public boolean canAddMixin(String mixinName) throws NoSuchNodeTypeException, RepositoryException {
+        // TODO
+        return false;
+    }
+
+    @Override
+    public NodeDefinition getDefinition() throws RepositoryException {
+        checkStatus();
+
+        // TODO
+        return null;
+    }
+
+
+    @Override
+    public String getCorrespondingNodePath(String workspaceName) throws ItemNotFoundException, NoSuchWorkspaceException, AccessDeniedException, RepositoryException {
+        checkStatus();
+
+        // TODO
+        return null;
+    }
+
+
+    @Override
+    public void update(String srcWorkspace) throws NoSuchWorkspaceException, AccessDeniedException, LockException, InvalidItemStateException, RepositoryException {
+        checkStatus();
+        checkSessionHasPendingChanges();
+
+        // TODO
+
+    }
+
+    /**
+     * @see javax.jcr.Node#checkin()
+     */
+    @Override
+    public Version checkin() throws VersionException, UnsupportedRepositoryOperationException, InvalidItemStateException, LockException, RepositoryException {
+        return getVersionManager().checkin(getPath());
+    }
+
+    /**
+     * @see javax.jcr.Node#checkout()
+     */
+    @Override
+    public void checkout() throws UnsupportedRepositoryOperationException, LockException, ActivityViolationException, RepositoryException {
+        getVersionManager().checkout(getPath());
+    }
+
+    /**
+     * @see javax.jcr.Node#doneMerge(javax.jcr.version.Version)
+     */
+    @Override
+    public void doneMerge(Version version) throws VersionException, InvalidItemStateException, UnsupportedRepositoryOperationException, RepositoryException {
+        getVersionManager().doneMerge(getPath(), version);
+    }
+
+    /**
+     * @see javax.jcr.Node#cancelMerge(javax.jcr.version.Version)
+     */
+    @Override
+    public void cancelMerge(Version version) throws VersionException, InvalidItemStateException, UnsupportedRepositoryOperationException, RepositoryException {
+        getVersionManager().cancelMerge(getPath(), version);
+    }
+
+    /**
+     * @see javax.jcr.Node#merge(String, boolean)
+     */
+    @Override
+    public NodeIterator merge(String srcWorkspace, boolean bestEffort) throws NoSuchWorkspaceException, AccessDeniedException, MergeException, LockException, InvalidItemStateException, RepositoryException {
+        return getVersionManager().merge(getPath(), srcWorkspace, bestEffort);
+    }
+
+    /**
+     * @see javax.jcr.Node#isCheckedOut()
+     */
+    @Override
+    public boolean isCheckedOut() throws RepositoryException {
+        return getSession().getWorkspace().getVersionManager().isCheckedOut(getPath());
+    }
+
+    /**
+     * @see javax.jcr.Node#restore(String, boolean)
+     */
+    @Override
+    public void restore(String versionName, boolean removeExisting) throws VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
+        getSession().getWorkspace().getVersionManager().restore(getPath(), versionName, removeExisting);
+    }
+
+    /**
+     * @see javax.jcr.Node#restore(javax.jcr.version.Version, boolean)
+     */
+    @Override
+    public void restore(Version version, boolean removeExisting) throws VersionException, ItemExistsException, InvalidItemStateException, UnsupportedRepositoryOperationException, LockException, RepositoryException {
+        getSession().getWorkspace().getVersionManager().restore(version, removeExisting);
+    }
+
+    /**
+     * @see javax.jcr.Node#restore(Version, String, boolean)
+     */
+    @Override
+    public void restore(Version version, String relPath, boolean removeExisting) throws PathNotFoundException, ItemExistsException, VersionException, ConstraintViolationException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
+        // additional checks are performed with subsequent calls.
+        if (hasNode(relPath)) {
+            // node at 'relPath' exists -> call restore on the target Node
+            getNode(relPath).restore(version, removeExisting);
+        } else {
+            // TODO
+        }
+    }
+
+    /**
+     * @see javax.jcr.Node#restoreByLabel(String, boolean)
+     */
+    @Override
+    public void restoreByLabel(String versionLabel, boolean removeExisting) throws VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
+        getVersionManager().restoreByLabel(getPath(), versionLabel, removeExisting);
+    }
+
+    /**
+     * @see javax.jcr.Node#getVersionHistory()
+     */
+    @Override
+    public VersionHistory getVersionHistory() throws UnsupportedRepositoryOperationException, RepositoryException {
+        return getVersionManager().getVersionHistory(getPath());
+    }
+
+    /**
+     * @see javax.jcr.Node#getBaseVersion()
+     */
+    @Override
+    public Version getBaseVersion() throws UnsupportedRepositoryOperationException, RepositoryException {
+        return getVersionManager().getBaseVersion(getPath());
+    }
+
+    /**
+     * @see javax.jcr.Node#lock(boolean, boolean)
+     */
+    @Override
+    public Lock lock(boolean isDeep, boolean isSessionScoped) throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, InvalidItemStateException, RepositoryException {
+        return getSession().getWorkspace().getLockManager().lock(getPath(), isDeep, isSessionScoped, Long.MAX_VALUE, null);
+    }
+
+    /**
+     * @see javax.jcr.Node#getLock()
+     */
+    @Override
+    public Lock getLock() throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, RepositoryException {
+        return getSession().getWorkspace().getLockManager().getLock(getPath());
+    }
+
+    /**
+     * @see javax.jcr.Node#unlock()
+     */
+    @Override
+    public void unlock() throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, InvalidItemStateException, RepositoryException {
+        getSession().getWorkspace().getLockManager().unlock(getPath());
+    }
+
+    /**
+     * @see javax.jcr.Node#holdsLock()
+     */
+    @Override
+    public boolean holdsLock() throws RepositoryException {
+        return getSession().getWorkspace().getLockManager().holdsLock(getPath());
+    }
+
+    /**
+     * @see javax.jcr.Node#isLocked() ()
+     */
+    @Override
+    public boolean isLocked() throws RepositoryException {
+        return getSession().getWorkspace().getLockManager().isLocked(getPath());
+    }
+
+
+    @Override
+    public NodeIterator getSharedSet() throws RepositoryException {
+        // TODO
+        return null;
+    }
+
+    @Override
+    public void removeSharedSet() throws VersionException, LockException, ConstraintViolationException, RepositoryException {
+        // TODO
+
+    }
+
+    @Override
+    public void removeShare() throws VersionException, LockException, ConstraintViolationException, RepositoryException {
+        // TODO
+
+    }
+
+    /**
+     * @see javax.jcr.Node#followLifecycleTransition() ()
+     */
+    @Override
+    public void followLifecycleTransition(String transition) throws UnsupportedRepositoryOperationException, InvalidLifecycleTransitionException, RepositoryException {
+        throw new UnsupportedRepositoryOperationException("Lifecycle Management is not supported");
+    }
+
+    /**
+     * @see javax.jcr.Node#getAllowedLifecycleTransistions() ()
+     */
+    @Override
+    public String[] getAllowedLifecycleTransistions() throws UnsupportedRepositoryOperationException, RepositoryException {
+        throw new UnsupportedRepositoryOperationException("Lifecycle Management is not supported");
+
+    }
+
+    //------------------------------------------------------------< private >---
+    /**
+     * Shortcut to retrieve the version manager from the workspace associated
+     * with the editing session.
+     *
+     * @return the version manager associated with the editing session.
+     * @throws RepositoryException
+     */
+    private VersionManager getVersionManager() throws RepositoryException {
+        return getSession().getWorkspace().getVersionManager();
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java?rev=1300636&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java Wed Mar 14 17:00:52 2012
@@ -0,0 +1,500 @@
+/*
+ * 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.oak.jcr;
+
+import org.apache.jackrabbit.oak.jcr.util.LogUtil;
+import org.apache.jackrabbit.value.ValueHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.Binary;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.ItemVisitor;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.PropertyDefinition;
+import javax.jcr.version.VersionException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.util.Calendar;
+
+/**
+ * <code>PropertyImpl</code>...
+ */
+public class PropertyImpl extends ItemImpl implements Property {
+
+    /**
+     * logger instance
+     */
+    private static final Logger log = LoggerFactory.getLogger(PropertyImpl.class);
+
+
+    //---------------------------------------------------------------< Item >---
+    /**
+     * @see javax.jcr.Item#isNode()
+     */
+    @Override
+    public boolean isNode() {
+        return false;
+    }
+
+    /**
+     * @see javax.jcr.Item#accept(javax.jcr.ItemVisitor)
+     */
+    @Override
+    public void accept(ItemVisitor visitor) throws RepositoryException {
+        checkStatus();
+        visitor.visit(this);
+    }
+
+    //-----------------------------------------------------------< Property >---
+    /**
+     * @see Property#setValue(Value)
+     */
+    @Override
+    public void setValue(Value value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        checkStatus();
+
+        int valueType = (value != null) ? value.getType() : PropertyType.UNDEFINED;
+        int reqType = getRequiredType(valueType);
+        setValue(value, reqType);
+    }
+
+    /**
+     * @see Property#setValue(Value[])
+     */
+    @Override
+    public void setValue(Value[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        checkStatus();
+
+        // assert equal types for all values entries
+        int valueType = PropertyType.UNDEFINED;
+        if (values != null) {
+            for (int i = 0; i < values.length; i++) {
+                if (values[i] == null) {
+                    // skip null values as those will be purged later
+                    continue;
+                }
+                if (valueType == PropertyType.UNDEFINED) {
+                    valueType = values[i].getType();
+                } else if (valueType != values[i].getType()) {
+                    String msg = "Inhomogeneous type of values (" + LogUtil.safeGetJCRPath(this) + ")";
+                    log.debug(msg);
+                    throw new ValueFormatException(msg);
+                }
+            }
+        }
+
+        int reqType = getRequiredType(valueType);
+        setValues(values, reqType);
+    }
+
+    /**
+     * @see Property#setValue(String)
+     */
+    @Override
+    public void setValue(String value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        checkStatus();
+
+        int reqType = getRequiredType(PropertyType.STRING);
+        if (value == null) {
+            setValue(null, reqType);
+        } else {
+            setValue(getValueFactory().createValue(value), reqType);
+        }
+    }
+
+    /**
+     * @see Property#setValue(String[])
+     */
+    @Override
+    public void setValue(String[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        checkStatus();
+
+        int reqType = getRequiredType(PropertyType.STRING);
+        Value[] vs;
+        if (values == null) {
+            vs = null;
+        } else {
+            vs = new Value[values.length];
+            for (int i = 0; i < values.length; i++) {
+                vs[i] = getValueFactory().createValue(values[i]);
+            }
+        }
+        setValues(vs, reqType);
+    }
+
+    /**
+     * @see Property#setValue(InputStream)
+     */
+    @Override
+    public void setValue(InputStream value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        checkStatus();
+
+        int reqType = getRequiredType(PropertyType.BINARY);
+        if (value == null) {
+            setValue(null, reqType);
+        } else {
+            setValue(getValueFactory().createValue(value), reqType);
+        }
+    }
+
+    /**
+     * @see Property#setValue(Binary)
+     */
+    @Override
+    public void setValue(Binary value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        checkStatus();
+
+        int reqType = getRequiredType(PropertyType.BINARY);
+        if (value == null) {
+            setValue(null, reqType);
+        } else {
+            setValue(getValueFactory().createValue(value), reqType);
+        }
+    }
+
+    /**
+     * @see Property#setValue(long)
+     */
+    @Override
+    public void setValue(long value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        checkStatus();
+
+        int reqType = getRequiredType(PropertyType.LONG);
+        setValue(getValueFactory().createValue(value), reqType);
+    }
+
+    /**
+     * @see Property#setValue(double)
+     */
+    @Override
+    public void setValue(double value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        checkStatus();
+
+        int reqType = getRequiredType(PropertyType.DOUBLE);
+        setValue(getValueFactory().createValue(value), reqType);
+    }
+
+    /**
+     * @see Property#setValue(BigDecimal)
+     */
+    @Override
+    public void setValue(BigDecimal value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        checkStatus();
+
+        int reqType = getRequiredType(PropertyType.DECIMAL);
+        setValue(getValueFactory().createValue(value), reqType);
+    }
+
+    /**
+     * @see Property#setValue(Calendar)
+     */
+    @Override
+    public void setValue(Calendar value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        checkStatus();
+
+        int reqType = getRequiredType(PropertyType.DATE);
+        if (value == null) {
+            setValue(null, reqType);
+        } else {
+            setValue(getValueFactory().createValue(value), reqType);
+        }
+    }
+
+    /**
+     * @see Property#setValue(boolean)
+     */
+    @Override
+    public void setValue(boolean value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        checkStatus();
+
+        int reqType = getRequiredType(PropertyType.BOOLEAN);
+        setValue(getValueFactory().createValue(value), reqType);
+    }
+
+    /**
+     * @see Property#setValue(javax.jcr.Node)
+     */
+    @Override
+    public void setValue(Node value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+        checkStatus();
+
+        int reqType = getRequiredType(PropertyType.REFERENCE);
+        if (value == null) {
+            setValue(null, reqType);
+        } else {
+            setValue(getValueFactory().createValue(value), reqType);
+        }
+    }
+
+    @Override
+    public Value getValue() throws ValueFormatException, RepositoryException {
+        checkStatus();
+        if (isMultiple()) {
+            throw new ValueFormatException(LogUtil.safeGetJCRPath(this) + " is multi-valued.");
+        }
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public Value[] getValues() throws ValueFormatException, RepositoryException {
+        checkStatus();
+        if (!isMultiple()) {
+            throw new ValueFormatException(LogUtil.safeGetJCRPath(this) + " is not multi-valued.");
+        }
+
+        // TODO
+        return new Value[0];
+    }
+
+    /**
+     * @see Property#getString()
+     */
+    @Override
+    public String getString() throws ValueFormatException, RepositoryException {
+        return getValue().getString();
+    }
+
+    /**
+     * @see Property#getStream()
+     */
+    @Override
+    public InputStream getStream() throws ValueFormatException, RepositoryException {
+        return getValue().getStream();
+    }
+
+    /**
+     * @see javax.jcr.Property#getBinary()
+     */
+    @Override
+    public Binary getBinary() throws ValueFormatException, RepositoryException {
+        return getValue().getBinary();
+    }
+
+    /**
+     * @see Property#getLong()
+     */
+    @Override
+    public long getLong() throws ValueFormatException, RepositoryException {
+        return getValue().getLong();
+    }
+
+    /**
+     * @see Property#getDouble()
+     */
+    @Override
+    public double getDouble() throws ValueFormatException, RepositoryException {
+        return getValue().getDouble();
+    }
+
+    /**
+     * @see Property#getDecimal()
+     */
+    @Override
+    public BigDecimal getDecimal() throws ValueFormatException, RepositoryException {
+        return getValue().getDecimal();
+    }
+
+    /**
+     * @see Property#getDate()
+     */
+    @Override
+    public Calendar getDate() throws ValueFormatException, RepositoryException {
+        return getValue().getDate();
+    }
+
+    /**
+     * @see Property#getBoolean()
+     */
+    @Override
+    public boolean getBoolean() throws ValueFormatException, RepositoryException {
+        return getValue().getBoolean();
+    }
+
+    /**
+     * @see javax.jcr.Property#getNode()
+     */
+    @Override
+    public Node getNode() throws ItemNotFoundException, ValueFormatException, RepositoryException {
+        Value value = getValue();
+        switch (value.getType()) {
+            case PropertyType.REFERENCE:
+            case PropertyType.WEAKREFERENCE:
+                return getSession().getNodeByIdentifier(value.getString());
+
+            case PropertyType.PATH:
+            case PropertyType.NAME:
+                String path = value.getString();
+                try {
+                    return (path.charAt(0) == '/') ? getSession().getNode(path) : getParent().getNode(path);
+                } catch (PathNotFoundException e) {
+                    throw new ItemNotFoundException(path);
+                }
+
+            case PropertyType.STRING:
+                try {
+                    Value refValue = ValueHelper.convert(value, PropertyType.REFERENCE, getValueFactory());
+                    return getSession().getNodeByIdentifier(refValue.getString());
+                } catch (ItemNotFoundException e) {
+                    throw e;
+                } catch (RepositoryException e) {
+                    // try if STRING value can be interpreted as PATH value
+                    Value pathValue = ValueHelper.convert(value, PropertyType.PATH, getValueFactory());
+                    path = pathValue.getString();
+                    try {
+                        return (path.charAt(0) == '/') ? getSession().getNode(path) : getParent().getNode(path);
+                    } catch (PathNotFoundException e1) {
+                        throw new ItemNotFoundException(pathValue.getString());
+                    }
+                }
+
+            default:
+                throw new ValueFormatException("Property value cannot be converted to a PATH, REFERENCE or WEAKREFERENCE");
+        }
+    }
+
+    /**
+     * @see javax.jcr.Property#getProperty()
+     */
+    @Override
+    public Property getProperty() throws ItemNotFoundException, ValueFormatException, RepositoryException {
+        Value value = getValue();
+        Value pathValue = ValueHelper.convert(value, PropertyType.PATH, getValueFactory());
+        String path = pathValue.getString();
+        try {
+            return (path.charAt(0) == '/') ? getSession().getProperty(path) : getParent().getProperty(path);
+        } catch (PathNotFoundException e) {
+            throw new ItemNotFoundException(path);
+        }
+    }
+
+    /**
+     * @see javax.jcr.Property#getLength()
+     */
+    @Override
+    public long getLength() throws ValueFormatException, RepositoryException {
+        return getLength(getValue());
+    }
+
+    /**
+     * @see javax.jcr.Property#getLengths()
+     */
+    @Override
+    public long[] getLengths() throws ValueFormatException, RepositoryException {
+        Value[] values = getValues();
+        long[] lengths = new long[values.length];
+
+        for (int i = 0; i < values.length; i++) {
+            lengths[i] = getLength(values[i]);
+        }
+        return lengths;
+    }
+
+    @Override
+    public PropertyDefinition getDefinition() throws RepositoryException {
+        // TODO
+        return null;
+    }
+
+    @Override
+    public int getType() throws RepositoryException {
+        // TODO
+        return 0;
+    }
+
+    @Override
+    public boolean isMultiple() throws RepositoryException {
+        // TODO
+        return false;
+    }
+
+    //------------------------------------------------------------< private >---
+
+    /**
+     *
+     * @param defaultType
+     * @return the required type for this property.
+     */
+    private int getRequiredType(int defaultType) throws RepositoryException {
+        // check type according to definition of this property
+        int reqType = getDefinition().getRequiredType();
+        if (reqType == PropertyType.UNDEFINED) {
+            if (defaultType == PropertyType.UNDEFINED) {
+                reqType = PropertyType.STRING;
+            } else {
+                reqType = defaultType;
+            }
+        }
+        return reqType;
+    }
+
+    /**
+     *
+     * @param value
+     * @param requiredType
+     * @throws RepositoryException
+     */
+    private void setValue(Value value, int requiredType) throws RepositoryException {
+        if (requiredType == PropertyType.UNDEFINED) {
+            // should never get here since calling methods assert valid type
+            throw new IllegalArgumentException("Property type of a value cannot be undefined (" + LogUtil.safeGetJCRPath(this) + ").");
+        }
+
+        // TODO -> set value on the property state and remember operation.
+    }
+
+    /**
+     *
+     * @param values
+     * @param requiredType
+     * @throws RepositoryException
+     */
+    private void setValues(Value[] values, int requiredType) throws RepositoryException {
+        if (requiredType == PropertyType.UNDEFINED) {
+            // should never get here since calling methods assert valid type
+            throw new IllegalArgumentException("Property type of a value cannot be undefined (" + LogUtil.safeGetJCRPath(this) + ").");
+        }
+
+        // TODO -> internal set values to the property and remember operation
+    }
+
+    /**
+     * Return the length of the specified JCR value object.
+     *
+     * @param value The value.
+     * @return The length of the given value.
+     * @throws RepositoryException If an error occurs.
+     */
+    private static long getLength(Value value) throws RepositoryException {
+        if (value.getType() == PropertyType.BINARY) {
+            return value.getBinary().getSize();
+        }
+        else {
+            return value.getString().length();
+        }
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/RepositoryImpl.java?rev=1300636&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/RepositoryImpl.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/RepositoryImpl.java Wed Mar 14 17:00:52 2012
@@ -0,0 +1,119 @@
+/*
+ * 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.oak.jcr;
+
+import org.apache.jackrabbit.commons.AbstractRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.Credentials;
+import javax.jcr.LoginException;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * <code>RepositoryImpl</code>...
+ */
+public class RepositoryImpl extends AbstractRepository {
+
+    /**
+     * logger instance
+     */
+    private static final Logger log = LoggerFactory.getLogger(RepositoryImpl.class);
+
+    private Map<String, Value[]> descriptors;
+
+    //---------------------------------------------------------< Repository >---
+    /**
+     * @see javax.jcr.Repository#getDescriptorKeys()
+     */
+    @Override
+    public String[] getDescriptorKeys() {
+        Set<String> keys = getDescriptors().keySet();
+        return keys.toArray(new String[keys.size()]);
+    }
+
+    /**
+     * @see javax.jcr.Repository#getDescriptor(String)
+     */
+    @Override
+    public String getDescriptor(String key) {
+        Value v = getDescriptorValue(key);
+        try {
+            return (v == null) ? null : v.getString();
+        } catch (RepositoryException e) {
+            log.error("corrupt descriptor value: " + key, e);
+            return null;
+        }
+    }
+
+    /**
+     * @see javax.jcr.Repository#getDescriptorValue(String)
+     */
+    @Override
+    public Value getDescriptorValue(String key) {
+        Value[] vs = getDescriptorValues(key);
+        return (vs == null || vs.length != 1) ? null : vs[0];
+    }
+
+    /**
+     * @see javax.jcr.Repository#getDescriptorValues(String)
+     */
+    @Override
+    public Value[] getDescriptorValues(String key) {
+        Map<String, Value[]> descriptors = getDescriptors();
+        if (descriptors.containsKey(key)) {
+            return descriptors.get(key);
+        } else {
+            return null;
+
+        }
+    }
+
+    /**
+     * @see javax.jcr.Repository#isSingleValueDescriptor(String)
+     */
+    @Override
+    public boolean isSingleValueDescriptor(String key) {
+        Value[] vs = getDescriptors().get(key);
+        return (vs != null && vs.length == 1);
+    }
+
+    /**
+     * @see javax.jcr.Repository#login(javax.jcr.Credentials, String)
+     */
+    @Override
+    public Session login(Credentials credentials, String workspaceName) throws LoginException, NoSuchWorkspaceException, RepositoryException {
+        // TODO -> SPI
+        return null;
+    }
+
+    //------------------------------------------------------------< private >---
+    /**
+     * Returns the descriptor map.
+     *
+     * @return the descriptor map.
+     */
+    private Map<String, Value[]> getDescriptors() {
+        // TODO
+        return null;
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java?rev=1300636&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java Wed Mar 14 17:00:52 2012
@@ -0,0 +1,351 @@
+/*
+ * 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.oak.jcr;
+
+import org.apache.jackrabbit.commons.AbstractSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.ContentHandler;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.ReferentialIntegrityException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.ValueFactory;
+import javax.jcr.Workspace;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.retention.RetentionManager;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.version.VersionException;
+import java.security.AccessControlException;
+
+/**
+ * <code>SessionImpl</code>...
+ */
+public class SessionImpl extends AbstractSession {
+
+    /**
+     * logger instance
+     */
+    private static final Logger log = LoggerFactory.getLogger(SessionImpl.class);
+
+    private final Repository repository = null;
+    private final Workspace workspace = null;
+    private final ValueFactory valueFactory = null;
+
+    private boolean isAlive;
+
+    //------------------------------------------------------------< Session >---
+    @Override
+    public Repository getRepository() {
+        return repository;
+    }
+
+    @Override
+    public String getUserID() {
+        // TODO
+        return null;
+    }
+
+    @Override
+    public String[] getAttributeNames() {
+        // TODO
+        return new String[0];
+    }
+
+    @Override
+    public Object getAttribute(String name) {
+        // TODO
+        return null;
+    }
+
+    @Override
+    public Workspace getWorkspace() {
+        return workspace;
+    }
+
+    @Override
+    public Node getRootNode() throws RepositoryException {
+        checkIsAlive();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public Node getNodeByUUID(String uuid) throws ItemNotFoundException, RepositoryException {
+        checkIsAlive();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public Node getNodeByIdentifier(String id) throws ItemNotFoundException, RepositoryException {
+        checkIsAlive();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public void move(String srcAbsPath, String destAbsPath) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException {
+        checkIsAlive();
+
+        // TODO
+
+    }
+
+    @Override
+    public void save() throws AccessDeniedException, ItemExistsException, ReferentialIntegrityException, ConstraintViolationException, InvalidItemStateException, VersionException, LockException, NoSuchNodeTypeException, RepositoryException {
+        checkIsAlive();
+
+        // TODO
+
+    }
+
+    @Override
+    public void refresh(boolean keepChanges) throws RepositoryException {
+        checkIsAlive();
+
+        // TODO
+
+    }
+
+    @Override
+    public boolean hasPendingChanges() throws RepositoryException {
+        checkIsAlive();
+
+        // TODO
+        return false;
+    }
+
+    @Override
+    public ValueFactory getValueFactory() throws UnsupportedRepositoryOperationException, RepositoryException {
+        checkIsAlive();
+        return valueFactory;
+    }
+
+    @Override
+    public boolean hasPermission(String absPath, String actions) throws RepositoryException {
+        checkIsAlive();
+
+        // TODO
+        return false;
+    }
+
+    @Override
+    public void checkPermission(String absPath, String actions) throws AccessControlException, RepositoryException {
+        if (!hasPermission(absPath, actions)) {
+            throw new AccessControlException("Access control violation: path = " + absPath + ", actions = " + actions);
+        }
+    }
+
+    @Override
+    public boolean hasCapability(String methodName, Object target, Object[] arguments) throws RepositoryException {
+        checkIsAlive();
+
+        // TODO
+        return false;
+    }
+
+    @Override
+    public ContentHandler getImportContentHandler(String parentAbsPath, int uuidBehavior) throws PathNotFoundException, ConstraintViolationException, VersionException, LockException, RepositoryException {
+        checkIsAlive();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public boolean isLive() {
+        return isAlive;
+    }
+
+
+    @Override
+    public void logout() {
+        if (!isAlive) {
+            // ignore
+            return;
+        }
+
+        // TODO
+    }
+
+    @Override
+    public void addLockToken(String lt) {
+        try {
+            getWorkspace().getLockManager().addLockToken(lt);
+        } catch (RepositoryException e) {
+            log.warn("Unable to add lock token '" +lt+ "' to this session.", e);
+        }
+    }
+
+    @Override
+    public String[] getLockTokens() {
+        try {
+            return getWorkspace().getLockManager().getLockTokens();
+        } catch (RepositoryException e) {
+            log.warn("Unable to retrieve lock tokens for this session. (" + e.getMessage() + ")");
+            return new String[0];        }
+    }
+
+    @Override
+    public void removeLockToken(String lt) {
+        try {
+            getWorkspace().getLockManager().addLockToken(lt);
+        } catch (RepositoryException e) {
+            log.warn("Unable to add lock token '" +lt+ "' to this session.", e);
+        }
+    }
+
+    @Override
+    public AccessControlManager getAccessControlManager() throws UnsupportedRepositoryOperationException, RepositoryException {
+        checkIsAlive();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public RetentionManager getRetentionManager() throws UnsupportedRepositoryOperationException, RepositoryException {
+        throw new UnsupportedRepositoryOperationException("Retention Management is not supported.");
+    }
+
+    //------------------------------------------------------< check methods >---
+    /**
+     * Performs a sanity check on this session.
+     *
+     * @throws RepositoryException if this session has been rendered invalid
+     * for some reason (e.g. if this session has been closed explicitly by logout)
+     */
+    void checkIsAlive() throws RepositoryException {
+        // check session status
+        if (!isAlive) {
+            throw new RepositoryException("This session has been closed.");
+        }
+    }
+
+    /**
+     * Returns true if the repository supports the given option. False otherwise.
+     *
+     * @param option Any of the option constants defined by {@link Repository}
+     * that either returns 'true' or 'false'. I.e.
+     * <ul>
+     * <li>{@link Repository#LEVEL_1_SUPPORTED}</li>
+     * <li>{@link Repository#LEVEL_2_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_ACCESS_CONTROL_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_ACTIVITIES_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_BASELINES_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_JOURNALED_OBSERVATION_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_LIFECYCLE_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_LOCKING_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_NODE_AND_PROPERTY_WITH_SAME_NAME_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_NODE_TYPE_MANAGEMENT_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_OBSERVATION_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_QUERY_SQL_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_RETENTION_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_SHAREABLE_NODES_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_SIMPLE_VERSIONING_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_TRANSACTIONS_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_UNFILED_CONTENT_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_UPDATE_MIXIN_NODE_TYPES_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_UPDATE_PRIMARY_NODE_TYPE_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_VERSIONING_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_WORKSPACE_MANAGEMENT_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_XML_EXPORT_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_XML_IMPORT_SUPPORTED}</li>
+     * <li>{@link Repository#WRITE_SUPPORTED}</li>
+     * </ul>
+     * @return true if the repository supports the given option. False otherwise.
+     */
+    boolean isSupportedOption(String option) {
+        String desc = repository.getDescriptor(option);
+        // if the descriptors are not available return true. the missing
+        // functionality of the given SPI impl will in this case be detected
+        // upon the corresponding SPI call (see JCR-3143).
+        return (desc == null) ? true : Boolean.valueOf(desc);
+    }
+
+    /**
+     * Make sure the repository supports the option indicated by the given string.
+     *
+     * @param option Any of the option constants defined by {@link Repository}
+     * that either returns 'true' or 'false'. I.e.
+     * <ul>
+     * <li>{@link Repository#LEVEL_1_SUPPORTED}</li>
+     * <li>{@link Repository#LEVEL_2_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_ACCESS_CONTROL_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_ACTIVITIES_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_BASELINES_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_JOURNALED_OBSERVATION_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_LIFECYCLE_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_LOCKING_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_NODE_AND_PROPERTY_WITH_SAME_NAME_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_NODE_TYPE_MANAGEMENT_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_OBSERVATION_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_QUERY_SQL_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_RETENTION_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_SHAREABLE_NODES_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_SIMPLE_VERSIONING_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_TRANSACTIONS_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_UNFILED_CONTENT_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_UPDATE_MIXIN_NODE_TYPES_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_UPDATE_PRIMARY_NODE_TYPE_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_VERSIONING_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_WORKSPACE_MANAGEMENT_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_XML_EXPORT_SUPPORTED}</li>
+     * <li>{@link Repository#OPTION_XML_IMPORT_SUPPORTED}</li>
+     * <li>{@link Repository#WRITE_SUPPORTED}</li>
+     * </ul>
+     * @throws UnsupportedRepositoryOperationException
+     * @throws RepositoryException
+     * @see javax.jcr.Repository#getDescriptorKeys()
+     */
+    void checkSupportedOption(String option) throws UnsupportedRepositoryOperationException, RepositoryException {
+        if (!isSupportedOption(option)) {
+            throw new UnsupportedRepositoryOperationException(option + " is not supported by this repository.");
+        }
+    }
+
+    /**
+     * Checks if this nodes session has pending changes.
+     *
+     * @throws InvalidItemStateException if this nodes session has pending changes
+     * @throws RepositoryException
+     */
+    void checkHasPendingChanges() throws RepositoryException {
+        // check for pending changes
+        if (hasPendingChanges()) {
+            String msg = "Unable to perform operation. Session has pending changes.";
+            log.debug(msg);
+            throw new InvalidItemStateException(msg);
+        }
+    }
+
+    //------------------------------------------------------------< private >---
+
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java?rev=1300636&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java Wed Mar 14 17:00:52 2012
@@ -0,0 +1,209 @@
+/*
+ * 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.oak.jcr;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.ContentHandler;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.InvalidSerializedDataException;
+import javax.jcr.ItemExistsException;
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.Workspace;
+import javax.jcr.lock.LockException;
+import javax.jcr.lock.LockManager;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.NodeTypeManager;
+import javax.jcr.observation.ObservationManager;
+import javax.jcr.query.QueryManager;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionException;
+import javax.jcr.version.VersionManager;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * <code>WorkspaceImpl</code>...
+ */
+public class WorkspaceImpl implements Workspace {
+
+    /**
+     * logger instance
+     */
+    private static final Logger log = LoggerFactory.getLogger(WorkspaceImpl.class);
+
+    private final SessionImpl session = null;
+    private final String name = null;
+
+    //----------------------------------------------------------< Workspace >---
+    @Override
+    public Session getSession() {
+        return session;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void copy(String srcAbsPath, String destAbsPath) throws ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException {
+        copy(getName(), srcAbsPath, destAbsPath);
+    }
+
+    @Override
+    public void copy(String srcWorkspace, String srcAbsPath, String destAbsPath) throws NoSuchWorkspaceException, ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException {
+        session.checkSupportedOption(Repository.LEVEL_2_SUPPORTED);
+        session.checkIsAlive();
+
+        // TODO -> SPI
+
+    }
+
+    @Override
+    public void clone(String srcWorkspace, String srcAbsPath, String destAbsPath, boolean removeExisting) throws NoSuchWorkspaceException, ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException {
+        session.checkSupportedOption(Repository.LEVEL_2_SUPPORTED);
+        session.checkIsAlive();
+
+        // TODO -> SPI
+
+    }
+
+    @Override
+    public void move(String srcAbsPath, String destAbsPath) throws ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException {
+        session.checkSupportedOption(Repository.LEVEL_2_SUPPORTED);
+        session.checkIsAlive();
+
+        // TODO -> SPI
+
+    }
+
+    @Override
+    public void restore(Version[] versions, boolean removeExisting) throws ItemExistsException, UnsupportedRepositoryOperationException, VersionException, LockException, InvalidItemStateException, RepositoryException {
+        getVersionManager().restore(versions, removeExisting);
+    }
+
+    @Override
+    public LockManager getLockManager() throws UnsupportedRepositoryOperationException, RepositoryException {
+        session.checkIsAlive();
+        session.checkSupportedOption(Repository.OPTION_LOCKING_SUPPORTED);
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public QueryManager getQueryManager() throws RepositoryException {
+        session.checkIsAlive();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public NamespaceRegistry getNamespaceRegistry() throws RepositoryException {
+        session.checkIsAlive();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public NodeTypeManager getNodeTypeManager() throws RepositoryException {
+        session.checkIsAlive();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public ObservationManager getObservationManager() throws UnsupportedRepositoryOperationException, RepositoryException {
+        session.checkSupportedOption(Repository.OPTION_OBSERVATION_SUPPORTED);
+        session.checkIsAlive();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public VersionManager getVersionManager() throws UnsupportedRepositoryOperationException, RepositoryException {
+        session.checkIsAlive();
+        session.checkSupportedOption(Repository.OPTION_VERSIONING_SUPPORTED);
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public String[] getAccessibleWorkspaceNames() throws RepositoryException {
+        session.checkIsAlive();
+
+        // TODO
+        return new String[0];
+    }
+
+    @Override
+    public ContentHandler getImportContentHandler(String parentAbsPath, int uuidBehavior) throws PathNotFoundException, ConstraintViolationException, VersionException, LockException, AccessDeniedException, RepositoryException {
+        session.checkSupportedOption(Repository.LEVEL_2_SUPPORTED);
+        session.checkIsAlive();
+
+        // TODO
+        return null;
+    }
+
+    @Override
+    public void importXML(String parentAbsPath, InputStream in, int uuidBehavior) throws IOException, VersionException, PathNotFoundException, ItemExistsException, ConstraintViolationException, InvalidSerializedDataException, LockException, AccessDeniedException, RepositoryException {
+        session.checkSupportedOption(Repository.LEVEL_2_SUPPORTED);
+        session.checkIsAlive();
+
+        // TODO -> SPI
+    }
+
+    @Override
+    public void createWorkspace(String name) throws AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
+        session.checkIsAlive();
+        session.checkSupportedOption(Repository.OPTION_WORKSPACE_MANAGEMENT_SUPPORTED);
+        // TODO -> SPI
+    }
+
+    @Override
+    public void createWorkspace(String name, String srcWorkspace) throws AccessDeniedException, UnsupportedRepositoryOperationException, NoSuchWorkspaceException, RepositoryException {
+        session.checkIsAlive();
+        session.checkSupportedOption(Repository.OPTION_WORKSPACE_MANAGEMENT_SUPPORTED);
+
+        // TODO -> SPI
+    }
+
+    @Override
+    public void deleteWorkspace(String name) throws AccessDeniedException, UnsupportedRepositoryOperationException, NoSuchWorkspaceException, RepositoryException {
+        session.checkIsAlive();
+        session.checkSupportedOption(Repository.OPTION_WORKSPACE_MANAGEMENT_SUPPORTED);
+
+        // TODO -> SPI
+    }
+
+    //------------------------------------------------------------< private >---
+
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/util/LogUtil.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/util/LogUtil.java?rev=1300636&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/util/LogUtil.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/util/LogUtil.java Wed Mar 14 17:00:52 2012
@@ -0,0 +1,55 @@
+/*
+ * 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.oak.jcr.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.Item;
+import javax.jcr.RepositoryException;
+
+/**
+ * <code>LogUtil</code>...
+ */
+public class LogUtil {
+
+    private static Logger log = LoggerFactory.getLogger(LogUtil.class);
+
+    /**
+     * Avoid instantiation
+     */
+    private LogUtil() {}
+
+    /**
+     * Failsafe retrieval of the JCR path for a given item. This is intended
+     * to be used in log output, error messages etc.
+     *
+     * @param item The target item.
+     * @return The JCR path of that item or some implementation specific
+     * string representation of the item.
+     */
+    public static String safeGetJCRPath(Item item) {
+        try {
+            return item.getPath();
+        } catch (RepositoryException e) {
+            log.error("Failed to retrieve path from item.");
+            // return string representation of the item as a fallback
+            return item.toString();
+        }
+    }
+
+}
\ No newline at end of file