You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by dp...@apache.org on 2009/04/15 12:49:35 UTC

svn commit: r765129 [4/5] - in /jackrabbit/sandbox/chemistry: ./ chemistry-api/ chemistry-api/src/ chemistry-api/src/main/ chemistry-api/src/main/java/ chemistry-api/src/main/java/org/ chemistry-api/src/main/java/org/apache/ chemistry-api/src/main/java...

Added: jackrabbit/sandbox/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/ObjectElement.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/ObjectElement.java?rev=765129&view=auto
==============================================================================
--- jackrabbit/sandbox/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/ObjectElement.java (added)
+++ jackrabbit/sandbox/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/ObjectElement.java Wed Apr 15 10:49:31 2009
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ *
+ * Authors:
+ *     Florent Guillaume
+ */
+package org.apache.chemistry.atompub;
+
+import java.util.Map;
+
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.model.ExtensibleElementWrapper;
+import org.apache.chemistry.ObjectEntry;
+import org.apache.chemistry.property.Property;
+
+/**
+ * Abdera ElementWrapper for an AtomPub cmis:object element.
+ *
+ * @author Florent Guillaume
+ */
+public class ObjectElement extends ExtensibleElementWrapper {
+
+    public ObjectElement(Factory factory, ObjectEntry object,
+            String contentStreamURI) {
+        super(factory, CMIS.OBJECT);
+        setProperties(object.getProperties(), contentStreamURI);
+    }
+
+    public void setProperties(Map<String, Property> properties,
+            String contentStreamURI) {
+        PropertiesElement el = new PropertiesElement(getFactory(),
+                contentStreamURI);
+        addExtension(el);
+        el.setProperties(properties);
+    }
+
+    // TODO allowable actions
+
+}

Propchange: jackrabbit/sandbox/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/ObjectElement.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/ObjectElement.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/sandbox/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/PropertiesElement.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/PropertiesElement.java?rev=765129&view=auto
==============================================================================
--- jackrabbit/sandbox/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/PropertiesElement.java (added)
+++ jackrabbit/sandbox/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/PropertiesElement.java Wed Apr 15 10:49:31 2009
@@ -0,0 +1,208 @@
+/*
+ * 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.
+ *
+ * Authors:
+ *     Florent Guillaume
+ */
+package org.apache.chemistry.atompub;
+
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.ExtensibleElement;
+import org.apache.abdera.model.ExtensibleElementWrapper;
+import org.apache.chemistry.property.Property;
+import org.apache.chemistry.property.PropertyDefinition;
+import org.apache.chemistry.property.PropertyType;
+
+/**
+ * Abdera ElementWrapper for an AtomPub cmis:properties element.
+ *
+ * @author Florent Guillaume
+ */
+public class PropertiesElement extends ExtensibleElementWrapper {
+
+    /**
+     * Constructor. ContentStreamUri is special-cased as it depends on the
+     * server context (base URL).
+     */
+    public PropertiesElement(Factory factory, String contentStreamURI) {
+        super(factory, CMIS.PROPERTIES);
+        if (contentStreamURI != null) {
+            ExtensibleElement el = addExtension(CMIS.PROPERTY_URI);
+            el.setAttributeValue(CMIS.NAME, Property.CONTENT_STREAM_URI);
+            Element val = el.addExtension(CMIS.VALUE);
+            // don't merge these two lines as JDK 5 has problems compiling it
+            val.setText(contentStreamURI);
+
+            // Alfresco compat (incorrect property name and type):
+            el = addExtension(CMIS.PROPERTY_STRING);
+            el.setAttributeValue(CMIS.NAME, "ContentStreamURI");
+            val = el.addExtension(CMIS.VALUE);
+            // don't merge these two lines
+            val.setText(contentStreamURI);
+        }
+    }
+
+    public void setProperties(Map<String, Property> properties) {
+        for (String name : properties.keySet()) {
+            if (Property.CONTENT_STREAM_URI.equals(name)) {
+                // special-cased in constructor
+                continue;
+            }
+            setProperty(properties.get(name));
+        }
+    }
+
+    @SuppressWarnings("null")
+    public void setProperty(Property property) {
+        Serializable value = property.getValue();
+        if (value == null) {
+            // TODO assumes this isn't called several times
+            return;
+        }
+        PropertyDefinition def = property.getDefinition();
+        QName qname = propertyQName(def);
+        boolean multi = def.isMultiValued();
+        List<String> values = null;
+        if (multi) {
+            if (value.getClass().isArray()) {
+                values = new ArrayList<String>(Array.getLength(value));
+            } else { // TODO: complex property don't know how to handle skip it
+                return;
+            }
+        }
+        PropertyType type = def.getType();
+        switch (type) {
+        case STRING:
+        case ID:
+            if (multi) {
+                for (String v : (String[]) value) {
+                    values.add(v);
+                }
+            } else {
+                values = Collections.singletonList((String) value);
+            }
+            break;
+        case DECIMAL:
+            if (multi) {
+                for (BigDecimal v : (BigDecimal[]) value) {
+                    values.add(v.toString());
+                }
+            } else {
+                values = Collections.singletonList(((BigDecimal) value).toString());
+            }
+            break;
+        case INTEGER:
+            if (multi) {
+                for (Number v : (Number[]) value) {
+                    values.add(v.toString());
+                }
+            } else {
+                values = Collections.singletonList(((Number) value).toString());
+            }
+            break;
+        case BOOLEAN:
+            if (multi) {
+                for (Boolean v : (Boolean[]) value) {
+                    values.add(v.toString());
+                }
+            } else {
+                values = Collections.singletonList(((Boolean) value).toString());
+            }
+            break;
+        case DATETIME:
+            if (multi) {
+                for (Calendar v : (Calendar[]) value) {
+                    values.add(calendarString(v));
+                }
+            } else {
+                values = Collections.singletonList(calendarString((Calendar) value));
+            }
+            break;
+        case URI:
+            throw new UnsupportedOperationException(type.toString());
+        case XML:
+            throw new UnsupportedOperationException(type.toString());
+        case HTML:
+            throw new UnsupportedOperationException(type.toString());
+        default:
+            throw new UnsupportedOperationException(type.toString());
+        }
+        ExtensibleElement el = addExtension(qname);
+        el.setAttributeValue(CMIS.NAME, def.getName());
+        for (String s : values) {
+            Element val = el.addExtension(CMIS.VALUE);
+            // don't merge these two lines as JDK 5 has problems compiling it
+            val.setText(s);
+        }
+    }
+
+    protected static QName propertyQName(PropertyDefinition def) {
+        switch (def.getType()) {
+        case STRING:
+            return CMIS.PROPERTY_STRING;
+        case DECIMAL:
+            return CMIS.PROPERTY_DECIMAL;
+        case INTEGER:
+            return CMIS.PROPERTY_INTEGER;
+        case BOOLEAN:
+            return CMIS.PROPERTY_BOOLEAN;
+        case DATETIME:
+            return CMIS.PROPERTY_DATETIME;
+        case ID:
+            return CMIS.PROPERTY_ID;
+        case URI:
+            return CMIS.PROPERTY_URI;
+        case XML:
+            return CMIS.PROPERTY_XML;
+        case HTML:
+            return CMIS.PROPERTY_HTML;
+        default:
+            throw new UnsupportedOperationException(def.getType().toString());
+        }
+    }
+
+    @SuppressWarnings("boxing")
+    protected static String calendarString(Calendar cal) {
+        char sign;
+        int offset = cal.getTimeZone().getOffset(cal.getTimeInMillis()) / 60000;
+        if (offset < 0) {
+            offset = -offset;
+            sign = '-';
+        } else {
+            sign = '+';
+        }
+        return String.format("%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
+                cal.get(Calendar.YEAR), //
+                cal.get(Calendar.MONTH) + 1, //
+                cal.get(Calendar.DAY_OF_MONTH), //
+                cal.get(Calendar.HOUR_OF_DAY), //
+                cal.get(Calendar.MINUTE), //
+                cal.get(Calendar.SECOND), //
+                sign, offset / 60, offset % 60);
+    }
+    
+}

