You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by dp...@apache.org on 2009/05/04 10:54:19 UTC

svn commit: r771246 - in /incubator/chemistry/trunk/chemistry: ./ chemistry-jcr/ chemistry-jcr/src/ chemistry-jcr/src/main/ chemistry-jcr/src/main/java/ chemistry-jcr/src/main/java/org/ chemistry-jcr/src/main/java/org/apache/ chemistry-jcr/src/main/jav...

Author: dpfister
Date: Mon May  4 08:54:18 2009
New Revision: 771246

URL: http://svn.apache.org/viewvc?rev=771246&view=rev
Log:
CMIS-11 Add JCR bridge code

Added:
    incubator/chemistry/trunk/chemistry/chemistry-jcr/
    incubator/chemistry/trunk/chemistry/chemistry-jcr/pom.xml
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrConnection.java   (with props)
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrContentStream.java   (with props)
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrDocument.java   (with props)
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrFolder.java   (with props)
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrNewDocument.java   (with props)
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrNewFolder.java   (with props)
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrObjectEntry.java   (with props)
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrProperty.java   (with props)
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrPropertyDefinition.java   (with props)
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrRepository.java   (with props)
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrType.java   (with props)
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/test/
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/test/java/
Modified:
    incubator/chemistry/trunk/chemistry/   (props changed)
    incubator/chemistry/trunk/chemistry/pom.xml

Propchange: incubator/chemistry/trunk/chemistry/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Mon May  4 08:54:18 2009
@@ -0,0 +1,6 @@
+
+target
+*.iws
+*.ipr
+*.iml
+.*