Propchange: jackrabbit/sandbox/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/PropertiesElement.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/PropertiesElement.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/sandbox/chemistry/chemistry-backups/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/chemistry/chemistry-backups/pom.xml?rev=765129&view=auto
==============================================================================
--- jackrabbit/sandbox/chemistry/chemistry-backups/pom.xml (added)
+++ jackrabbit/sandbox/chemistry/chemistry-backups/pom.xml Wed Apr 15 10:49:31 2009
@@ -0,0 +1,63 @@
+<?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-backups</artifactId>
+  <name>Chemistry Backups</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>com.thoughtworks.xstream</groupId>
+    	<artifactId>xstream</artifactId>
+    	<version>1.3</version>
+    	<scope>compile</scope>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.chemistry</groupId>
+    	<artifactId>chemistry-tests</artifactId>
+    	<scope>compile</scope>
+    </dependency>
+
+  </dependencies>
+</project>

Propchange: jackrabbit/sandbox/chemistry/chemistry-backups/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/sandbox/chemistry/chemistry-backups/src/main/java/org/apache/chemistry/backups/DataSerializer.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/chemistry/chemistry-backups/src/main/java/org/apache/chemistry/backups/DataSerializer.java?rev=765129&view=auto
==============================================================================
--- jackrabbit/sandbox/chemistry/chemistry-backups/src/main/java/org/apache/chemistry/backups/DataSerializer.java (added)
+++ jackrabbit/sandbox/chemistry/chemistry-backups/src/main/java/org/apache/chemistry/backups/DataSerializer.java Wed Apr 15 10:49:31 2009
@@ -0,0 +1,65 @@
+/*
+ * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser General Public License
+ * (LGPL) version 2.1 which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Contributors:
+ *     Stephane Lacoin [aka matic] (Nuxeo EP Software Engineer)
+ */
+package org.apache.chemistry.backups;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.mapper.MapperWrapper;
+
+/**
+ * @author Stephane Lacoin [aka matic] (Nuxeo EP Software Engineer)
+ * 
+ * @depend - - - InputStream
+ */
+public class DataSerializer<T> {
+
+    public DataSerializer(Class<T> clazz) {
+        xstream = new XStream() {
+            @Override
+            protected MapperWrapper wrapMapper(MapperWrapper next) {
+                return new MapperWrapper(next) {
+
+                    @SuppressWarnings("unchecked")
+                    public boolean shouldSerializeMember(Class definedIn,
+                            String fieldName) {
+                        return definedIn != Object.class ? super.shouldSerializeMember(
+                                definedIn, fieldName)
+                                : false;
+                    }
+
+                };
+            }
+
+        };
+        xstream.processAnnotations(clazz);
+    }
+
+    protected final XStream xstream;
+
+    
+    @SuppressWarnings("unchecked")
+    public T fromXML(InputStream input)  {
+        return (T) xstream.fromXML(input);
+    }
+    
+    public void toXML(T data, OutputStream output)  {
+        xstream.toXML(data,output);
+    }
+
+}

Propchange: jackrabbit/sandbox/chemistry/chemistry-backups/src/main/java/org/apache/chemistry/backups/DataSerializer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/chemistry/chemistry-backups/src/main/java/org/apache/chemistry/backups/DataSerializer.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/sandbox/chemistry/chemistry-backups/src/main/java/org/apache/chemistry/backups/RepositoryBackup.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/chemistry/chemistry-backups/src/main/java/org/apache/chemistry/backups/RepositoryBackup.java?rev=765129&view=auto
==============================================================================
--- jackrabbit/sandbox/chemistry/chemistry-backups/src/main/java/org/apache/chemistry/backups/RepositoryBackup.java (added)
+++ jackrabbit/sandbox/chemistry/chemistry-backups/src/main/java/org/apache/chemistry/backups/RepositoryBackup.java Wed Apr 15 10:49:31 2009
@@ -0,0 +1,97 @@
+/*
+ * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser General Public License
+ * (LGPL) version 2.1 which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Contributors:
+ *     matic
+ */
+package org.apache.chemistry.backups;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Calendar;
+
+import org.apache.chemistry.repository.Repository;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+/**
+ * @author matic
+ * 
+ */
+public class RepositoryBackup {
+
+    public final URL location;
+
+    public RepositoryBackup(URL url) {
+        this.location = url;
+    }
+
+    @XStreamAlias("data")
+    public static class Info {
+        String name = "";
+        long timestamp = 0L;
+        public String getName() {
+            return name;
+        }
+        public long getTimestamp() {
+            return timestamp;
+        }
+    }
+
+    @XStreamAlias("data")
+    protected static class Data {
+        String name;
+        long timestamp;
+        Repository repository;
+    }
+
+    public void save(Repository repo) throws IOException, URISyntaxException {
+        Data data = new Data();
+        data.timestamp = Calendar.getInstance().getTimeInMillis();
+        data.name = repo.getName();
+        data.repository = repo;
+        File file = new File(location.toURI());
+        file.delete();
+        file.createNewFile();
+        OutputStream stream = new FileOutputStream(file);
+        try {
+            new DataSerializer<Data>(Data.class).toXML(data, stream);
+        } finally {
+            stream.close();
+        }
+    }
+
+    public Repository load() throws IOException {
+        InputStream stream = location.openStream();
+        try {
+            Data data = new DataSerializer<Data>(Data.class).fromXML(stream);
+            return data.repository;
+        } finally {
+            stream.close();
+        }
+    }
+    
+    public Info loadInfo() throws IOException {
+        InputStream stream = location.openStream();
+        try {
+            return new DataSerializer<Info>(Info.class).fromXML(stream);
+        } finally {
+            stream.close();
+        }
+    }
+}

Propchange: jackrabbit/sandbox/chemistry/chemistry-backups/src/main/java/org/apache/chemistry/backups/RepositoryBackup.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/chemistry/chemistry-backups/src/main/java/org/apache/chemistry/backups/RepositoryBackup.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/sandbox/chemistry/chemistry-backups/src/test/java/TestBackup.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/chemistry/chemistry-backups/src/test/java/TestBackup.java?rev=765129&view=auto
==============================================================================
--- jackrabbit/sandbox/chemistry/chemistry-backups/src/test/java/TestBackup.java (added)
+++ jackrabbit/sandbox/chemistry/chemistry-backups/src/test/java/TestBackup.java Wed Apr 15 10:49:31 2009
@@ -0,0 +1,73 @@
+/*
+ * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser General Public License
+ * (LGPL) version 2.1 which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Contributors:
+ *     Stephane Lacoin [aka matic] (Nuxeo EP Software Engineer)
+ */
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.chemistry.Connection;
+import org.apache.chemistry.Folder;
+import org.apache.chemistry.ObjectEntry;
+import org.apache.chemistry.backups.RepositoryBackup;
+import org.apache.chemistry.backups.RepositoryBackup.Info;
+import org.apache.chemistry.impl.simple.SimpleRepository;
+import org.apache.chemistry.repository.Repository;
+import org.apache.chemistry.test.RepositoryTestFactory;
+
+
+
+public class TestBackup extends TestCase {
+    
+    protected URL doResolvePath(String name) throws MalformedURLException {
+        URL folderLocation = getClass().getResource("/");
+        URL fileLocation = new URL(folderLocation.toExternalForm() + name + ".xml");
+        return fileLocation;
+    }
+    
+    public Folder getRootFolder(Repository repo) {
+        Connection conn = repo.getConnection(null);
+        return conn.getRootFolder();
+    }
+    
+    public List<ObjectEntry> getEntries(Repository repo) {
+        Connection conn = repo.getConnection(null);
+        Folder folder = conn.getRootFolder();
+        return folder.getChildren(null, null);
+    }
+    
+    public void testSaveAndRestore() throws IOException, URISyntaxException {
+        SimpleRepository source = RepositoryTestFactory.makeRepository();
+        RepositoryBackup backup = new RepositoryBackup(doResolvePath("backup"));
+        backup.save(source);
+        Info info = backup.loadInfo();
+        String repoName = source.getName();
+        String infoName = info.getName();
+        assertEquals(repoName,infoName);
+        Repository copy = backup.load();
+        assertNotNull(copy);
+        List<ObjectEntry> sourceEntries = getEntries(source);
+        List<ObjectEntry> copyEntries = getEntries(copy);
+        assertEquals(sourceEntries.size(), copyEntries.size());
+        assertEquals(sourceEntries.get(0), copyEntries.get(0));
+    }
+
+   
+}