Added: incubator/chemistry/trunk/chemistry/chemistry-jcr/pom.xml
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-jcr/pom.xml?rev=771246&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-jcr/pom.xml (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-jcr/pom.xml Mon May  4 08:54:18 2009
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+   Copyright 2009 Nuxeo SA <http://nuxeo.com>
+
+   Licensed 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.
+  -->
+
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.chemistry</groupId>
+    <artifactId>chemistry-parent</artifactId>
+    <version>0.1-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>chemistry-jcr</artifactId>
+  <name>Chemistry JCR Connector</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.chemistry</groupId>
+      <artifactId>chemistry-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.chemistry</groupId>
+      <artifactId>chemistry-commons</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <version>1.1</version>
+    </dependency>
+
+    <dependency>
+      <groupId>javax.jcr</groupId>
+      <artifactId>jcr</artifactId>
+      <version>1.0</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>jackrabbit-jcr-commons</artifactId>
+      <version>1.4.2</version>
+    </dependency>
+
+  </dependencies>
+</project>

Added: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrConnection.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrConnection.java?rev=771246&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrConnection.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrConnection.java Mon May  4 08:54:18 2009
@@ -0,0 +1,494 @@
+package org.apache.chemistry.jcr;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
+import javax.jcr.query.QueryResult;
+
+import org.apache.chemistry.CMISObject;
+import org.apache.chemistry.Connection;
+import org.apache.chemistry.ContentStream;
+import org.apache.chemistry.Document;
+import org.apache.chemistry.Folder;
+import org.apache.chemistry.ObjectEntry;
+import org.apache.chemistry.Policy;
+import org.apache.chemistry.Relationship;
+import org.apache.chemistry.RelationshipDirection;
+import org.apache.chemistry.ReturnVersion;
+import org.apache.chemistry.SPI;
+import org.apache.chemistry.Unfiling;
+import org.apache.chemistry.VersioningState;
+import org.apache.chemistry.repository.Repository;
+import org.apache.chemistry.type.BaseType;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.JcrConstants;
+
+public class JcrConnection implements Connection, SPI {
+
+    private static final Log log = LogFactory.getLog(JcrConnection.class);
+
+    private Session session;
+    private JcrRepository repository;
+
+    public JcrConnection(Session session, JcrRepository repository) {
+        this.session = session;
+        this.repository = repository;
+    }
+
+    public void addObjectToFolder(ObjectEntry object, ObjectEntry folder) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void applyPolicy(Policy policy, ObjectEntry object) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void cancelCheckOut(ObjectEntry document) {
+        throw new UnsupportedOperationException();
+    }
+
+    public CMISObject checkIn(ObjectEntry document, boolean major,
+                              String comment) {
+        throw new UnsupportedOperationException();
+    }
+
+    public CMISObject checkOut(ObjectEntry document) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void close() {
+        session.logout();
+    }
+
+    public void deleteAllVersions(ObjectEntry document) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void deleteObject(ObjectEntry object) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<String> deleteTree(ObjectEntry folder, Unfiling unfiling,
+                                         boolean continueOnFailure) {
+        JcrFolder f = (JcrFolder) folder;
+        f.delete();
+        return Collections.emptySet();
+    }
+
+    public Collection<ObjectEntry> getAllVersions(ObjectEntry document,
+                                                  String filter) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<Policy> getAppliedPolicies(ObjectEntry object) {
+        throw new UnsupportedOperationException();
+    }
+
+    public List<ObjectEntry> getChildren(ObjectEntry folder) {
+        return getChildren(folder.getId(), null, null, false, false,
+                Integer.MAX_VALUE, 0, null, new boolean[1]);
+    }
+
+    public CMISObject getLatestVersion(ObjectEntry document, boolean major) {
+        throw new UnsupportedOperationException();
+    }
+
+    public CMISObject getObject(String objectId, ReturnVersion returnVersion) {
+        try {
+            String relPath = JcrObjectEntry.getPath(objectId).substring(1);
+            if (relPath.equals("")) {
+                return getRootFolder();
+            } else {
+                Node node = session.getRootNode().getNode(relPath);
+                if (node.isNodeType(JcrConstants.NT_FOLDER)) {
+                    return new JcrFolder(node);
+                } else if (node.isNodeType(JcrConstants.NT_FILE)) {
+                    return new JcrDocument(node);
+                }
+            }
+        } catch (RepositoryException e) {
+            String msg = "Unable to get object: " + objectId;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public List<ObjectEntry> getRelationships(ObjectEntry object,
+                                              RelationshipDirection direction,
+                                              String typeId,
+                                              boolean includeSubRelationshipTypes) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Repository getRepository() {
+        return repository;
+    }
+
+    public ObjectEntry getRootEntry() {
+        return getRootFolder();
+    }
+
+    public Folder getRootFolder() {
+        try {
+            return new JcrFolder(session.getRootNode());
+        } catch (RepositoryException e) {
+            String msg = "Unable to get root entry.";
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public SPI getSPI() {
+        return this;
+    }
+
+    public void moveObject(ObjectEntry object, ObjectEntry targetFolder,
+                           ObjectEntry sourceFolder) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Document newDocument(String typeId, ObjectEntry folder) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Folder newFolder(String typeId, ObjectEntry folder) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Policy newPolicy(String typeId, ObjectEntry folder) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Relationship newRelationship(String typeId) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<ObjectEntry> query(String statement,
+                                         boolean searchAllVersions) {
+
+        boolean[] hasMoreItems = new boolean[1];
+        return query(statement, searchAllVersions, false, false,
+                Integer.MAX_VALUE, 0, hasMoreItems);
+    }
+
+    public void removeObjectFromFolder(ObjectEntry object, ObjectEntry folder) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void removePolicy(Policy policy, ObjectEntry object) {
+        throw new UnsupportedOperationException();
+    }
+
+    //---------------------------------------------------------------------- SPI
+
+    public void addObjectToFolder(String objectId, String folderId) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void applyPolicy(String policyId, String objectId) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void cancelCheckOut(String documentId) {
+        throw new UnsupportedOperationException();
+    }
+
+    public String checkIn(String documentId, boolean major,
+                          Map<String, Serializable> properties,
+                          ContentStream contentStream, String comment) {
+        throw new UnsupportedOperationException();
+    }
+
+    public String checkOut(String documentId, boolean[] contentCopied) {
+        throw new UnsupportedOperationException();
+    }
+
+    // TODO add IOException to throws clause
+    public String createDocument(String typeId,
+                                 Map<String, Serializable> properties,
+                                 String folderId, ContentStream contentStream,
+                                 VersioningState versioningState) {
+    	
+    	try {
+	    	JcrFolder folder = (JcrFolder) getObject(folderId, ReturnVersion.LATEST);
+	    	Document doc = folder.newDocument(null);
+	    	doc.setValues(properties);
+	    	if (contentStream != null) {
+		    	doc.setName(contentStream.getFilename());
+		    	doc.setValue("title", contentStream.getFilename());
+		    	doc.setContentStream(contentStream);
+	    	}
+	    	doc.save();
+	    	return doc.getId();
+    	} catch (IOException e) {
+    		String msg = "Unable to create document.";
+    		log.error(msg, e);
+    	}
+    	return null;
+    }
+
+    public String createFolder(String typeId,
+                               Map<String, Serializable> properties,
+                               String folderId) {
+        throw new UnsupportedOperationException();
+    }
+
+    public String createPolicy(String typeId,
+                               Map<String, Serializable> properties,
+                               String folderId) {
+        throw new UnsupportedOperationException();
+    }
+
+    public String createRelationship(String typeId,
+                                     Map<String, Serializable> properties,
+                                     String sourceId, String targetId) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void deleteAllVersions(String versionSeriesId) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void deleteContentStream(String documentId) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void deleteObject(String objectId) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<String> deleteTree(String folderId, Unfiling unfiling,
+                                         boolean continueOnFailure) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<ObjectEntry> getAllVersions(String versionSeriesId,
+                                                  String filter) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<String> getAllowableActions(String objectId, String asUser) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<ObjectEntry> getAppliedPolicies(String objectId,
+                                                      String filter) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<ObjectEntry> getCheckedoutDocuments(String folderId,
+                                                          String filter,
+                                                          boolean includeAllowableActions,
+                                                          boolean includeRelationships,
+                                                          int maxItems,
+                                                          int skipCount,
+                                                          boolean[] hasMoreItems) {
+        throw new UnsupportedOperationException();
+    }
+
+    public List<ObjectEntry> getChildren(String folderId, BaseType type,
+                                         String filter,
+                                         boolean includeAllowableActions,
+                                         boolean includeRelationships,
+                                         int maxItems, int skipCount,
+                                         String orderBy, boolean[] hasMoreItems) {
+
+        try {
+            if (maxItems == 0) {
+                maxItems = Integer.MAX_VALUE;
+            }
+
+            Node node = session.getRootNode();
+            String relPath = JcrObjectEntry.getPath(folderId).substring(1);
+            if (!relPath.equals("")) {
+                node = node.getNode(relPath);
+            }
+            NodeIterator iter;
+            if (filter == null) {
+                iter = node.getNodes();
+            } else {
+                iter = node.getNodes(filter);
+            }
+            /* Problem with skipCount == 0, when there are no more elements */
+            if (iter.hasNext()) {
+            	iter.skip(skipCount);
+            }
+
+            List<ObjectEntry> result = new ArrayList<ObjectEntry>();
+            while (result.size() < maxItems && iter.hasNext()) {
+                Node child = iter.nextNode();
+                if (child.isNodeType(JcrConstants.NT_FOLDER)) {
+                    result.add(new JcrFolder(child));
+                } else if (child.isNodeType(JcrConstants.NT_FILE)) {
+                    result.add(new JcrDocument(child));
+                }
+            }
+            hasMoreItems[0] = iter.hasNext();
+            return result;
+
+        } catch (RepositoryException e) {
+            String msg = "Unable to get children: " + folderId;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public Connection getConnection() {
+        return this;
+    }
+
+    public InputStream getContentStream(String documentId, int offset,
+                                        int length) throws IOException {
+
+        try {
+            String relPath = JcrObjectEntry.getPath(documentId).substring(1);
+            Node node = session.getRootNode().getNode(relPath);
+            JcrDocument document = new JcrDocument(node);
+            return document.getStream();
+        } catch (RepositoryException e) {
+            String msg = "Unable to get object: " + documentId;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public List<ObjectEntry> getDescendants(String folderId, BaseType type,
+                                            int depth, String filter,
+                                            boolean includeAllowableActions,
+                                            boolean includeRelationships,
+                                            String orderBy) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public List<ObjectEntry> getFolderParent(String folderId, String filter,
+                                             boolean includeAllowableActions,
+                                             boolean includeRelationships,
+                                             boolean returnToRoot) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Collection<ObjectEntry> getObjectParents(String objectId,
+                                                    String filter,
+                                                    boolean includeAllowableActions,
+                                                    boolean includeRelationships) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public ObjectEntry getProperties(String objectId,
+                                     ReturnVersion returnVersion,
+                                     String filter,
+                                     boolean includeAllowableActions,
+                                     boolean includeRelationships) {
+
+        try {
+            String relPath = JcrObjectEntry.getPath(objectId).substring(1);
+            if (relPath.equals("")) {
+                return getRootFolder();
+            } else {
+                Node node = session.getRootNode().getNode(relPath);
+                if (node.isNodeType(JcrConstants.NT_FOLDER)) {
+                    return new JcrFolder(node);
+                } else if (node.isNodeType(JcrConstants.NT_FILE)) {
+                    return new JcrDocument(node);
+                }
+            }
+        } catch (RepositoryException e) {
+            String msg = "Unable to get object: " + objectId;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public Map<String, Serializable> getPropertiesOfLatestVersion(String versionSeriesId,
+                                                                  boolean majorVersion,
+                                                                  String filter) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public List<ObjectEntry> getRelationships(String objectId,
+                                              RelationshipDirection direction,
+                                              String typeId,
+                                              boolean includeSubRelationshipTypes,
+                                              String filter,
+                                              String includeAllowableActions,
+                                              int maxItems, int skipCount,
+                                              boolean[] hasMoreItems) {
+
+        return Collections.emptyList();
+    }
+
+    public void moveObject(String objectId, String targetFolderId,
+                           String sourceFolderId) {
+
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<ObjectEntry> query(String statement,
+                                         boolean searchAllVersions,
+                                         boolean includeAllowableActions,
+                                         boolean includeRelationships,
+                                         int maxItems, int skipCount,
+                                         boolean[] hasMoreItems) {
+
+
+        try {
+            QueryManager qm = session.getWorkspace().getQueryManager();
+            QueryResult qr = qm.createQuery(statement, Query.SQL).execute();
+            NodeIterator iter = qr.getNodes();
+            iter.skip(skipCount);
+
+            List<ObjectEntry> result = new ArrayList<ObjectEntry>();
+
+            while (result.size() < maxItems && iter.hasNext()) {
+                Node child = iter.nextNode();
+                if (child.isNodeType(JcrConstants.NT_FOLDER)) {
+                    result.add(new JcrFolder(child));
+                } else if (child.isNodeType(JcrConstants.NT_FILE)) {
+                    result.add(new JcrDocument(child));
+                }
+            }
+            hasMoreItems[0] = iter.hasNext();
+            return result;
+
+        } catch (RepositoryException e) {
+            String msg = "Unable to execute query.";
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public void removeObjectFromFolder(String objectId, String folderId) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void removePolicy(String policyId, String objectId) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setContentStream(String documentId, boolean overwrite,
+                                 ContentStream contentStream) {
+        throw new UnsupportedOperationException();
+    }
+
+    public String updateProperties(String objectId, String changeToken,
+                                   Map<String, Serializable> properties) {
+        throw new UnsupportedOperationException();
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrConnection.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrContentStream.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrContentStream.java?rev=771246&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrContentStream.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrContentStream.java Mon May  4 08:54:18 2009
@@ -0,0 +1,71 @@
+package org.apache.chemistry.jcr;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.apache.chemistry.ContentStream;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.JcrConstants;
+
+public class JcrContentStream implements ContentStream {
+
+    private static final Log log = LogFactory.getLog(JcrFolder.class);
+    private Node content;
+
+    public JcrContentStream(Node content) {
+        this.content = content;
+    }
+
+    public String getFilename() {
+        try {
+            return content.getName();
+        } catch (RepositoryException e) {
+            String msg = "Unable to get node name.";
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public long getLength() {
+        try {
+            javax.jcr.Property data = content.getProperty(JcrConstants.JCR_DATA);
+            return data.getLength();
+        } catch (RepositoryException e) {
+            String msg = "Unable to get length.";
+            log.error(msg, e);
+        }
+        return 0;
+    }
+
+    public String getMimeType() {
+        try {
+            javax.jcr.Property mimetype = content.getProperty(JcrConstants.JCR_MIMETYPE);
+            return mimetype.getString();
+        } catch (RepositoryException e) {
+            String msg = "Unable to get mime type.";
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public InputStream getStream() throws IOException {
+        try {
+            javax.jcr.Property data = content.getProperty(JcrConstants.JCR_DATA);
+            return data.getStream();
+        } catch (RepositoryException e) {
+            String msg = "Unable to get stream.";
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public URI getURI() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrContentStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrDocument.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrDocument.java?rev=771246&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrDocument.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrDocument.java Mon May  4 08:54:18 2009
@@ -0,0 +1,113 @@
+package org.apache.chemistry.jcr;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.apache.chemistry.ContentStream;
+import org.apache.chemistry.Document;
+import org.apache.chemistry.Folder;
+import org.apache.chemistry.property.Property;
+import org.apache.chemistry.type.BaseType;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.JcrConstants;
+
+public class JcrDocument extends JcrObjectEntry implements Document {
+
+    private static final Log log = LogFactory.getLog(JcrDocument.class);
+
+    public JcrDocument(Node node) {
+        super(node);
+    }
+
+    protected JcrDocument() {}
+
+    public ContentStream getContentStream() {
+        try {
+            Node content = node.getNode(JcrConstants.JCR_CONTENT);
+            return new JcrContentStream(content);
+        } catch (RepositoryException e) {
+            String msg = "Unable to get parent.";
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public Folder getParent() {
+        try {
+            return new JcrFolder(node.getParent());
+        } catch (RepositoryException e) {
+            String msg = "Unable to get parent.";
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public InputStream getStream() throws IOException {
+        try {
+            Node content = node.getNode(JcrConstants.JCR_CONTENT);
+            javax.jcr.Property prop = content.getProperty(JcrConstants.JCR_DATA);
+            return prop.getStream();
+        } catch (RepositoryException e) {
+            String msg = "Unable to get stream.";
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    @Override
+    public String getString(String name) {
+        if (name.equals(Property.CONTENT_STREAM_MIME_TYPE)) {
+            return getContentStream().getMimeType();
+        }
+        return super.getString(name);
+    }
+
+    public void setContentStream(ContentStream contentStream)
+            throws IOException {
+
+        throw new UnsupportedOperationException();
+    }
+
+    public void save() {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setName(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setValue(String name, Serializable value) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setValues(Map<String, Serializable> values) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Document getDocument() {
+        return this;
+    }
+
+    @Override
+    public boolean hasContentStream() {
+        try {
+            return node.hasNode(JcrConstants.JCR_CONTENT);
+        } catch (RepositoryException e) {
+            String msg = "Unable to get sub node: " + JcrConstants.JCR_CONTENT;
+            log.error(msg, e);
+        }
+        return false;
+    }
+    
+    @Override
+    protected BaseType getBaseType() {
+    	return BaseType.DOCUMENT;
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrDocument.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrFolder.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrFolder.java?rev=771246&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrFolder.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrFolder.java Mon May  4 08:54:18 2009
@@ -0,0 +1,113 @@
+package org.apache.chemistry.jcr;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+
+import org.apache.chemistry.Document;
+import org.apache.chemistry.Folder;
+import org.apache.chemistry.ObjectEntry;
+import org.apache.chemistry.type.BaseType;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.JcrConstants;
+
+public class JcrFolder extends JcrObjectEntry implements Folder {
+
+    private static final Log log = LogFactory.getLog(JcrFolder.class);
+
+    public JcrFolder(Node node) {
+        super(node);
+    }
+
+    protected JcrFolder() {}
+
+    public List<ObjectEntry> getChildren(BaseType type, String orderBy) {
+        try {
+            List<ObjectEntry> result = new ArrayList<ObjectEntry>();
+
+            NodeIterator iter = node.getNodes();
+            while (iter.hasNext()) {
+                Node child = iter.nextNode();
+                JcrObjectEntry entry = null;
+                if (child.isNodeType(JcrConstants.NT_FOLDER)) {
+                    entry = new JcrFolder(child);
+                } else if (child.isNodeType(JcrConstants.NT_FILE)) {
+                    entry = new JcrDocument(child);
+                } else {
+                    continue;
+                }
+                if (type == null || type == entry.getType().getBaseType()) {
+                    result.add(entry);
+                }
+            }
+            return result;
+        } catch (RepositoryException e) {
+            String msg = "Unable to get children.";
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public Document newDocument(String typeId) {
+        return new JcrNewDocument(node);
+    }
+
+    public Folder newFolder(String typeId) {
+        return new JcrNewFolder(node);
+    }
+
+    public Folder getParent() {
+        try {
+            if (node.getDepth() > 0) {
+                return new JcrFolder(node.getParent());
+            }
+        } catch (RepositoryException e) {
+            String msg = "Unable to get parent.";
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public void save() {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setName(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setValue(String name, Serializable value) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setValues(Map<String, Serializable> values) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Folder getFolder() {
+        return this;
+    }
+
+    public void delete() {
+        try {
+            Node parent = node.getParent();
+            node.remove();
+            parent.save();
+        } catch (RepositoryException e) {
+            String msg = "Unable to delete folder.";
+            log.error(msg, e);
+        }
+    }
+    
+    @Override
+    protected BaseType getBaseType() {
+    	return BaseType.FOLDER;
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrFolder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrNewDocument.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrNewDocument.java?rev=771246&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrNewDocument.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrNewDocument.java Mon May  4 08:54:18 2009
@@ -0,0 +1,131 @@
+package org.apache.chemistry.jcr;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.apache.chemistry.ContentStream;
+import org.apache.chemistry.Folder;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.JcrConstants;
+
+public class JcrNewDocument extends JcrDocument {
+
+    private static final Log log = LogFactory.getLog(JcrNewDocument.class);
+
+    private Node parent;
+    private String name;
+    private Map<String, Serializable> values = new HashMap<String, Serializable>();
+    private ContentStream cs;
+    private boolean saved;
+
+    public JcrNewDocument(Node parent) {
+        this.parent = parent;
+    }
+
+    public ContentStream getContentStream() {
+        if (!saved) {
+            throw new UnsupportedOperationException();
+        }
+        return super.getContentStream();
+    }
+
+    public Folder getParent() {
+        if (!saved) {
+            return new JcrFolder(parent);
+        }
+        return super.getParent();
+    }
+
+    public InputStream getStream() throws IOException {
+        if (!saved) {
+            throw new UnsupportedOperationException();
+        }
+        return super.getStream();
+    }
+
+    public void setContentStream(ContentStream contentStream)
+            throws IOException {
+
+        if (saved) {
+            throw new UnsupportedOperationException();
+        }
+        this.cs = contentStream;
+    }
+
+    public void save() {
+        if (saved) {
+            throw new UnsupportedOperationException();
+        }
+        try {
+            String name = this.name;
+            if (cs != null) {
+                name = cs.getFilename();
+            }
+            if (name == null) {
+            	Serializable val = getValue("title");
+            	if (val != null) {
+            		name = val.toString();
+            	}
+            }
+            if (name == null) {
+            	name = "unnamed";
+            }
+
+            Node node = parent.addNode(name, JcrConstants.NT_FILE);
+            node.addMixin(MIX_UNSTRUCTURED);
+            Node content = node.addNode(JcrConstants.JCR_CONTENT,
+                    JcrConstants.NT_RESOURCE);
+            if (cs != null) {
+                content.setProperty(JcrConstants.JCR_MIMETYPE, cs.getMimeType());
+                content.setProperty(JcrConstants.JCR_DATA, cs.getStream());
+            } else {
+                content.setProperty(JcrConstants.JCR_MIMETYPE, "application/octet-stream");
+                content.setProperty(JcrConstants.JCR_DATA, new ByteArrayInputStream(new byte[0]));
+            }
+            content.setProperty(JcrConstants.JCR_LASTMODIFIED, Calendar.getInstance());
+
+            for (String key : values.keySet()) {
+                node.setProperty(key, values.get(key).toString());
+            }
+            parent.save();
+            setNode(node);
+            saved = true;
+        } catch (IOException e) {
+            String msg = "Unable to get stream.";
+            log.error(msg, e);
+        } catch (RepositoryException e) {
+            String msg = "Unable to save folder.";
+            log.error(msg, e);
+        }
+    }
+
+    public void setName(String name) {
+        if (saved) {
+            throw new UnsupportedOperationException();
+        }
+        this.name = name;
+    }
+
+    public void setValue(String name, Serializable value) {
+        if (saved) {
+            throw new UnsupportedOperationException();
+        }
+        values.put(name, value);
+    }
+
+    public void setValues(Map<String, Serializable> values) {
+        if (saved) {
+            throw new UnsupportedOperationException();
+        }
+        this.values.putAll(values);
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrNewDocument.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrNewFolder.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrNewFolder.java?rev=771246&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrNewFolder.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrNewFolder.java Mon May  4 08:54:18 2009
@@ -0,0 +1,100 @@
+package org.apache.chemistry.jcr;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.apache.chemistry.Document;
+import org.apache.chemistry.Folder;
+import org.apache.chemistry.ObjectEntry;
+import org.apache.chemistry.type.BaseType;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.JcrConstants;
+
+public class JcrNewFolder extends JcrFolder {
+
+    private static final Log log = LogFactory.getLog(JcrNewFolder.class);
+
+    private Node parent;
+    private String name;
+    private Map<String, Serializable> values = new HashMap<String, Serializable>();
+    private boolean saved;
+
+    public JcrNewFolder(Node parent) {
+        this.parent = parent;
+    }
+
+    public List<ObjectEntry> getChildren(BaseType type, String orderBy) {
+        if (!saved) {
+            throw new UnsupportedOperationException();
+        }
+        return super.getChildren(type, orderBy);
+    }
+
+    public Document newDocument(String typeId) {
+        if (!saved) {
+            throw new UnsupportedOperationException();
+        }
+        return super.newDocument(typeId);
+    }
+
+    public Folder newFolder(String typeId) {
+        if (!saved) {
+            throw new UnsupportedOperationException();
+        }
+        return super.newFolder(typeId);
+    }
+
+    public Folder getParent() {
+        if (!saved) {
+            return new JcrFolder(parent);
+        }
+        return super.getParent();
+    }
+
+    public void save() {
+        if (saved) {
+            throw new UnsupportedOperationException();
+        }
+        try {
+            Node node = parent.addNode(name, JcrConstants.NT_FOLDER);
+            node.addMixin(MIX_UNSTRUCTURED);
+
+            for (String key : values.keySet()) {
+                node.setProperty(key, values.get(key).toString());
+            }
+            parent.save();
+            setNode(node);
+            saved = true;
+        } catch (RepositoryException e) {
+            String msg = "Unable to save folder.";
+            log.error(msg, e);
+        }
+    }
+
+    public void setName(String name) {
+        if (saved) {
+            throw new UnsupportedOperationException();
+        }
+        this.name = name;
+    }
+
+    public void setValue(String name, Serializable value) {
+        if (saved) {
+            throw new UnsupportedOperationException();
+        }
+        values.put(name, value);
+    }
+
+    public void setValues(Map<String, Serializable> values) {
+        if (saved) {
+            throw new UnsupportedOperationException();
+        }
+        this.values.putAll(values);
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrNewFolder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrObjectEntry.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrObjectEntry.java?rev=771246&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrObjectEntry.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrObjectEntry.java Mon May  4 08:54:18 2009
@@ -0,0 +1,468 @@
+package org.apache.chemistry.jcr;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.net.URI;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+
+import org.apache.chemistry.Document;
+import org.apache.chemistry.Folder;
+import org.apache.chemistry.ObjectEntry;
+import org.apache.chemistry.Policy;
+import org.apache.chemistry.Relationship;
+import org.apache.chemistry.impl.simple.SimplePropertyDefinition;
+import org.apache.chemistry.property.Property;
+import org.apache.chemistry.property.PropertyDefinition;
+import org.apache.chemistry.property.PropertyType;
+import org.apache.chemistry.property.Updatability;
+import org.apache.chemistry.type.BaseType;
+import org.apache.chemistry.type.Type;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public abstract class JcrObjectEntry implements ObjectEntry {
+
+    public static final String MIX_UNSTRUCTURED = "mix:unstructured";
+    private static final Log log = LogFactory.getLog(JcrObjectEntry.class);
+
+    protected Node node;
+
+    public JcrObjectEntry(Node node) {
+        this.node = node;
+    }
+
+    public JcrObjectEntry() {}
+
+    public Collection<String> getAllowableActions() {
+        throw new UnsupportedOperationException();
+    }
+
+    public Boolean getBoolean(String name) {
+        try {
+            return Boolean.valueOf(node.getProperty(name).getBoolean());
+        } catch (PathNotFoundException e) {
+            /* property does not exist */
+        } catch (RepositoryException e) {
+            String msg = "Unable to get boolean value: " + name;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public Boolean[] getBooleans(String name) {
+        try {
+            Value[] values = node.getProperty(name).getValues();
+            Boolean[] result = new Boolean[values.length];
+            for (int i = 0; i < values.length; i++) {
+                result[i] = Boolean.valueOf(values[i].getBoolean());
+            }
+            return result;
+        } catch (PathNotFoundException e) {
+            /* property does not exist */
+        } catch (RepositoryException e) {
+            String msg = "Unable to get boolean values: " + name;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public String getChangeToken() {
+        return getString(Property.CHANGE_TOKEN);
+    }
+
+    public String getCheckinComment() {
+        return getString(Property.CHECKIN_COMMENT);
+    }
+
+    public String getCreatedBy() {
+        return getString(Property.CREATED_BY);
+    }
+
+    public Calendar getCreationDate() {
+        return getDateTime(Property.CREATION_DATE);
+    }
+
+    public Calendar getDateTime(String name) {
+        try {
+            return node.getProperty(name).getDate();
+        } catch (PathNotFoundException e) {
+            /* property does not exist */
+        } catch (RepositoryException e) {
+            String msg = "Unable to get date time value: " + name;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public Calendar[] getDateTimes(String name) {
+        try {
+            Value[] values = node.getProperty(name).getValues();
+            Calendar[] result = new Calendar[values.length];
+            for (int i = 0; i < values.length; i++) {
+                result[i] = values[i].getDate();
+            }
+            return result;
+        } catch (PathNotFoundException e) {
+            /* property does not exist */
+        } catch (RepositoryException e) {
+            String msg = "Unable to get date time values: " + name;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public BigDecimal getDecimal(String name) {
+        try {
+            return new BigDecimal(node.getProperty(name).getDouble());
+        } catch (PathNotFoundException e) {
+            /* property does not exist */
+        } catch (RepositoryException e) {
+            String msg = "Unable to get decimal value: " + name;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public BigDecimal[] getDecimals(String name) {
+        try {
+            Value[] values = node.getProperty(name).getValues();
+            BigDecimal[] result = new BigDecimal[values.length];
+            for (int i = 0; i < values.length; i++) {
+                result[i] = new BigDecimal(values[i].getDouble());
+            }
+            return result;
+        } catch (PathNotFoundException e) {
+            /* property does not exist */
+        } catch (RepositoryException e) {
+            String msg = "Unable to get decimal values: " + name;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public Document getDocument() {
+        throw new UnsupportedOperationException();
+    }
+
+    public Folder getFolder() {
+        throw new UnsupportedOperationException();
+    }
+
+    public String getHTML(String name) {
+        return (String) getValue(name);
+    }
+
+    public String[] getHTMLs(String name) {
+        return (String[]) getValue(name);
+    }
+
+    public String getId(String name) {
+        try {
+            javax.jcr.Property prop = node.getProperty(name);
+            return getItemId(prop);
+        } catch (PathNotFoundException e) {
+            /* property does not exist */
+        } catch (RepositoryException e) {
+            String msg = "Unable to get item path: " + name;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public String getId() {
+        try {
+            return getItemId(node);
+        } catch (RepositoryException e) {
+            String msg = "Unable to get item path.";
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public String[] getIds(String name) {
+        return (String[]) getValue(name);
+    }
+
+    public Integer getInteger(String name) {
+        try {
+            return Integer.valueOf((int) node.getProperty(name).getLong());
+        } catch (PathNotFoundException e) {
+            /* property does not exist */
+        } catch (RepositoryException e) {
+            String msg = "Unable to get integer value: " + name;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public Integer[] getIntegers(String name) {
+        try {
+            Value[] values = node.getProperty(name).getValues();
+            Integer[] result = new Integer[values.length];
+            for (int i = 0; i < values.length; i++) {
+                result[i] = Integer.valueOf((int) values[i].getLong());
+            }
+            return result;
+        } catch (PathNotFoundException e) {
+            /* property does not exist */
+        } catch (RepositoryException e) {
+            String msg = "Unable to get integer values: " + name;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public Calendar getLastModificationDate() {
+        return getDateTime(Property.LAST_MODIFICATION_DATE);
+    }
+
+    public String getLastModifiedBy() {
+        return getString(Property.LAST_MODIFIED_BY);
+    }
+
+    public String getName() {
+        try {
+            return node.getName();
+        } catch (RepositoryException e) {
+            String msg = "Unable to get node name.";
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public Policy getPolicy() {
+        throw new UnsupportedOperationException();
+    }
+
+    // TODO use the definition inside SimpleType
+    private static final SimplePropertyDefinition PROP_TYPE_ID = new SimplePropertyDefinition(
+            Property.TYPE_ID, "def:typeid", "Type ID", "", false,
+            PropertyType.ID, false, null, false, true, null,
+            Updatability.READ_ONLY, true, true, 0, null, null, -1, null, null);
+
+    public Map<String, Property> getProperties() {
+        Map<String, Property> properties = new HashMap<String, Property>();
+        for (PropertyDefinition pd : getType().getPropertyDefinitions()) {
+            String name = pd.getName();
+            properties.put(name, getProperty(name));
+        }
+        // TODO return other virtual properties and provide helper class
+        properties.put(Property.TYPE_ID, new Property() {
+
+			public PropertyDefinition getDefinition() {
+				return PROP_TYPE_ID;
+			}
+
+			public Serializable getValue() {
+				return getTypeId();
+			}
+
+			public void setValue(Serializable value) {
+			}
+        });
+        return properties;
+    }
+
+    public Property getProperty(String name) {
+        try {
+            return new JcrProperty(node.getProperty(name));
+        } catch (PathNotFoundException e) {
+            /* property does not exist */
+        } catch (RepositoryException e) {
+            String msg = "Unable to get property: " + name;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public Relationship getRelationship() {
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<ObjectEntry> getRelationships() {
+        return Collections.emptyList();
+    }
+
+    public String getString(String name) {
+        try {
+            return node.getProperty(name).getString();
+        } catch (PathNotFoundException e) {
+            /* property does not exist */
+        } catch (RepositoryException e) {
+            String msg = "Unable to get string value: " + name;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public String[] getStrings(String name) {
+        try {
+            Value[] values = node.getProperty(name).getValues();
+            String[] result = new String[values.length];
+            for (int i = 0; i < values.length; i++) {
+                result[i] = values[i].getString();
+            }
+            return result;
+        } catch (PathNotFoundException e) {
+            /* property does not exist */
+        } catch (RepositoryException e) {
+            String msg = "Unable to get string values: " + name;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public Type getType() {
+        try {
+            return new JcrType(node.getPrimaryNodeType(), getBaseType());
+        } catch (RepositoryException e) {
+            String msg = "Unable to get primary node type.";
+            log.error(msg, e);
+        }
+        return null;
+    }
+    
+    protected abstract BaseType getBaseType();
+
+    public String getTypeId() {
+        return getType().getId();
+    }
+
+    public URI getURI(String name) {
+        return (URI) getValue(name);
+    }
+
+    public URI getURI() {
+        return getURI(Property.URI);
+    }
+
+    public URI[] getURIs(String name) {
+        return (URI[]) getValue(name);
+    }
+
+    public Serializable getValue(String name) {
+        try {
+        	if (node.hasProperty(name)) {
+	            Value value = node.getProperty(name).getValue();
+	            if (value instanceof Serializable) {
+	                return (Serializable) value;
+	            }
+        	}
+        } catch (PathNotFoundException e) {
+            /* property does not exist */
+        } catch (RepositoryException e) {
+            String msg = "Unable to get value: " + name;
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public String getVersionLabel() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String getVersionSeriesCheckedOutBy() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String getVersionSeriesCheckedOutId() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String getVersionSeriesId() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String getXML(String name) {
+        return (String) getValue(name);
+    }
+
+    public String[] getXMLs(String name) {
+        return (String[]) getValue(name);
+    }
+
+    public boolean hasContentStream() {
+        return false;
+    }
+
+    public boolean isImmutable() {
+        return false;
+    }
+
+    public boolean isLatestMajorVersion() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    public boolean isLatestVersion() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    public boolean isMajorVersion() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    public boolean isVersionSeriesCheckedOut() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    public static String getItemId(Item item) throws RepositoryException {
+        return escape(item.getPath());
+    }
+
+    public static String getPath(String id) {
+        return unescape(id);
+    }
+
+    public static String escape(String s) {
+        StringBuffer result = new StringBuffer();
+
+        char[] ach = s.toCharArray();
+        for (char c : ach) {
+            String esc = Integer.toHexString(c);
+            int len = esc.length();
+            if (len > 2) {
+                esc = esc.substring(len - 2);
+            } else if (len < 2) {
+                result.append('0');
+            }
+            result.append(esc);
+        }
+        return result.toString();
+    }
+
+    public static String unescape(String s) {
+        StringBuffer result = new StringBuffer();
+
+        char[] ach = s.toCharArray();
+        int i = 0;
+
+        while (i < ach.length) {
+            char c = (char) Integer.parseInt(s.substring(i, i + 2), 16);
+            result.append(c);
+            i += 2;
+        }
+        return result.toString();
+    }
+
+    protected void setNode(Node node) {
+        this.node = node;
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrObjectEntry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrProperty.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrProperty.java?rev=771246&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrProperty.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrProperty.java Mon May  4 08:54:18 2009
@@ -0,0 +1,46 @@
+package org.apache.chemistry.jcr;
+
+import java.io.Serializable;
+
+import javax.jcr.RepositoryException;
+
+import org.apache.chemistry.property.Property;
+import org.apache.chemistry.property.PropertyDefinition;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class JcrProperty implements Property {
+
+    private static final Log log = LogFactory.getLog(JcrProperty.class);
+
+    private javax.jcr.Property property;
+
+    public JcrProperty(javax.jcr.Property property) {
+        this.property = property;
+    }
+
+    public PropertyDefinition getDefinition() {
+        try {
+            return new JcrPropertyDefinition(property.getDefinition());
+        } catch (RepositoryException e) {
+            String msg = "Unable to get property definition.";
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public Serializable getValue() {
+        try {
+            return property.getValue().getString();
+        } catch (RepositoryException e) {
+            String msg = "Unable to get property value.";
+            log.error(msg, e);
+        }
+        return null;
+    }
+
+    public void setValue(Serializable value) {
+        throw new UnsupportedOperationException();
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrProperty.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrPropertyDefinition.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrPropertyDefinition.java?rev=771246&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrPropertyDefinition.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrPropertyDefinition.java Mon May  4 08:54:18 2009
@@ -0,0 +1,136 @@
+package org.apache.chemistry.jcr;
+
+import java.io.Serializable;
+import java.net.URI;
+import java.util.List;
+
+import org.apache.chemistry.property.Choice;
+import org.apache.chemistry.property.PropertyDefinition;
+import org.apache.chemistry.property.PropertyType;
+import org.apache.chemistry.property.Updatability;
+
+public class JcrPropertyDefinition implements PropertyDefinition {
+
+    private javax.jcr.nodetype.PropertyDefinition propDef;
+
+    public JcrPropertyDefinition(javax.jcr.nodetype.PropertyDefinition propDef) {
+        this.propDef = propDef;
+    }
+
+    public List<Choice> getChoices() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Serializable getDefaultValue() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String getDescription() {
+        return propDef.getName();
+    }
+
+    public String getDisplayName() {
+        return propDef.getName();
+    }
+
+    public String getEncoding() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String getId() {
+        return propDef.getName();
+    }
+
+    public int getMaxLength() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    public Integer getMaxValue() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Integer getMinValue() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String getName() {
+        return propDef.getName();
+    }
+
+    public int getPrecision() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    public URI getSchemaURI() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public PropertyType getType() {
+        switch (propDef.getRequiredType()) {
+            case javax.jcr.PropertyType.STRING:
+                return PropertyType.STRING;
+            case javax.jcr.PropertyType.LONG:
+                return PropertyType.INTEGER;
+            case javax.jcr.PropertyType.DOUBLE:
+                return PropertyType.DECIMAL;
+            case javax.jcr.PropertyType.DATE:
+                return PropertyType.DATETIME;
+            case javax.jcr.PropertyType.BOOLEAN:
+                return PropertyType.BOOLEAN;
+            case javax.jcr.PropertyType.REFERENCE:
+                return PropertyType.ID;
+            case javax.jcr.PropertyType.NAME:
+            case javax.jcr.PropertyType.BINARY:
+            case javax.jcr.PropertyType.PATH:
+            case javax.jcr.PropertyType.UNDEFINED:
+                return PropertyType.STRING;
+            default:
+                return null;
+        }
+    }
+
+    public Updatability getUpdatability() {
+        return propDef.isProtected() ? Updatability.READ_ONLY : Updatability.READ_WRITE;
+    }
+
+    public boolean isInherited() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    public boolean isMultiValued() {
+        return propDef.isMultiple();
+    }
+
+    public boolean isOpenChoice() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    public boolean isOrderable() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    public boolean isQueryable() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    public boolean isRequired() {
+        return propDef.isMandatory();
+    }
+
+    public boolean validates(Serializable value) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrPropertyDefinition.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrRepository.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrRepository.java?rev=771246&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrRepository.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrRepository.java Mon May  4 08:54:18 2009
@@ -0,0 +1,208 @@
+package org.apache.chemistry.jcr;
+
+import java.io.Serializable;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.NodeTypeManager;
+
+import org.apache.chemistry.Connection;
+import org.apache.chemistry.repository.JoinCapability;
+import org.apache.chemistry.repository.QueryCapability;
+import org.apache.chemistry.repository.Repository;
+import org.apache.chemistry.repository.RepositoryCapabilities;
+import org.apache.chemistry.repository.RepositoryEntry;
+import org.apache.chemistry.repository.RepositoryInfo;
+import org.apache.chemistry.type.BaseType;
+import org.apache.chemistry.type.Type;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
+
+public class JcrRepository implements Repository, RepositoryInfo,
+        RepositoryCapabilities {
+
+    private static final Log log = LogFactory.getLog(JcrRepository.class);
+    private javax.jcr.Repository repository;
+    private String workspace;
+
+    public JcrRepository(javax.jcr.Repository repository, String workspace) {
+        this.repository = repository;
+        this.workspace = workspace;
+    }
+
+    public JcrRepository(javax.jcr.Repository repository) {
+        this(repository, null);
+    }
+    
+    public Connection getConnection(Map<String, Serializable> parameters) {
+        // TODO pass credentials as parameters
+        SimpleCredentials creds = new SimpleCredentials("admin", "admin".toCharArray());
+
+        try {
+            return new JcrConnection(repository.login(creds, workspace), this);
+        } catch (RepositoryException e) {
+            String msg = "Unable to open connection.";
+            throw new RuntimeException(msg, e);
+        }
+    }
+
+    public <T> T getExtension(Class<T> klass) {
+        return null;
+    }
+
+    public RepositoryInfo getInfo() {
+        return this;
+    }
+
+    public Type getType(String typeId) {
+    	try {
+	        // TODO pass credentials as parameters
+	        SimpleCredentials creds = new SimpleCredentials("admin", "admin".toCharArray());
+	        
+	    	Session session = repository.login(creds, workspace);
+	    	
+	    	// TODO fetch the types only once, include other types
+	    	NodeTypeManager ntmgr = session.getWorkspace().getNodeTypeManager();
+	    	NodeType nt = ntmgr.getNodeType(typeId);
+	    	
+	    	BaseType baseType = BaseType.FOLDER;
+	    	if (nt.getName().equals("nt:file")) {
+	    		baseType = BaseType.DOCUMENT;
+	    	}
+	    	return new JcrType(nt, baseType);
+    	} catch (RepositoryException e) {
+    		String msg = "Unable get type: " + typeId;
+    		log.error(msg, e);
+    	}
+    	return null;
+    }
+
+    public Collection<Type> getTypes(String typeId,
+                                     boolean returnPropertyDefinitions) {
+    	boolean[] hasMoreItems = new boolean[1];
+    	return getTypes(typeId, returnPropertyDefinitions, 0, 0, hasMoreItems);
+    }
+
+    public List<Type> getTypes(String typeId,
+                               boolean returnPropertyDefinitions, int maxItems,
+                               int skipCount, boolean[] hasMoreItems) {
+    	
+    	try {
+	        // TODO pass credentials as parameters
+	        SimpleCredentials creds = new SimpleCredentials("admin", "admin".toCharArray());
+	        
+	        ArrayList<Type> result = new ArrayList<Type>();
+	        
+	    	Session session = repository.login(creds, workspace);
+	    	
+	    	// TODO fetch the types only once, include other types
+	    	NodeTypeManager ntmgr = session.getWorkspace().getNodeTypeManager();
+	    	result.add(new JcrType(ntmgr.getNodeType("rep:root"), BaseType.FOLDER));
+	    	result.add(new JcrType(ntmgr.getNodeType("nt:folder"), BaseType.FOLDER));
+	    	result.add(new JcrType(ntmgr.getNodeType("nt:file"), BaseType.DOCUMENT));
+	    	return result;
+    	} catch (RepositoryException e) {
+    		String msg = "Unable to retrieve node types.";
+    		log.error(msg, e);
+    	}
+        return null;
+    }
+
+    public String getId() {
+        return getName();
+    }
+
+    public String getName() {
+        return repository.getDescriptor(javax.jcr.Repository.REP_NAME_DESC);
+    }
+
+    public String getRelationshipName() {
+        return null;
+    }
+
+    public URI getURI() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    // ---------------------------------------------------------- RepositoryInfo
+
+    public RepositoryCapabilities getCapabilities() {
+        return this;
+    }
+
+    public String getDescription() {
+        return getName();
+    }
+
+    public String getProductName() {
+        return repository.getDescriptor(javax.jcr.Repository.REP_NAME_DESC);
+    }
+
+    public String getProductVersion() {
+        return repository.getDescriptor(javax.jcr.Repository.REP_VERSION_DESC);
+    }
+
+    public Collection<RepositoryEntry> getRelatedRepositories() {
+        return Collections.emptySet();
+    }
+
+    public Document getRepositorySpecificInformation() {
+        return null;
+    }
+
+    public String getRootFolderId() {
+        return JcrObjectEntry.escape("/");
+    }
+
+    public String getVendorName() {
+        return repository.getDescriptor(javax.jcr.Repository.REP_VENDOR_DESC);
+    }
+
+    public String getVersionSupported() {
+        return "0.61";
+    }
+
+    // -------------------------------------------------- RepositoryCapabilities
+
+    public JoinCapability getJoinCapability() {
+        return JoinCapability.NO_JOIN;
+    }
+
+    public QueryCapability getQueryCapability() {
+        return QueryCapability.BOTH_SEPARATE;
+    }
+
+    public boolean hasMultifiling() {
+        return true;
+    }
+
+    public boolean hasUnfiling() {
+        return true;
+    }
+
+    public boolean hasVersionSpecificFiling() {
+        return false;
+    }
+
+    public boolean isAllVersionsSearchable() {
+        return false;
+    }
+
+    public boolean isPWCSearchable() {
+        return false;
+    }
+
+    public boolean isPWCUpdatable() {
+        return false;
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrRepository.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrType.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrType.java?rev=771246&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrType.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrType.java Mon May  4 08:54:18 2009
@@ -0,0 +1,109 @@
+package org.apache.chemistry.jcr;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import javax.jcr.nodetype.NodeType;
+
+import org.apache.chemistry.property.PropertyDefinition;
+import org.apache.chemistry.type.BaseType;
+import org.apache.chemistry.type.ContentStreamPresence;
+import org.apache.chemistry.type.Type;
+
+public class JcrType implements Type {
+
+    private NodeType nodeType;
+    private BaseType baseType;
+
+    public JcrType(NodeType nodeType, BaseType baseType) {
+        this.nodeType = nodeType;
+        this.baseType = baseType;
+    }
+
+    public String[] getAllowedSourceTypes() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String[] getAllowedTargetTypes() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public BaseType getBaseType() {
+    	return baseType;
+    }
+
+    public String getBaseTypeQueryName() {
+    	return baseType.toString();
+    }
+
+    public ContentStreamPresence getContentStreamAllowed() {
+        if (baseType == BaseType.DOCUMENT) {
+            return ContentStreamPresence.ALLOWED;
+        } else {
+            return ContentStreamPresence.NOT_ALLOWED;
+        }
+    }
+
+    public String getDescription() {
+        return nodeType.getName();
+    }
+
+    public String getDisplayName() {
+        return nodeType.getName();
+    }
+
+    public String getId() {
+        return nodeType.getName();
+    }
+
+    public String getParentId() {
+        return null;
+    }
+
+    public PropertyDefinition getPropertyDefinition(String name) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Collection<PropertyDefinition> getPropertyDefinitions() {
+        // TODO Auto-generated method stub
+        return Collections.emptyList();
+    }
+
+    public String getQueryName() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public boolean isControllable() {
+        return false;
+    }
+
+    public boolean isCreatable() {
+        return true;
+    }
+
+    public boolean isFileable() {
+        return baseType == BaseType.DOCUMENT;
+    }
+
+    public boolean isIncludedInSuperTypeQuery() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    public boolean isQueryable() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    public boolean isVersionable() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrType.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/chemistry/trunk/chemistry/pom.xml
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/pom.xml?rev=771246&r1=771245&r2=771246&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/pom.xml (original)
+++ incubator/chemistry/trunk/chemistry/pom.xml Mon May  4 08:54:18 2009
@@ -35,6 +35,7 @@
     <module>chemistry-parent</module>
     <module>chemistry-api</module>
     <module>chemistry-commons</module>
+    <module>chemistry-jcr</module>
     <module>chemistry-tests</module>
     <module>chemistry-backups</module>
     <module>chemistry-atompub</module>