Propchange: jackrabbit/sandbox/chemistry/chemistry-backups/src/test/java/TestBackup.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/chemistry/chemistry-backups/src/test/java/TestBackup.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/sandbox/chemistry/chemistry-commons/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/chemistry/chemistry-commons/pom.xml?rev=765129&view=auto
==============================================================================
--- jackrabbit/sandbox/chemistry/chemistry-commons/pom.xml (added)
+++ jackrabbit/sandbox/chemistry/chemistry-commons/pom.xml Wed Apr 15 10:49:31 2009
@@ -0,0 +1,46 @@
+<?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-commons</artifactId>
+  <name>Chemistry Commons</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.chemistry</groupId>
+      <artifactId>chemistry-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+</project>

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleConnection.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleConnection.java?rev=765129&view=auto
==============================================================================
--- jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleConnection.java (added)
+++ jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleConnection.java Wed Apr 15 10:49:31 2009
@@ -0,0 +1,589 @@
+/*
+ * 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.
+ *
+ * Authors:
+ *     Florent Guillaume
+ */
+package org.apache.chemistry.impl.simple;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+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.property.Property;
+import org.apache.chemistry.property.PropertyDefinition;
+import org.apache.chemistry.repository.Repository;
+import org.apache.chemistry.type.BaseType;
+import org.apache.chemistry.type.ContentStreamPresence;
+import org.apache.chemistry.type.Type;
+
+public class SimpleConnection implements Connection, SPI {
+
+    protected final SimpleRepository repository;
+
+    protected final SimpleFolder rootFolder;
+
+    public SimpleConnection(SimpleRepository repository) {
+        this.repository = repository;
+        rootFolder = (SimpleFolder) getObject(
+                repository.getInfo().getRootFolderId(), ReturnVersion.THIS);
+    }
+
+    public Connection getConnection() {
+        return this;
+    }
+
+    public SPI getSPI() {
+        return this;
+    }
+
+    public void close() {
+        // TODO disable use of this connection
+    }
+
+    public Repository getRepository() {
+        return repository;
+    }
+
+    public Folder getRootFolder() {
+        return rootFolder;
+    }
+
+    public ObjectEntry getRootEntry() {
+        return rootFolder;
+    }
+
+    public List<ObjectEntry> getChildren(ObjectEntry folder) {
+        return getChildren(folder.getId(), null, null, false, false,
+                Integer.MAX_VALUE, 0, null, new boolean[1]);
+    }
+
+    /*
+     * ----- Factories -----
+     */
+
+    public Document newDocument(String typeId, ObjectEntry folder) {
+        Type type = repository.getType(typeId);
+        if (type == null || type.getBaseType() != BaseType.DOCUMENT) {
+            throw new IllegalArgumentException(typeId);
+        }
+        SimpleData data = new SimpleData(typeId);
+        if (folder != null) {
+            data.put(Property.PARENT_ID, folder.getId());
+        }
+        return new SimpleDocument(data, this);
+    }
+
+    public Folder newFolder(String typeId, ObjectEntry folder) {
+        Type type = repository.getType(typeId);
+        if (type == null || type.getBaseType() != BaseType.FOLDER) {
+            throw new IllegalArgumentException(typeId);
+        }
+        SimpleData data = new SimpleData(typeId);
+        if (folder != null) {
+            data.put(Property.PARENT_ID, folder.getId());
+        }
+        return new SimpleFolder(data, this);
+    }
+
+    public Relationship newRelationship(String typeId) {
+        Type type = repository.getType(typeId);
+        if (type == null || type.getBaseType() != BaseType.RELATIONSHIP) {
+            throw new IllegalArgumentException(typeId);
+        }
+        SimpleData data = new SimpleData(typeId);
+        return new SimpleRelationship(data, this);
+    }
+
+    public Policy newPolicy(String typeId, ObjectEntry folder) {
+        Type type = repository.getType(typeId);
+        if (type == null || type.getBaseType() != BaseType.POLICY) {
+            throw new IllegalArgumentException(typeId);
+        }
+        SimpleData data = new SimpleData(typeId);
+        if (folder != null) {
+            data.put(Property.PARENT_ID, folder.getId());
+        }
+        return new SimplePolicy(data, this);
+    }
+
+    /*
+     * Called by save() for new objects.
+     */
+    protected void saveObject(SimpleObject object) {
+        SimpleData data = object.data;
+        Map<String, Serializable> update = new HashMap<String, Serializable>();
+
+        // generate an ID
+        String id = repository.generateId();
+        update.put(Property.ID, id);
+
+        // check mandatory properties
+        Type type = object.getType();
+        for (PropertyDefinition pd : type.getPropertyDefinitions()) {
+            String name = pd.getName();
+            if (Property.ID.equals(name)) {
+                // ignore, set later
+                continue;
+            }
+            if (pd.isRequired() && !data.containsKey(name)) {
+                if (Property.NAME.equals(name)) {
+                    update.put(Property.NAME, id);
+                } else if (Property.CREATED_BY.equals(name)) {
+                    update.put(Property.CREATED_BY, "system"); // TODO
+                } else if (Property.CREATION_DATE.equals(name)) {
+                    update.put(Property.CREATION_DATE, Calendar.getInstance());
+                } else if (Property.LAST_MODIFIED_BY.equals(name)) {
+                    update.put(Property.LAST_MODIFIED_BY, "system"); // TODO
+                } else if (Property.LAST_MODIFICATION_DATE.equals(name)) {
+                    update.put(Property.LAST_MODIFICATION_DATE,
+                            Calendar.getInstance());
+                } else if (Property.CONTENT_STREAM_ALLOWED.equals(name)) {
+                    update.put(Property.CONTENT_STREAM_ALLOWED, "allowed");
+                } else if (Property.IS_LATEST_VERSION.equals(name)) {
+                    update.put(Property.IS_LATEST_VERSION, Boolean.TRUE);
+                } else if (Property.IS_LATEST_MAJOR_VERSION.equals(name)) {
+                    update.put(Property.IS_LATEST_MAJOR_VERSION, Boolean.TRUE);
+                } else if (Property.IS_VERSION_SERIES_CHECKED_OUT.equals(name)) {
+                    update.put(Property.IS_VERSION_SERIES_CHECKED_OUT,
+                            Boolean.FALSE);
+                } else if (Property.VERSION_SERIES_ID.equals(name)) {
+                    update.put(Property.VERSION_SERIES_ID, id);
+                } else if (Property.VERSION_LABEL.equals(name)) {
+                    update.put(Property.VERSION_LABEL, "1.0");
+                } else {
+                    throw new RuntimeException("Missing property: " + name); // TODO
+                }
+            }
+        }
+
+        byte[] contentBytes = (byte[]) data.get(SimpleDocument.CONTENT_BYTES_KEY);
+        if (type.getContentStreamAllowed() == ContentStreamPresence.REQUIRED
+                && contentBytes == null) {
+            throw new RuntimeException("Content stream required"); // TODO
+        }
+
+        // content stream
+        if (contentBytes != null) {
+            update.put(Property.CONTENT_STREAM_LENGTH,
+                    Integer.valueOf(contentBytes.length));
+        }
+        // update data once we know there's no error
+        data.putAll(update);
+
+        // properties
+        repository.datas.put(id, data); // TODO clone data?
+
+        if (contentBytes == null) {
+            repository.contentBytes.remove(id);
+        } else {
+            repository.contentBytes.put(id, contentBytes);
+        }
+
+        // parents/children
+        String parentId = (String) data.get(Property.PARENT_ID);
+        if (type.getBaseType() == BaseType.FOLDER) {
+            // new folder, empty set of children
+            repository.children.put(id, repository.newSet());
+        } else {
+            // only folders have this property
+            data.remove(Property.PARENT_ID);
+        }
+        if (parentId != null) {
+            // this object is filed
+            // pointer to parent
+            Set<String> parents = repository.newSet();
+            parents.add(parentId);
+            repository.parents.put(id, parents);
+            // new pointer to child
+            repository.children.get(parentId).add(id);
+        }
+    }
+
+    /*
+     * ----- Navigation Services -----
+     */
+
+    public List<ObjectEntry> getDescendants(String folderId, BaseType type,
+            int depth, String filter, boolean includeAllowableActions,
+            boolean includeRelationships, String orderBy) {
+        // TODO Auto-generated method stub
+        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) {
+        // TODO type and orderBy
+        Set<String> ids = repository.children.get(folderId);
+        List<ObjectEntry> all = new ArrayList<ObjectEntry>(ids.size());
+        for (String id : ids) {
+            SimpleData data = repository.datas.get(id);
+            // could build a full Object, but some implementations won't
+            all.add(new SimpleObjectEntry(data, this));
+        }
+
+        int fromIndex = skipCount;
+        if (fromIndex < 0 || fromIndex > all.size()) {
+            hasMoreItems[0] = false;
+            return Collections.emptyList();
+        }
+        if (maxItems == 0) {
+            maxItems = all.size();
+        }
+        int toIndex = skipCount + maxItems;
+        if (toIndex > all.size()) {
+            toIndex = all.size();
+        }
+        hasMoreItems[0] = toIndex < all.size();
+        return all.subList(fromIndex, toIndex);
+    }
+
+    public List<ObjectEntry> getFolderParent(String folderId, String filter,
+            boolean includeAllowableActions, boolean includeRelationships,
+            boolean returnToRoot) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<ObjectEntry> getObjectParents(String objectId,
+            String filter, boolean includeAllowableActions,
+            boolean includeRelationships) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<ObjectEntry> getCheckedoutDocuments(String folderId,
+            String filter, boolean includeAllowableActions,
+            boolean includeRelationships, int maxItems, int skipCount,
+            boolean[] hasMoreItems) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * ----- Object Services -----
+     */
+
+    public String createDocument(String typeId,
+            Map<String, Serializable> properties, String folderId,
+            ContentStream contentStream, VersioningState versioningState) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public String createFolder(String typeId,
+            Map<String, Serializable> properties, String folderId) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public String createRelationship(String typeId,
+            Map<String, Serializable> properties, String sourceId,
+            String targetId) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public String createPolicy(String typeId,
+            Map<String, Serializable> properties, String folderId) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<String> getAllowableActions(String objectId, String asUser) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public ObjectEntry getProperties(String objectId,
+            ReturnVersion returnVersion, String filter,
+            boolean includeAllowableActions, boolean includeRelationships) {
+        SimpleData data = repository.datas.get(objectId);
+        if (data == null) {
+            throw new RuntimeException("Not found: " + objectId); // TODO
+        }
+        return new SimpleObjectEntry(data, this);
+    }
+
+    public CMISObject getObject(String objectId, ReturnVersion returnVersion) {
+        // TODO returnVersion
+        SimpleData data = repository.datas.get(objectId);
+        if (data == null) {
+            throw new RuntimeException("Not found: " + objectId); // TODO
+        }
+        String typeId = (String) data.get(Property.TYPE_ID);
+        switch (repository.getType(typeId).getBaseType()) {
+        case DOCUMENT:
+            return new SimpleDocument(data, this);
+        case FOLDER:
+            return new SimpleFolder(data, this);
+        case RELATIONSHIP:
+            return new SimpleRelationship(data, this);
+        case POLICY:
+            return new SimplePolicy(data, this);
+        }
+        throw new RuntimeException();
+    }
+
+    public InputStream getContentStream(String documentId, int offset,
+            int length) {
+        byte[] bytes = repository.contentBytes.get(documentId);
+        if (bytes == null) {
+            return null;
+        }
+        if (length == -1) {
+            length = bytes.length;
+        }
+        return new ByteArrayInputStream(bytes, offset, length);
+    }
+
+    public void setContentStream(String documentId, boolean overwrite,
+            ContentStream contentStream) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void deleteContentStream(String documentId) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public String updateProperties(String objectId, String changeToken,
+            Map<String, Serializable> properties) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void moveObject(String objectId, String targetFolderId,
+            String sourceFolderId) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void moveObject(ObjectEntry object, ObjectEntry targetFolder,
+            ObjectEntry sourceFolder) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void deleteObject(String objectId) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void deleteObject(ObjectEntry object) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<String> deleteTree(String folderId, Unfiling unfiling,
+            boolean continueOnFailure) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<String> deleteTree(ObjectEntry folder, Unfiling unfiling,
+            boolean continueOnFailure) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void addObjectToFolder(String objectId, String folderId) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void addObjectToFolder(ObjectEntry object, ObjectEntry folder) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void removeObjectFromFolder(String objectId, String folderId) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void removeObjectFromFolder(ObjectEntry object, ObjectEntry folder) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * ----- Discovery Services -----
+     */
+
+    public Collection<ObjectEntry> query(String statement,
+            boolean searchAllVersions, boolean includeAllowableActions,
+            boolean includeRelationships, int maxItems, int skipCount,
+            boolean[] hasMoreItems) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<ObjectEntry> query(String statement,
+            boolean searchAllVersions) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * ----- Versioning Services -----
+     */
+
+    public String checkOut(String documentId, boolean[] contentCopied) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public CMISObject checkOut(ObjectEntry document) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void cancelCheckOut(String documentId) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void cancelCheckOut(ObjectEntry document) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public String checkIn(String documentId, boolean major,
+            Map<String, Serializable> properties, ContentStream contentStream,
+            String comment) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public CMISObject checkIn(ObjectEntry document, boolean major,
+            String comment) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public Map<String, Serializable> getPropertiesOfLatestVersion(
+            String versionSeriesId, boolean majorVersion, String filter) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public CMISObject getLatestVersion(ObjectEntry document, boolean major) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<ObjectEntry> getAllVersions(String versionSeriesId,
+            String filter) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<ObjectEntry> getAllVersions(ObjectEntry document,
+            String filter) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void deleteAllVersions(String versionSeriesId) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void deleteAllVersions(ObjectEntry document) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * ----- Relationship Services -----
+     */
+
+    public List<ObjectEntry> getRelationships(String objectId,
+            RelationshipDirection direction, String typeId,
+            boolean includeSubRelationshipTypes, String filter,
+            String includeAllowableActions, int maxItems, int skipCount,
+            boolean[] hasMoreItems) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public List<ObjectEntry> getRelationships(ObjectEntry object,
+            RelationshipDirection direction, String typeId,
+            boolean includeSubRelationshipTypes) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * ----- Policy Services -----
+     */
+
+    public void applyPolicy(String policyId, String objectId) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void applyPolicy(Policy policy, ObjectEntry object) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void removePolicy(String policyId, String objectId) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public void removePolicy(Policy policy, ObjectEntry object) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<ObjectEntry> getAppliedPolicies(String policyId,
+            String filter) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<Policy> getAppliedPolicies(ObjectEntry object) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+}

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleConnection.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleConnection.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleContentStream.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleContentStream.java?rev=765129&view=auto
==============================================================================
--- jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleContentStream.java (added)
+++ jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleContentStream.java Wed Apr 15 10:49:31 2009
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ *
+ * Authors:
+ *     Florent Guillaume
+ */
+package org.apache.chemistry.impl.simple;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+
+import org.apache.chemistry.ContentStream;
+
+/**
+ * Simple {@link ContentStream} storing the stream in memory.
+ *
+ * @author Florent Guillaume
+ */
+public class SimpleContentStream implements ContentStream {
+
+    protected final String mimeType;
+
+    protected final String filename;
+
+    protected final URI uri;
+
+    protected final byte[] bytes;
+
+    protected final long length;
+
+    public SimpleContentStream(byte[] bytes, String mimeType, String filename,
+            URI uri) throws IOException {
+        this.mimeType = mimeType;
+        this.filename = filename;
+        this.uri = uri;
+        this.bytes = bytes;
+        length = bytes.length;
+    }
+
+    public SimpleContentStream(InputStream stream, String mimeType,
+            String filename, URI uri) throws IOException {
+        this.mimeType = mimeType;
+        this.filename = filename;
+        this.uri = uri;
+        bytes = getBytes(stream);
+        length = bytes.length;
+    }
+
+    protected static byte[] getBytes(InputStream stream) throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        byte[] buf = new byte[1024];
+        int n;
+        while ((n = stream.read(buf)) != -1) {
+            out.write(buf, 0, n);
+        }
+        return out.toByteArray();
+    }
+
+    public long getLength() {
+        return length;
+    }
+
+    public String getMimeType() {
+        return mimeType;
+    }
+
+    public String getFilename() {
+        return filename;
+    }
+
+    public URI getURI() {
+        return uri;
+    }
+
+    public InputStream getStream() {
+        return new ByteArrayInputStream(bytes);
+    }
+
+}

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleContentStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleContentStream.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleData.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleData.java?rev=765129&view=auto
==============================================================================
--- jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleData.java (added)
+++ jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleData.java Wed Apr 15 10:49:31 2009
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ *
+ * Authors:
+ *     Florent Guillaume
+ */
+package org.apache.chemistry.impl.simple;
+
+import java.io.Serializable;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.chemistry.property.Property;
+
+/**
+ * The data held in the repository for one object.
+ * <p>
+ * This also holds data for objects not yet saved, in this case the ID is not
+ * set, and the PARENT_ID is temporarily set to the parent's ID.
+ *
+ * @author Florent Guillaume
+ */
+public class SimpleData extends ConcurrentHashMap<String, Serializable> {
+
+    private static final long serialVersionUID = 1L;
+
+    public SimpleData(String typeId) {
+        put(Property.TYPE_ID, typeId);
+    }
+
+}

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleData.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleData.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleDocument.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleDocument.java?rev=765129&view=auto
==============================================================================
--- jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleDocument.java (added)
+++ jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleDocument.java Wed Apr 15 10:49:31 2009
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ *
+ * Authors:
+ *     Florent Guillaume
+ */
+package org.apache.chemistry.impl.simple;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+
+import org.apache.chemistry.ContentStream;
+import org.apache.chemistry.Document;
+import org.apache.chemistry.property.Property;
+import org.apache.chemistry.type.ContentStreamPresence;
+
+public class SimpleDocument extends SimpleObject implements Document {
+
+    public SimpleDocument(SimpleData data, SimpleConnection connection) {
+        super(data, connection);
+    }
+
+    protected static final String CONTENT_BYTES_KEY = "__content__";
+
+    protected byte[] getContentBytes() {
+        return (byte[]) data.get(CONTENT_BYTES_KEY);
+    }
+    
+    public InputStream getStream() {
+    	byte[] contentBytes = getContentBytes();
+        if (contentBytes == null) {
+            return null;
+        }
+        return new ByteArrayInputStream(contentBytes);
+    }
+
+    public ContentStream getContentStream() {
+    	byte[] contentBytes = getContentBytes();
+        if (contentBytes == null) {
+            return null;
+        }
+        // length is recomputed, no need to read it
+        String mimeType = getString(Property.CONTENT_STREAM_MIME_TYPE);
+        String filename = getString(Property.CONTENT_STREAM_FILENAME);
+        URI uri = getURI(Property.CONTENT_STREAM_URI);
+        try {
+            return new SimpleContentStream(contentBytes, mimeType, filename,
+                    uri);
+        } catch (IOException e) {
+            // cannot happen, reading from ByteArrayInputStream
+            return null;
+        }
+    }
+
+    public void setContentStream(ContentStream contentStream)
+            throws IOException {
+        ContentStreamPresence csa = getType().getContentStreamAllowed();
+        if (csa == ContentStreamPresence.NOT_ALLOWED && contentStream != null) {
+            throw new RuntimeException("Content stream not allowed"); // TODO
+        } else if (csa == ContentStreamPresence.REQUIRED
+                && contentStream == null) {
+            throw new RuntimeException("Content stream required"); // TODO
+        }
+        if (contentStream == null) {
+            _setValue(Property.CONTENT_STREAM_LENGTH, null);
+            _setValue(Property.CONTENT_STREAM_MIME_TYPE, null);
+            _setValue(Property.CONTENT_STREAM_FILENAME, null);
+            _setValue(Property.CONTENT_STREAM_URI, null);
+            data.remove(CONTENT_BYTES_KEY);
+        } else {
+            _setValue(Property.CONTENT_STREAM_LENGTH,
+                    Integer.valueOf((int) contentStream.getLength())); // cast?
+            _setValue(Property.CONTENT_STREAM_MIME_TYPE,
+                    contentStream.getMimeType());
+            _setValue(Property.CONTENT_STREAM_FILENAME,
+                    contentStream.getFilename());
+            _setValue(Property.CONTENT_STREAM_URI, contentStream.getURI());
+            data.put(CONTENT_BYTES_KEY,
+                    SimpleContentStream.getBytes(contentStream.getStream()));
+        }
+    }
+
+}

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleDocument.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleDocument.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleFolder.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleFolder.java?rev=765129&view=auto
==============================================================================
--- jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleFolder.java (added)
+++ jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleFolder.java Wed Apr 15 10:49:31 2009
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ *
+ * Authors:
+ *     Florent Guillaume
+ */
+package org.apache.chemistry.impl.simple;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.chemistry.Document;
+import org.apache.chemistry.ObjectEntry;
+import org.apache.chemistry.Folder;
+import org.apache.chemistry.type.BaseType;
+
+public class SimpleFolder extends SimpleObject implements Folder {
+
+    public SimpleFolder(SimpleData data, SimpleConnection connection) {
+        super(data, connection);
+    }
+
+    public List<ObjectEntry> getChildren(BaseType type, String orderBy) {
+        // TODO type and orderBy
+        Set<String> ids = connection.repository.children.get(getId());
+        List<ObjectEntry> children = new ArrayList<ObjectEntry>(ids.size());
+        for (String id : ids) {
+            SimpleData d = connection.repository.datas.get(id);
+            // could build a full Object, but some implementations won't
+            children.add(new SimpleObjectEntry(d, connection));
+        }
+        return children;
+    }
+
+    public Document newDocument(String typeId) {
+        return connection.newDocument(typeId, this);
+    }
+
+    public Folder newFolder(String typeId) {
+        return connection.newFolder(typeId, this);
+    }
+
+}

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleFolder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleFolder.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleObject.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleObject.java?rev=765129&view=auto
==============================================================================
--- jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleObject.java (added)
+++ jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleObject.java Wed Apr 15 10:49:31 2009
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ *
+ * Authors:
+ *     Florent Guillaume
+ */
+package org.apache.chemistry.impl.simple;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.chemistry.CMISObject;
+import org.apache.chemistry.Document;
+import org.apache.chemistry.Folder;
+import org.apache.chemistry.Policy;
+import org.apache.chemistry.Relationship;
+import org.apache.chemistry.property.Property;
+import org.apache.chemistry.type.BaseType;
+
+public class SimpleObject extends SimpleObjectEntry implements CMISObject {
+
+    protected SimpleObject(SimpleData data, SimpleConnection connection) {
+        super(data, connection);
+    }
+
+    @Override
+    public Document getDocument() {
+        if (getType().getBaseType() != BaseType.DOCUMENT) {
+            throw new RuntimeException("Not a document: " + getId());
+        }
+        return (Document) this;
+    }
+
+    @Override
+    public Folder getFolder() {
+        if (getType().getBaseType() != BaseType.FOLDER) {
+            throw new RuntimeException("Not a folder: " + getId());
+        }
+        return (Folder) this;
+    }
+
+    @Override
+    public Relationship getRelationship() {
+        if (getType().getBaseType() != BaseType.RELATIONSHIP) {
+            throw new RuntimeException("Not a relationship: " + getId());
+        }
+        return (Relationship) this;
+    }
+
+    @Override
+    public Policy getPolicy() {
+        if (getType().getBaseType() != BaseType.POLICY) {
+            throw new RuntimeException("Not a policy: " + getId());
+        }
+        return (Policy) this;
+    }
+
+    /*
+     * ----- CMISObject -----
+     */
+
+    public Folder getParent() {
+        Set<String> parents = connection.repository.parents.get(getId());
+        if (parents == SimpleRepository.NO_PARENT) {
+            return null;
+        }
+        if (parents.size() != 1) {
+            throw new RuntimeException("Several parents for: " + getId()); // TODO
+        }
+        String pid = parents.iterator().next();
+        SimpleData data = connection.repository.datas.get(pid);
+        return new SimpleFolder(data, connection);
+    }
+
+    public void setValue(String name, Serializable value) {
+        SimplePropertyDefinition pd = (SimplePropertyDefinition) getType().getPropertyDefinition(
+                name);
+        if (pd == null) {
+            throw new IllegalArgumentException(name);
+        }
+        String error = pd.validationError(value);
+        if (error != null) {
+            throw new RuntimeException("Property " + name + ": " + error); // TODO
+        }
+
+        _setValue(name, value);
+    }
+
+    protected void _setValue(String name, Serializable value) {
+        if (value == null) {
+            data.remove(name);
+        } else {
+            data.put(name, value);
+        }
+    }
+
+    public void setValues(Map<String, Serializable> values) {
+        // don't use putAll as we want to do type checks
+        for (String name : values.keySet()) {
+            setValue(name, values.get(name));
+        }
+    }
+
+    public void save() {
+        if (getId() == null) {
+            connection.saveObject(this);
+        }
+    }
+
+    /*
+     * ----- convenience methods for specific properties -----
+     */
+
+    public void setName(String name) {
+        setValue(Property.NAME, name);
+    }
+
+}

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleObject.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleObject.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleObjectEntry.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleObjectEntry.java?rev=765129&view=auto
==============================================================================
--- jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleObjectEntry.java (added)
+++ jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleObjectEntry.java Wed Apr 15 10:49:31 2009
@@ -0,0 +1,322 @@
+/*
+ * 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.
+ *
+ * Authors:
+ *     Florent Guillaume
+ */
+package org.apache.chemistry.impl.simple;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.net.URI;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.chemistry.Document;
+import org.apache.chemistry.ObjectEntry;
+import org.apache.chemistry.Folder;
+import org.apache.chemistry.Policy;
+import org.apache.chemistry.Relationship;
+import org.apache.chemistry.property.Property;
+import org.apache.chemistry.property.PropertyDefinition;
+import org.apache.chemistry.type.BaseType;
+import org.apache.chemistry.type.Type;
+
+public class SimpleObjectEntry implements ObjectEntry {
+
+    protected final SimpleData data;
+
+    protected final SimpleConnection connection;
+
+    protected SimpleObjectEntry(SimpleData data, SimpleConnection connection) {
+        this.data = data;
+        this.connection = connection;
+    }
+
+    public Type getType() {
+        String typeId = (String) data.get(Property.TYPE_ID);
+        return connection.repository.getType(typeId);
+    }
+
+    public Property getProperty(String name) {
+        return new SimpleProperty(this, name);
+    }
+
+    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));
+        }
+        return properties;
+    }
+
+    public Serializable getValue(String name) {
+        PropertyDefinition propertyDefinition = getType().getPropertyDefinition(
+                name);
+        if (propertyDefinition == null) {
+            throw new IllegalArgumentException(name);
+        }
+        return data.get(name);
+    }
+
+    public Collection<String> getAllowableActions() {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    public Collection<ObjectEntry> getRelationships() {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * ----- link to Document/Folder/etc classes -----
+     */
+
+    public Document getDocument() {
+        if (getType().getBaseType() != BaseType.DOCUMENT) {
+            throw new RuntimeException("Not a document: " + getId());
+        }
+        return new SimpleDocument(data, connection);
+    }
+
+    public Folder getFolder() {
+        if (getType().getBaseType() != BaseType.FOLDER) {
+            throw new RuntimeException("Not a folder: " + getId());
+        }
+        return new SimpleFolder(data, connection);
+    }
+
+    public Relationship getRelationship() {
+        if (getType().getBaseType() != BaseType.RELATIONSHIP) {
+            throw new RuntimeException("Not a relationship: " + getId());
+        }
+        return new SimpleRelationship(data, connection);
+    }
+
+    public Policy getPolicy() {
+        if (getType().getBaseType() != BaseType.POLICY) {
+            throw new RuntimeException("Not a policy: " + getId());
+        }
+        return new SimplePolicy(data, connection);
+    }
+
+    /*
+     * ----- convenience methods -----
+     */
+
+    public String getString(String name) {
+        return (String) getValue(name);
+    }
+
+    public String[] getStrings(String name) {
+        return (String[]) getValue(name);
+    }
+
+    public BigDecimal getDecimal(String name) {
+        return (BigDecimal) getValue(name);
+    }
+
+    public BigDecimal[] getDecimals(String name) {
+        return (BigDecimal[]) getValue(name);
+    }
+
+    public Integer getInteger(String name) {
+        return (Integer) getValue(name);
+    }
+
+    public Integer[] getIntegers(String name) {
+        return (Integer[]) getValue(name);
+    }
+
+    public Boolean getBoolean(String name) {
+        return (Boolean) getValue(name);
+    }
+
+    public Boolean[] getBooleans(String name) {
+        return (Boolean[]) getValue(name);
+    }
+
+    public Calendar getDateTime(String name) {
+        return (Calendar) getValue(name);
+    }
+
+    public Calendar[] getDateTimes(String name) {
+        return (Calendar[]) getValue(name);
+    }
+
+    public URI getURI(String name) {
+        return (URI) getValue(name);
+    }
+
+    public URI[] getURIs(String name) {
+        return (URI[]) getValue(name);
+    }
+
+    public String getId(String name) {
+        return (String) getValue(name);
+    }
+
+    public String[] getIds(String name) {
+        return (String[]) getValue(name);
+    }
+
+    public String getXML(String name) {
+        return (String) getValue(name);
+    }
+
+    public String[] getXMLs(String name) {
+        return (String[]) getValue(name);
+    }
+
+    public String getHTML(String name) {
+        return (String) getValue(name);
+    }
+
+    public String[] getHTMLs(String name) {
+        return (String[]) getValue(name);
+    }
+
+    /*
+     * ----- convenience methods for specific properties -----
+     */
+
+    public String getId() {
+        return getString(Property.ID);
+    }
+
+    public URI getURI() {
+        return getURI(Property.URI);
+    }
+
+    public String getTypeId() {
+        return getId(Property.TYPE_ID);
+    }
+
+    public String getCreatedBy() {
+        return getString(Property.CREATED_BY);
+    }
+
+    public Calendar getCreationDate() {
+        return getDateTime(Property.CREATION_DATE);
+    }
+
+    public String getLastModifiedBy() {
+        return getString(Property.LAST_MODIFIED_BY);
+    }
+
+    public Calendar getLastModificationDate() {
+        return getDateTime(Property.LAST_MODIFICATION_DATE);
+    }
+
+    public String getChangeToken() {
+        return getString(Property.CHANGE_TOKEN);
+    }
+
+    public String getName() {
+        return getString(Property.NAME);
+    }
+
+    public boolean isImmutable() {
+        Boolean b = getBoolean(Property.IS_IMMUTABLE);
+        return b == null ? false : b.booleanValue();
+    }
+
+    public boolean isLatestVersion() {
+        Boolean b = getBoolean(Property.IS_LATEST_VERSION);
+        return b == null ? false : b.booleanValue();
+    }
+
+    public boolean isMajorVersion() {
+        Boolean b = getBoolean(Property.IS_MAJOR_VERSION);
+        return b == null ? false : b.booleanValue();
+    }
+
+    public boolean isLatestMajorVersion() {
+        Boolean b = getBoolean(Property.IS_LATEST_MAJOR_VERSION);
+        return b == null ? false : b.booleanValue();
+    }
+
+    public String getVersionLabel() {
+        return getString(Property.VERSION_LABEL);
+    }
+
+    public String getVersionSeriesId() {
+        return getId(Property.VERSION_SERIES_ID);
+    }
+
+    public boolean isVersionSeriesCheckedOut() {
+        Boolean b = getBoolean(Property.IS_VERSION_SERIES_CHECKED_OUT);
+        return b == null ? false : b.booleanValue();
+    }
+
+    public String getVersionSeriesCheckedOutBy() {
+        return getString(Property.VERSION_SERIES_CHECKED_OUT_BY);
+    }
+
+    public String getVersionSeriesCheckedOutId() {
+        return getId(Property.VERSION_SERIES_CHECKED_OUT_ID);
+    }
+
+    public String getCheckinComment() {
+        return getString(Property.CHECKIN_COMMENT);
+    }
+
+    public boolean hasContentStream() {
+        // spec says this is present iff content stream is present
+        String name = Property.CONTENT_STREAM_MIME_TYPE;
+        PropertyDefinition propertyDefinition = getType().getPropertyDefinition(
+                name);
+        if (propertyDefinition == null) {
+            return false;
+        }
+        return data.containsKey(name);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((data == null) ? 0 : data.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        SimpleObjectEntry other = (SimpleObjectEntry) obj;
+        if (data == null) {
+            if (other.data != null) {
+                return false;
+            }
+        } else if (!data.equals(other.data)) {
+            return false;
+        }
+        return true;
+    }
+
+    
+}

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleObjectEntry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleObjectEntry.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimplePolicy.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimplePolicy.java?rev=765129&view=auto
==============================================================================
--- jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimplePolicy.java (added)
+++ jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimplePolicy.java Wed Apr 15 10:49:31 2009
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ *
+ * Authors:
+ *     Florent Guillaume
+ */
+package org.apache.chemistry.impl.simple;
+
+import org.apache.chemistry.Policy;
+
+public class SimplePolicy extends SimpleObject implements Policy {
+
+    public SimplePolicy(SimpleData data, SimpleConnection connection) {
+        super(data, connection);
+    }
+
+}

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimplePolicy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimplePolicy.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleProperty.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleProperty.java?rev=765129&view=auto
==============================================================================
--- jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleProperty.java (added)
+++ jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleProperty.java Wed Apr 15 10:49:31 2009
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ *
+ * Authors:
+ *     Florent Guillaume
+ */
+package org.apache.chemistry.impl.simple;
+
+import java.io.Serializable;
+
+import org.apache.chemistry.ObjectEntry;
+import org.apache.chemistry.property.Property;
+import org.apache.chemistry.property.PropertyDefinition;
+
+/**
+ * A live property of an object.
+ *
+ * @author Florent Guillaume
+ */
+public class SimpleProperty implements Property {
+
+    protected final ObjectEntry entry;
+
+    protected final String name;
+
+    public SimpleProperty(ObjectEntry entry, String name) {
+        this.entry = entry;
+        this.name = name;
+    }
+
+    public PropertyDefinition getDefinition() {
+        return entry.getType().getPropertyDefinition(name);
+    }
+
+    public Serializable getValue() {
+        return entry.getValue(name);
+    }
+
+    public void setValue(Serializable value) {
+        // TODO XXX
+        throw new UnsupportedOperationException();
+    }
+
+}

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleProperty.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/sandbox/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleProperty.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url