You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by dc...@apache.org on 2009/08/18 16:27:59 UTC

svn commit: r805426 [2/9] - in /incubator/chemistry/trunk/chemistry: ./ chemistry-tck-atompub/ chemistry-tck-atompub/src/ chemistry-tck-atompub/src/main/ chemistry-tck-atompub/src/main/java/ chemistry-tck-atompub/src/main/java/org/ chemistry-tck-atompu...

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISRepositoryInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISValue.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISValue.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISValue.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISValue.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,120 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ */
+package org.apache.chemistry.abdera.ext;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import javax.xml.namespace.QName;
+
+import org.apache.chemistry.tck.atompub.utils.ISO8601DateFormat;
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.ExtensibleElementWrapper;
+
+
+/**
+ * CMIS Property Value for the Abdera ATOM library.
+ */
+public class CMISValue extends ExtensibleElementWrapper {
+    
+    /**
+     * @param internal
+     */
+    public CMISValue(Element internal) {
+        super(internal);
+    }
+
+    /**
+     * @param factory
+     * @param qname
+     */
+    public CMISValue(Factory factory, QName qname) {
+        super(factory, qname);
+    }
+
+    /**
+     * Gets property value (converting to appropriate Java type for the property
+     * type)
+     * 
+     * @return property value (or null, if not specified)
+     */
+    public Object getNativeValue() {
+        CMISProperty parent = (CMISProperty) getParentElement();
+        String type = parent.getType();
+        if (type.equals(CMISConstants.PROP_TYPE_STRING)) {
+            return getStringValue();
+        } else if (type.equals(CMISConstants.PROP_TYPE_INTEGER)) {
+            return getIntegerValue();
+        } else if (type.equals(CMISConstants.PROP_TYPE_DATETIME)) {
+            return getDateValue();
+        } else if (type.equals(CMISConstants.PROP_TYPE_BOOLEAN)) {
+            return getBooleanValue();
+        } else if (type.equals(CMISConstants.PROP_TYPE_DECIMAL)) {
+            return getDecimalValue();
+        }
+        // TODO: Handle remaining property types
+        return getStringValue();
+    }
+
+    /**
+     * Gets String value
+     * 
+     * @return string value
+     */
+    public String getStringValue() {
+        return getText();
+    }
+
+    /**
+     * Gets Decimal value
+     * 
+     * @return decimal value
+     */
+    public BigDecimal getDecimalValue() {
+        return new BigDecimal(getStringValue());
+    }
+
+    /**
+     * Gets Integer value
+     * 
+     * @return integer value
+     */
+    public int getIntegerValue() {
+        return new Integer(getStringValue());
+    }
+
+    /**
+     * Gets Boolean value
+     * 
+     * @return boolean value
+     */
+    public boolean getBooleanValue() {
+        return Boolean.valueOf(getStringValue());
+    }
+
+    /**
+     * Gets Date value
+     * 
+     * @return date value
+     */
+    public Date getDateValue() {
+        // TODO: Use mechanism not reliant on Alfresco code
+        return ISO8601DateFormat.parse(getStringValue());
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/abdera/ext/CMISValue.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/TCKLogger.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/TCKLogger.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/TCKLogger.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/TCKLogger.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,29 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ *     Gabriele Columbro, Alfresco
+ */
+package org.apache.chemistry.tck.atompub;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * TCK Logger 
+ */
+public class TCKLogger {
+    public static final Log logger = LogFactory.getLog(TCKLogger.class);
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/TCKLogger.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/TCKOptions.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/TCKOptions.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/TCKOptions.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/TCKOptions.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,41 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ *     Gabriele Columbro, Alfresco
+ */
+package org.apache.chemistry.tck.atompub;
+
+
+/**
+ * TCK Options
+ */
+public interface TCKOptions {
+
+    public String getServiceUrl();
+
+    public String getUser();
+
+    public String getPassword();
+
+    public Boolean getValidate();
+
+    public Boolean getFailOnValidationError();
+
+    public Boolean getTraceRequests();
+
+    public Boolean getDeleteTestFixture();
+
+    public String getConnectionFactory();
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/TCKOptions.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/TCKTest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/TCKTest.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/TCKTest.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/TCKTest.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,107 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ *     Gabriele Columbro, Alfresco
+ */
+package org.apache.chemistry.tck.atompub;
+
+import junit.framework.TestCase;
+
+import org.apache.chemistry.tck.atompub.client.CMISAppModel;
+import org.apache.chemistry.tck.atompub.client.CMISClient;
+import org.apache.chemistry.tck.atompub.fixture.CMISTestFixture;
+import org.apache.chemistry.tck.atompub.http.Connection;
+import org.apache.chemistry.tck.atompub.http.ConnectionFactory;
+import org.apache.chemistry.tck.atompub.http.httpclient.HttpClientConnectionFactory;
+import org.apache.chemistry.tck.atompub.utils.ResourceLoader;
+import org.apache.chemistry.tck.atompub.utils.SystemPropertyOptions;
+
+/**
+ * Base Test Class for TCK Tests
+ */
+public class TCKTest extends TestCase {
+
+    protected TCKOptions options = null;
+    protected CMISClient client;
+    protected CMISAppModel model;
+    protected CMISTestFixture fixture;
+    protected ResourceLoader templates;
+
+    public void setOptions(TCKOptions properties) {
+        this.options = properties;
+    }
+
+    @Override
+    public void setUp() {
+        // construct TCK properties
+        if (options == null)
+            options = new SystemPropertyOptions();
+
+        // construct connection to server
+        // TODO: allow configuration of different connection factory
+        ConnectionFactory connFactory = new HttpClientConnectionFactory();
+        String user = options.getUser();
+        String password = options.getPassword();
+        Connection connection = (user == null) ? connFactory.createConnection() : connFactory.createConnection(user,
+                password);
+
+        // construct CMIS test client
+        String url = options.getServiceUrl();
+        if (url == null)
+            fail("CMIS Service URL not specified");
+        client = new CMISClient(connection, url);
+        Boolean validate = (options.getValidate() == null) ? true : options.getValidate();
+        client.setValidate(validate);
+        Boolean failOnValidationError = (options.getFailOnValidationError() == null) ? false : options
+                .getFailOnValidationError();
+        client.setFailOnValidationError(failOnValidationError);
+        Boolean trace = (options.getTraceRequests() == null) ? true : options.getTraceRequests();
+        client.setTrace(trace);
+
+        // construct model helper
+        model = new CMISAppModel();
+
+        // construct test templates
+        templates = new ResourceLoader("/org/apache/chemistry/tck/atompub/templates/");
+
+        // construct test fixture
+        fixture = new CMISTestFixture(client, getName());
+
+        if (TCKLogger.logger.isInfoEnabled()) {
+            TCKLogger.logger.info("Start Test: " + getClass().getName() + "." + getName());
+            TCKLogger.logger.info("Service URL: " + url);
+            TCKLogger.logger.info("User: " + user);
+            TCKLogger.logger.info("Password: " + password);
+            TCKLogger.logger.info("Validate: " + validate);
+            TCKLogger.logger.info("Fail on Validation Error: " + failOnValidationError);
+            TCKLogger.logger.info("Trace Requests: " + trace);
+        }
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        Boolean delete = (options.getDeleteTestFixture() == null) ? true : options.getDeleteTestFixture();
+        if (delete)
+            fixture.delete();
+
+        if (TCKLogger.logger.isInfoEnabled())
+            TCKLogger.logger.info("End Test: " + getClass().getName() + "." + getName());
+    }
+
+    public void skipTest(String reason) {
+        if (TCKLogger.logger.isInfoEnabled())
+            TCKLogger.logger.info("Skiped Test: " + getClass().getName() + "." + getName() + ": " + reason);
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/TCKTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISAppModel.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISAppModel.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISAppModel.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISAppModel.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,120 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.client;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.abdera.Abdera;
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.model.Document;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Feed;
+import org.apache.abdera.model.Service;
+import org.apache.abdera.parser.Parser;
+import org.apache.chemistry.abdera.ext.CMISExtensionFactory;
+
+
+/**
+ * Create / Read CMIS AtomPub Service, Feeds and Entries
+ */
+public class CMISAppModel {
+    
+    private Abdera abdera;
+    private Parser parser;
+    private Factory factory;
+
+    public CMISAppModel() {
+        // construct Abdera Service
+        abdera = new Abdera();
+        factory = abdera.getFactory();
+        factory.registerExtension(new CMISExtensionFactory());
+        parser = factory.newParser();
+    }
+
+    public Entry createEntry() {
+        return factory.newEntry();
+    }
+
+    public Feed createFeed() {
+        return factory.newFeed();
+    }
+
+    public Element parse(InputStream doc, String base) {
+        Reader inputReader = new InputStreamReader(doc);
+        return parse(inputReader, base);
+    }
+
+    public Element parse(Reader doc, String base) {
+        Document<Element> entryDoc;
+        if (base != null && base.length() > 0) {
+            entryDoc = parser.parse(doc, base);
+        } else {
+            entryDoc = parser.parse(doc);
+        }
+
+        Element root = entryDoc.getRoot();
+        return root;
+    }
+
+    public Service parseService(InputStream doc, String base) {
+        Reader inputReader = new InputStreamReader(doc);
+        return parseService(inputReader, base);
+    }
+
+    public Service parseService(Reader doc, String base) {
+        Element root = parse(doc, base);
+        if (!Service.class.isAssignableFrom(root.getClass())) {
+            throw new RuntimeException(HttpServletResponse.SC_BAD_REQUEST + "Expected APP Service, but recieved " + root.getClass());
+        }
+
+        return (Service) root;
+    }
+
+    public Entry parseEntry(InputStream doc, String base) {
+        Reader inputReader = new InputStreamReader(doc);
+        return parseEntry(inputReader, base);
+    }
+
+    public Entry parseEntry(Reader doc, String base) {
+        Element root = parse(doc, base);
+        if (!Entry.class.isAssignableFrom(root.getClass())) {
+            throw new RuntimeException(HttpServletResponse.SC_BAD_REQUEST + "Expected Atom Entry, but recieved " + root.getClass());
+        }
+
+        return (Entry) root;
+    }
+
+    public Feed parseFeed(InputStream doc, String base) {
+        Reader inputReader = new InputStreamReader(doc);
+        return parseFeed(inputReader, base);
+    }
+
+    public Feed parseFeed(Reader doc, String base) {
+        Element root = parse(doc, base);
+        if (!Feed.class.isAssignableFrom(root.getClass())) {
+            throw new RuntimeException(HttpServletResponse.SC_BAD_REQUEST + "Expected Atom Feed, but recieved " + root.getClass());
+        }
+
+        return (Feed) root;
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISAppModel.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISClient.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISClient.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISClient.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISClient.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,409 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ *     Gabriele Columbro, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.client;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+import java.util.Map;
+
+import javax.activation.MimeType;
+import javax.activation.MimeTypeParseException;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.validation.Validator;
+
+import org.apache.abdera.i18n.iri.IRI;
+import org.apache.abdera.model.Collection;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Feed;
+import org.apache.abdera.model.Link;
+import org.apache.abdera.model.Service;
+import org.apache.abdera.model.Workspace;
+import org.apache.chemistry.abdera.ext.CMISCapabilities;
+import org.apache.chemistry.abdera.ext.CMISConstants;
+import org.apache.chemistry.abdera.ext.CMISObject;
+import org.apache.chemistry.abdera.ext.CMISRepositoryInfo;
+import org.apache.chemistry.tck.atompub.TCKLogger;
+import org.apache.chemistry.tck.atompub.http.Connection;
+import org.apache.chemistry.tck.atompub.http.GetRequest;
+import org.apache.chemistry.tck.atompub.http.PostRequest;
+import org.apache.chemistry.tck.atompub.http.Request;
+import org.apache.chemistry.tck.atompub.http.Response;
+import org.apache.chemistry.tck.atompub.utils.ResourceLoader;
+import org.apache.commons.codec.binary.Base64;
+import org.junit.Assert;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Interact with CMIS Repository
+ */
+public class CMISClient {
+
+    private Connection connection;
+    private boolean traceConnection;
+
+    private String serviceUrl;
+
+    private CMISAppModel appModel = new CMISAppModel();
+
+    private CMISValidator cmisValidator = new CMISValidator();
+    private boolean validate = true;
+    private boolean failOnValidationError = false;
+
+    private ResourceLoader templates = new ResourceLoader("/org/apache/chemistry/tck/atompub/templates/");
+
+    private Service cmisService = null;
+    private CMISCapabilities cmisCapabilities = null;
+
+
+    public CMISClient(Connection connection, String serviceUrl) {
+        this.connection = connection;
+        this.serviceUrl = serviceUrl;
+    }
+
+    public void setValidate(boolean validate) {
+        this.validate = validate;
+    }
+
+    public void setFailOnValidationError(boolean failOnValidationError) {
+        this.failOnValidationError = failOnValidationError;
+    }
+
+    public void setTrace(boolean trace) {
+        this.traceConnection = trace;
+    }
+
+    public Service getRepository() throws Exception {
+        if (cmisService == null) {
+            Request req = new GetRequest(serviceUrl);
+            Response res = executeRequest(req, 200, cmisValidator.getAppValidator());
+            String xml = res.getContentAsString();
+            Assert.assertNotNull(xml);
+            Assert.assertTrue(xml.length() > 0);
+            cmisService = appModel.parseService(new StringReader(xml), null);
+            Assert.assertNotNull(cmisService);
+        }
+        return cmisService;
+    }
+
+    public CMISCapabilities getCapabilities() throws Exception {
+        if (cmisCapabilities == null) {
+            Service repo = getRepository();
+            Workspace workspace = getWorkspace(repo);
+            CMISRepositoryInfo repoInfo = workspace.getExtension(CMISConstants.REPOSITORY_INFO);
+            Assert.assertNotNull(repoInfo);
+            cmisCapabilities = repoInfo.getCapabilities();
+        }
+        return cmisCapabilities;
+    }
+
+    public Workspace getWorkspace() throws Exception {
+        return getRepository().getWorkspaces().get(0);
+    }
+
+    public Workspace getWorkspace(Service service) {
+        return service.getWorkspaces().get(0);
+    }
+
+    public Collection getCMISCollection(Workspace workspace, String collectionId) {
+        List<Collection> collections = workspace.getCollections();
+        for (Collection collection : collections) {
+            String id = collection.getAttributeValue(CMISConstants.COLLECTION_TYPE);
+            if (id != null && id.equals(collectionId)) {
+                return collection;
+            }
+        }
+        return null;
+    }
+
+    public IRI getRootCollection(Workspace workspace) {
+        Collection root = getCMISCollection(workspace, CMISConstants.COLLECTION_ROOT);
+        Assert.assertNotNull(root);
+        IRI rootHREF = root.getHref();
+        Assert.assertNotNull(rootHREF);
+        return rootHREF;
+    }
+
+    public IRI getCheckedOutCollection(Workspace workspace) {
+        Collection root = getCMISCollection(workspace, CMISConstants.COLLECTION_CHECKEDOUT);
+        Assert.assertNotNull(root);
+        IRI rootHREF = root.getHref();
+        Assert.assertNotNull(rootHREF);
+        return rootHREF;
+    }
+
+    public IRI getTypesChildrenCollection(Workspace workspace) {
+        Collection root = getCMISCollection(workspace, CMISConstants.COLLECTION_TYPES);
+        Assert.assertNotNull(root);
+        IRI rootHREF = root.getHref();
+        Assert.assertNotNull(rootHREF);
+        return rootHREF;
+    }
+
+    public IRI getQueryCollection(Workspace workspace) {
+        Collection root = getCMISCollection(workspace, CMISConstants.COLLECTION_QUERY);
+        Assert.assertNotNull(root);
+        IRI rootHREF = root.getHref();
+        Assert.assertNotNull(rootHREF);
+        return rootHREF;
+    }
+
+    public Link getLink(Entry entry, String rel, String... matchesMimetypes) {
+        List<Link> links = entry.getLinks(rel);
+        if (links != null) {
+            for (Link link : links) {
+                MimeType mimetype = link.getMimeType();
+                if (matchesMimetypes.length == 0) {
+                    if (links.size() == 1) {
+                        // take the single link regardless of type
+                        return link;
+                    } else if (mimetype == null) {
+                        // take the link if it doesn't have a type
+                        return link;
+                    }
+                }
+                for (String matchesMimetype : matchesMimetypes) {
+                    try {
+                        MimeType mtMatchesMimetype = new MimeType(matchesMimetype);
+                        String type = mimetype.getParameter("type");
+                        if (type == null) {
+                            if (mimetype != null && mimetype.getBaseType().equals(mtMatchesMimetype.getBaseType())
+                                    && mimetype.getSubType().equals(mtMatchesMimetype.getSubType())) {
+                                return link;
+                            }
+                        } else {
+                            String matchesType = mtMatchesMimetype.getParameter("type");
+                            if (mimetype != null && mimetype.getBaseType().equals(mtMatchesMimetype.getBaseType())
+                                    && mimetype.getSubType().equals(mtMatchesMimetype.getSubType())
+                                    && type.equals(matchesType)) {
+                                return link;
+                            }
+                        }
+                    } catch (MimeTypeParseException e) {
+                        // note: not a match
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    public Link getChildrenLink(Entry entry) {
+        return getLink(entry, CMISConstants.REL_DOWN, CMISConstants.MIMETYPE_FEED);
+    }
+
+    public Link getDescendantsLink(Entry entry) {
+        return getLink(entry, CMISConstants.REL_DOWN, CMISConstants.MIMETYPE_CMISTREE);
+    }
+
+    public Link getFolderTreeLink(Entry entry) {
+        return getLink(entry, CMISConstants.REL_FOLDER_TREE, CMISConstants.MIMETYPE_CMISTREE);
+    }
+
+    public Link getObjectParentsLink(Entry entry) {
+        return getLink(entry, CMISConstants.REL_UP, CMISConstants.MIMETYPE_FEED);
+    }
+
+    public Link getFolderParentLink(Entry entry) {
+        return getLink(entry, CMISConstants.REL_UP, CMISConstants.MIMETYPE_ENTRY);
+    }
+
+    public Entry getEntry(IRI href) throws Exception {
+        return getEntry(href, null);
+    }
+
+    public Entry getEntry(IRI href, Map<String, String> args) throws Exception {
+        Request get = new GetRequest(href.toString()).setArgs(args);
+        Response res = executeRequest(get, 200, cmisValidator.getCMISAtomValidator());
+        String xml = res.getContentAsString();
+        Entry entry = appModel.parseEntry(new StringReader(xml), null);
+        Assert.assertNotNull(entry);
+        // TODO: fix up self links with arguments
+        if (args == null) {
+            Assert.assertEquals(get.getFullUri(), entry.getSelfLink().getHref().toString());
+        }
+        return entry;
+    }
+
+    public Feed getFeed(IRI href) throws Exception {
+        return getFeed(href, null);
+    }
+
+    public Feed getFeed(IRI href, Map<String, String> args) throws Exception {
+        Request get = new GetRequest(href.toString()).setArgs(args);
+        Response res = executeRequest(get, 200, cmisValidator.getCMISAtomValidator());
+        Assert.assertNotNull(res);
+        String xml = res.getContentAsString();
+        Feed feed = appModel.parseFeed(new StringReader(xml), null);
+        Assert.assertNotNull(feed);
+        Assert.assertEquals(get.getFullUri(), feed.getSelfLink().getHref().toString());
+        return feed;
+    }
+
+    public Entry createFolder(IRI parent, String name) throws Exception {
+        return createFolder(parent, name, null);
+    }
+
+    public Entry createFolder(IRI parent, String name, String atomEntryFile) throws Exception {
+        String createFolder = templates.load(atomEntryFile == null ? "createfolder.atomentry.xml" : atomEntryFile);
+        createFolder = createFolder.replace("${NAME}", name);
+        Request req = new PostRequest(parent.toString(), createFolder, CMISConstants.MIMETYPE_ENTRY);
+        Response res = executeRequest(req, 201, cmisValidator.getCMISAtomValidator());
+        Assert.assertNotNull(res);
+        String xml = res.getContentAsString();
+        Entry entry = appModel.parseEntry(new StringReader(xml), null);
+        Assert.assertNotNull(entry);
+        Assert.assertEquals(name, entry.getTitle());
+        // Assert.assertEquals(name + " (summary)", entry.getSummary());
+        CMISObject object = entry.getExtension(CMISConstants.OBJECT);
+        Assert.assertEquals(CMISConstants.TYPE_FOLDER, object.getBaseTypeId().getStringValue());
+        String testFolderHREF = (String) res.getHeader("Location");
+        Assert.assertNotNull(testFolderHREF);
+        return entry;
+    }
+
+    public Entry createDocument(IRI parent, String name) throws Exception {
+        return createDocument(parent, name, null);
+    }
+
+    public Entry createDocument(IRI parent, String name, String atomEntryFile) throws Exception {
+        String createFile = templates.load(atomEntryFile == null ? "createdocument.atomentry.xml" : atomEntryFile);
+        createFile = createFile.replace("${NAME}", name);
+        // determine if creating content via mediatype
+        Entry createEntry = appModel.parseEntry(new StringReader(createFile), null);
+        MimeType mimeType = createEntry.getContentMimeType();
+        boolean mediaType = (mimeType != null);
+        createFile = createFile.replace("${CONTENT}", mediaType ? new String(Base64.encodeBase64(name.getBytes())) : name);
+        Request req = new PostRequest(parent.toString(), createFile, CMISConstants.MIMETYPE_ENTRY);
+        Response res = executeRequest(req, 201, cmisValidator.getCMISAtomValidator());
+        Assert.assertNotNull(res);
+        String xml = res.getContentAsString();
+        Entry entry = appModel.parseEntry(new StringReader(xml), null);
+        Assert.assertNotNull(entry);
+        Assert.assertEquals(name, entry.getTitle());
+        // Assert.assertEquals(name + " (summary)", entry.getSummary());
+        Assert.assertNotNull(entry.getContentSrc());
+        CMISObject object = entry.getExtension(CMISConstants.OBJECT);
+        Assert.assertEquals(CMISConstants.TYPE_DOCUMENT, object.getBaseTypeId().getStringValue());
+        String testFileHREF = (String) res.getHeader("Location");
+        Assert.assertNotNull(testFileHREF);
+        return entry;
+    }
+
+    public Entry createRelationship(IRI parent, String type, String targetId) throws Exception {
+        return createRelationship(parent, type, targetId, "createrelationship.atomentry.xml");
+    }
+
+    public Entry createRelationship(IRI parent, String type, String targetId, String atomEntryFile) throws Exception {
+        String createFile = templates.load(atomEntryFile);
+        createFile = createFile.replace("${RELTYPE}", type);
+        createFile = createFile.replace("${TARGETID}", targetId);
+        Request req = new PostRequest(parent.toString(), createFile, CMISConstants.MIMETYPE_ENTRY);
+        Response res = executeRequest(req, 201, cmisValidator.getCMISAtomValidator());
+        Assert.assertNotNull(res);
+        String xml = res.getContentAsString();
+        Entry entry = appModel.parseEntry(new StringReader(xml), null);
+        Assert.assertNotNull(entry);
+        CMISObject object = entry.getExtension(CMISConstants.OBJECT);
+        Assert.assertEquals(CMISConstants.TYPE_RELATIONSHIP, object.getBaseTypeId().getStringValue());
+        Assert.assertEquals(targetId, object.getTargetId().getStringValue());
+        String testFileHREF = (String) res.getHeader("Location");
+        Assert.assertNotNull(testFileHREF);
+        return entry;
+    }
+
+    public Response executeRequest(Request req, int expectedStatus) throws IOException {
+        return executeRequest(req, expectedStatus, null);
+    }
+
+    /**
+     * Execute Request
+     *
+     * @param req
+     * @param expectedStatus
+     * @param asUser
+     * @return response
+     * @throws IOException
+     */
+    public Response executeRequest(Request req, int expectedStatus, Validator validator) throws IOException {
+        if (traceConnection && TCKLogger.logger.isInfoEnabled()) {
+            TCKLogger.logger.info("Request: " + req.getMethod() + " " + req.getFullUri()
+                    + (req.getBody() == null ? "" : "\n" + new String(req.getBody(), req.getEncoding())));
+        }
+
+        Response res = connection.executeRequest(req);
+
+        if (traceConnection && TCKLogger.logger.isInfoEnabled()) {
+            TCKLogger.logger.info("Response: " + res.getStatus() + " " + req.getMethod() + " " + req.getFullUri()
+                    + (res.getContentAsString() == null ? "" : "\n" + res.getContentAsString()));
+        }
+
+        if (expectedStatus > -1)
+            Assert.assertEquals("Request status for " + req.getFullUri(), expectedStatus, res.getStatus());
+
+        if (validator != null && validate) {
+            try {
+                String resXML = res.getContentAsString();
+                assertValid(resXML, validator);
+            } catch (ParserConfigurationException e) {
+                // @TODO: Maybe make a Chemistry specific exception
+                throw new RuntimeException("Failed to validate", e);
+            }
+        }
+        return res;
+    }
+
+    public Validator getAppValidator() throws IOException, SAXException {
+        return cmisValidator.getAppValidator();
+    }
+
+    public Validator getAtomValidator() throws IOException, SAXException {
+        return cmisValidator.getCMISAtomValidator();
+    }
+
+    /**
+     * Asserts XML complies with specified Validator
+     *
+     * @param xml
+     *            xml to assert
+     * @param validator
+     *            validator to assert with
+     * @throws IOException
+     * @throws ParserConfigurationException
+     */
+    private void assertValid(String xml, Validator validator) throws IOException, ParserConfigurationException {
+        if (validate) {
+            try {
+                Document document = cmisValidator.getDocumentBuilder().parse(new InputSource(new StringReader(xml)));
+                validator.validate(new DOMSource(document));
+            } catch (SAXException e) {
+                if (TCKLogger.logger.isInfoEnabled()) {
+                    TCKLogger.logger.info("Failed Validation: " + cmisValidator.toString(e, null));
+                }
+                if (failOnValidationError) {
+                    Assert.fail(cmisValidator.toString(e, xml));
+                }
+            }
+        }
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISClient.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISValidator.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISValidator.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISValidator.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISValidator.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,144 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.client;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+
+/**
+ * CMIS Validator
+ * 
+ * Support for validating CMIS requests/responses against CMIS XSDs
+ */
+public class CMISValidator {
+    
+    /** XML Schema Validation */
+    private DocumentBuilder documentBuilder = null;
+    private Validator appValidator = null;
+    private Validator atomValidator = null;
+
+    /**
+     * Gets document parser
+     * 
+     * @return document parser
+     * @throws ParserConfigurationException
+     */
+    public DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
+        if (documentBuilder == null) {
+            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
+            builderFactory.setNamespaceAware(true);
+            documentBuilder = builderFactory.newDocumentBuilder();
+        }
+        return documentBuilder;
+    }
+
+    /**
+     * Gets CMIS Atom Publishing Protocol XML Validator
+     * 
+     * @return APP Validator
+     * @throws IOException
+     * @throws SAXException
+     */
+    public Validator getAppValidator() throws IOException, SAXException {
+        if (appValidator == null) {
+            SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+            Source APPFile = new StreamSource(getClass().getResourceAsStream(
+                    "/org/apache/chemistry/tck/atompub/xsd/APP.xsd"), getClass().getResource(
+                    "/org/apache/chemistry/tck/atompub/xsd/APP.xsd").toExternalForm());
+            Schema schema = factory.newSchema(APPFile);
+            appValidator = schema.newValidator();
+        }
+        return appValidator;
+    }
+
+    /**
+     * Gets CMIS Atom Validator
+     * 
+     * @return CMIS Atom Validator
+     * @throws IOException
+     * @throws SAXException
+     */
+    public Validator getCMISAtomValidator() throws IOException, SAXException {
+        if (atomValidator == null) {
+            SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+            Source ATOMFile = new StreamSource(getClass().getResourceAsStream(
+                    "/org/apache/chemistry/tck/atompub/xsd/ATOM.xsd"), getClass().getResource(
+                    "/org/apache/chemistry/tck/atompub/xsd/ATOM.xsd").toExternalForm());
+            Schema schema = factory.newSchema(ATOMFile);
+            atomValidator = schema.newValidator();
+        }
+
+        return atomValidator;
+    }
+
+    /**
+     * Asserts XML complies with specified Validator
+     * 
+     * @param xml
+     *            xml to assert
+     * @param validator
+     *            validator to assert with
+     * @throws IOException
+     * @throws ParserConfigurationException
+     */
+    public void validateXML(String xml, Validator validator) throws IOException, ParserConfigurationException,
+            SAXException {
+        Document document = getDocumentBuilder().parse(new InputSource(new StringReader(xml)));
+        validator.validate(new DOMSource(document));
+    }
+
+    /**
+     * Convert SAX Exception to String
+     * 
+     * @param e
+     *            SAX Exception
+     * @param xml
+     *            related XML (if any)
+     * @return description of SAX Exception
+     */
+    public String toString(SAXException e, String xml) {
+        StringBuffer fail = new StringBuffer(e.toString());
+        if (e instanceof SAXParseException) {
+            fail.append("\n");
+            fail.append("line: ").append(((SAXParseException) e).getLineNumber()).append("\n");
+            fail.append("col: ").append(((SAXParseException) e).getColumnNumber()).append("\n");
+        }
+        if (xml != null) {
+            fail.append("\n");
+            fail.append(xml);
+        }
+        return fail.toString();
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/client/CMISValidator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertEntryInFeedVisitor.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertEntryInFeedVisitor.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertEntryInFeedVisitor.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertEntryInFeedVisitor.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,38 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.fixture;
+
+import org.apache.abdera.model.Feed;
+import org.apache.chemistry.tck.atompub.fixture.EntryTree.TreeVisitor;
+import org.junit.Assert;
+
+
+/**
+ * Visitor that asserts each Entry in Entry Tree exists in specified Feed
+ */
+public class AssertEntryInFeedVisitor implements TreeVisitor {
+    
+    private Feed feed;
+
+    public AssertEntryInFeedVisitor(Feed feed) {
+        this.feed = feed;
+    }
+
+    public void visit(EntryTree entry) throws Exception {
+        Assert.assertNotNull(feed.getEntry(entry.entry.getId().toString()));
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertEntryInFeedVisitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertExistVisitor.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertExistVisitor.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertExistVisitor.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertExistVisitor.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,38 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.fixture;
+
+import org.apache.chemistry.tck.atompub.client.CMISClient;
+import org.apache.chemistry.tck.atompub.fixture.EntryTree.TreeVisitor;
+import org.apache.chemistry.tck.atompub.http.GetRequest;
+
+
+/**
+ * Asserts each Entry in EntryTree exists in CMIS Repository
+ */
+public class AssertExistVisitor implements TreeVisitor {
+    
+    private CMISClient client;
+
+    public AssertExistVisitor(CMISClient client) {
+        this.client = client;
+    }
+
+    public void visit(EntryTree entry) throws Exception {
+        client.executeRequest(new GetRequest(entry.entry.getSelfLink().getHref().toString()), 200);
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertExistVisitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertNotExistVisitor.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertNotExistVisitor.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertNotExistVisitor.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertNotExistVisitor.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,38 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.fixture;
+
+import org.apache.chemistry.tck.atompub.client.CMISClient;
+import org.apache.chemistry.tck.atompub.fixture.EntryTree.TreeVisitor;
+import org.apache.chemistry.tck.atompub.http.GetRequest;
+
+
+/**
+ * Asserts each Entry in EntryTree does not exist in CMIS Repository
+ */
+public class AssertNotExistVisitor implements TreeVisitor {
+    
+    private CMISClient client;
+
+    public AssertNotExistVisitor(CMISClient client) {
+        this.client = client;
+    }
+
+    public void visit(EntryTree entry) throws Exception {
+        client.executeRequest(new GetRequest(entry.entry.getSelfLink().getHref().toString()), 404);
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertNotExistVisitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertValidFolderParentVisitor.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertValidFolderParentVisitor.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertValidFolderParentVisitor.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertValidFolderParentVisitor.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,56 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.fixture;
+
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Link;
+import org.apache.chemistry.abdera.ext.CMISConstants;
+import org.apache.chemistry.tck.atompub.client.CMISClient;
+import org.apache.chemistry.tck.atompub.fixture.EntryTree.TreeVisitor;
+import org.junit.Assert;
+
+
+/**
+ * Asserts each Folder Entry in EntryTree has a valid parent
+ */
+public class AssertValidFolderParentVisitor implements TreeVisitor {
+
+    private CMISClient client;
+
+    public AssertValidFolderParentVisitor(CMISClient client) {
+        this.client = client;
+    }
+
+    public void visit(EntryTree entry) throws Exception {
+        Link parentLink = client.getFolderParentLink(entry.entry);
+
+        if (entry.parent == null) {
+            Assert.assertNull(parentLink);
+            return;
+        }
+
+        if (entry.type.equals(CMISConstants.TYPE_FOLDER))
+            Assert.assertNotNull(parentLink);
+
+        if (parentLink == null)
+            return;
+
+        // ensure link is to parent
+        Entry parent = client.getEntry(parentLink.getHref());
+        Assert.assertEquals(entry.parent.getId(), parent.getId());
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertValidFolderParentVisitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertValidObjectParentsVisitor.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertValidObjectParentsVisitor.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertValidObjectParentsVisitor.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertValidObjectParentsVisitor.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,52 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.fixture;
+
+import org.apache.abdera.model.Feed;
+import org.apache.abdera.model.Link;
+import org.apache.chemistry.abdera.ext.CMISConstants;
+import org.apache.chemistry.tck.atompub.client.CMISClient;
+import org.apache.chemistry.tck.atompub.fixture.EntryTree.TreeVisitor;
+import org.junit.Assert;
+
+
+/**
+ * Asserts each Document Entry in EntryTree has valid Object Parents
+ */
+public class AssertValidObjectParentsVisitor implements TreeVisitor {
+    
+    private CMISClient client;
+
+    public AssertValidObjectParentsVisitor(CMISClient client) {
+        this.client = client;
+    }
+
+    public void visit(EntryTree entry) throws Exception {
+        Link parentLink = client.getObjectParentsLink(entry.entry);
+
+        if (entry.type.equals(CMISConstants.TYPE_FOLDER)) {
+            Assert.assertNull(parentLink);
+            return;
+        }
+
+        Assert.assertNotNull(parentLink);
+
+        // ensure parents feed contains item
+        Feed parents = client.getFeed(parentLink.getHref());
+        Assert.assertNotNull(parents.getEntry(entry.parent.getId().toString()));
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/AssertValidObjectParentsVisitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/CMISTestFixture.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/CMISTestFixture.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/CMISTestFixture.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/CMISTestFixture.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,131 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.fixture;
+
+import java.util.ArrayList;
+
+import org.apache.abdera.i18n.iri.IRI;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Link;
+import org.apache.abdera.model.Service;
+import org.apache.chemistry.abdera.ext.CMISConstants;
+import org.apache.chemistry.tck.atompub.client.CMISClient;
+import org.apache.chemistry.tck.atompub.http.DeleteRequest;
+import org.apache.chemistry.tck.atompub.http.Request;
+import org.junit.Assert;
+
+
+/**
+ * CMIS Test Data
+ */
+public class CMISTestFixture {
+    
+    private static Long testStartTime = null;
+
+    private CMISClient client;
+    private String name;
+    private Entry testCaseFolder = null;
+
+    public CMISTestFixture(CMISClient client, String name) {
+        this.client = client;
+        this.name = name;
+    }
+
+    private long getStartTime() {
+        if (testStartTime == null) {
+            testStartTime = System.currentTimeMillis();
+        }
+        return testStartTime;
+    }
+
+    public Entry getTestCaseFolder() throws Exception {
+        if (testCaseFolder == null) {
+            Service service = client.getRepository();
+            IRI rootFolderHREF = client.getRootCollection(client.getWorkspace(service));
+            Assert.assertNotNull(rootFolderHREF);
+            String folderName = "CMISTCK " + getStartTime() + " - " + name;
+            testCaseFolder = client.createFolder(rootFolderHREF, folderName);
+        }
+        return testCaseFolder;
+    }
+
+    public Entry createTestDocument(String name) throws Exception {
+        return createTestDocument(name, null);
+    }
+
+    public Entry createTestDocument(String name, String template) throws Exception {
+        Link children = client.getChildrenLink(getTestCaseFolder());
+        return client.createDocument(children.getHref(), name, template);
+    }
+
+    public Entry createTestFolder(String name) throws Exception {
+        return createTestFolder(name, null);
+    }
+
+    public Entry createTestFolder(String name, String template) throws Exception {
+        Link children = client.getChildrenLink(getTestCaseFolder());
+        return client.createFolder(children.getHref(), name, template);
+    }
+
+    public EntryTree createTestTree(String name, int depth, int docCount, String folderTemplate, String docTemplate) throws Exception {
+        if (depth <= 0)
+            return null;
+
+        Entry root = createTestFolder(name, folderTemplate);
+        return createTree(getTestCaseFolder(), root, depth - 1, docCount, folderTemplate, docTemplate);
+    }
+
+    private EntryTree createTree(Entry parent, Entry entry, int depth, int docCount, String folderTemplate, String docTemplate) throws Exception {
+        String name = entry.getTitle();
+
+        // create entry for parent
+        EntryTree folderEntry = new EntryTree();
+        folderEntry.parent = parent;
+        folderEntry.entry = entry;
+        folderEntry.type = CMISConstants.TYPE_FOLDER;
+        folderEntry.children = new ArrayList<EntryTree>();
+
+        // construct child documents, if required
+        Link childrenLink = client.getChildrenLink(entry);
+        for (int docIdx = 0; docIdx < docCount; docIdx++) {
+            EntryTree docEntry = new EntryTree();
+            String docName = name + " doc " + docIdx;
+            docEntry.parent = entry;
+            docEntry.entry = client.createDocument(childrenLink.getHref(), docName, docTemplate);
+            docEntry.type = CMISConstants.TYPE_DOCUMENT;
+            folderEntry.children.add(docEntry);
+        }
+
+        // do deeper, if required
+        if (depth > 0) {
+            Entry subFolder = client.createFolder(childrenLink.getHref(), name, folderTemplate);
+            folderEntry.children.add(createTree(entry, subFolder, depth - 1, docCount, folderTemplate, docTemplate));
+        }
+
+        return folderEntry;
+    }
+
+    public void delete() throws Exception {
+        if (testCaseFolder != null) {
+            Link descendants = client.getDescendantsLink(testCaseFolder);
+            Assert.assertNotNull(descendants);
+            Request delete = new DeleteRequest(descendants.getHref().toString());
+            client.executeRequest(delete, -1);
+        }
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/CMISTestFixture.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/CMISTree.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/CMISTree.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/CMISTree.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/CMISTree.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,66 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.fixture;
+
+import java.util.ArrayList;
+
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Feed;
+import org.apache.chemistry.abdera.ext.CMISChildren;
+import org.apache.chemistry.abdera.ext.CMISConstants;
+import org.apache.chemistry.abdera.ext.CMISObject;
+import org.apache.chemistry.abdera.ext.CMISProperty;
+
+
+/**
+ * CMIS Tree of Folders and Documents
+ */
+public class CMISTree extends EntryTree {
+    
+    public CMISTree(EntryTree parentEntryTree, Feed cmisTree) {
+        parent = parentEntryTree.parent;
+        entry = parentEntryTree.entry;
+        type = parentEntryTree.type;
+        children = new ArrayList<EntryTree>();
+
+        for (Entry child : cmisTree.getEntries()) {
+            EntryTree childEntryTree = createEntryTree(entry, child);
+            children.add(childEntryTree);
+        }
+    }
+
+    private EntryTree createEntryTree(Entry parent, Entry entry) {
+        EntryTree entryTree = new EntryTree();
+        entryTree.parent = parent;
+        entryTree.entry = entry;
+        CMISObject object = entry.getExtension(CMISConstants.OBJECT);
+        CMISProperty baseTypeId = object.getBaseTypeId();
+        if (baseTypeId != null) {
+            entryTree.type = baseTypeId.getStringValue();
+        }
+
+        CMISChildren children = entry.getFirstChild(CMISConstants.CHILDREN);
+        if (children != null) {
+            entryTree.children = new ArrayList<EntryTree>();
+            for (Entry child : children.getEntries()) {
+                EntryTree childEntryTree = createEntryTree(entry, child);
+                entryTree.children.add(childEntryTree);
+            }
+        }
+        return entryTree;
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/CMISTree.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/EntryTree.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/EntryTree.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/EntryTree.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/EntryTree.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,153 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.fixture;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.abdera.model.Entry;
+import org.apache.chemistry.abdera.ext.CMISConstants;
+
+
+/**
+ * General Tree of Folders and Documents
+ */
+public class EntryTree {
+    
+    public Entry parent;
+    public Entry entry;
+    public String type;
+    public List<EntryTree> children;
+
+    public EntryTree() {
+    }
+
+    public EntryTree(EntryTree tree) throws Exception {
+        this(tree, -1, true);
+    }
+
+    public EntryTree(EntryTree tree, int depth) throws Exception {
+        this(tree, depth, true);
+    }
+
+    public EntryTree(EntryTree tree, int depth, boolean includeDocs) throws Exception {
+        parent = tree.parent;
+        entry = tree.entry;
+        type = tree.type;
+        children = copyChildren(tree.children, depth, includeDocs);
+    }
+
+    private List<EntryTree> copyChildren(List<EntryTree> children, int depth, boolean includeDocs) throws Exception {
+        if (children == null)
+            return null;
+
+        List<EntryTree> childrenCopy = new ArrayList<EntryTree>();
+        if (depth == 0)
+            return childrenCopy;
+
+        for (EntryTree child : children) {
+            if (includeDocs || child.type.equals(CMISConstants.TYPE_FOLDER)) {
+                EntryTree childCopy = new EntryTree(child, depth - 1, includeDocs);
+                childrenCopy.add(childCopy);
+            }
+        }
+        return childrenCopy;
+    }
+
+    public boolean equalsTree(EntryTree tree) {
+        if (parent == null && tree.parent != null)
+            return false;
+        if (parent != null && tree.parent == null)
+            return false;
+        if (!parent.getId().equals(tree.parent.getId()))
+            return false;
+        if (!entry.getId().equals(tree.entry.getId()))
+            return false;
+        if (!type.equals(tree.type))
+            return false;
+        if (children == null && tree.children != null && tree.children.size() != 0)
+            return false;
+        if (children != null && children.size() != 0 && tree.children == null)
+            return false;
+        if (children == null)
+            return true;
+        int childrenSize = (children == null) ? 0 : children.size();
+        int treeChildrenSize = (tree.children == null) ? 0 : tree.children.size();
+        if (childrenSize != treeChildrenSize)
+            return false;
+        if (childrenSize == 0)
+            return true;
+
+        // compare children, force sort of entries by id
+        Collections.sort(children, new EntryTypeComparator());
+        Collections.sort(tree.children, new EntryTypeComparator());
+        for (int i = 0; i < children.size(); i++) {
+            if (!children.get(i).equalsTree(tree.children.get(i)))
+                return false;
+        }
+        return true;
+    }
+
+    private class EntryTypeComparator implements Comparator<EntryTree> {
+        public int compare(EntryTree o1, EntryTree o2) {
+            return o1.entry.getId().toString().compareTo(o2.entry.getId().toString());
+        }
+    }
+
+    public interface TreeVisitor {
+        public void visit(EntryTree entry) throws Exception;
+    }
+
+    public void walkTree(TreeVisitor visitor) throws Exception {
+        walkEntry(this, visitor);
+    }
+
+    public void walkChildren(TreeVisitor visitor) throws Exception {
+        walkChildren(this, visitor);
+    }
+
+    private void walkEntry(EntryTree entryTree, TreeVisitor visitor) throws Exception {
+        visitor.visit(entryTree);
+        walkChildren(entryTree, visitor);
+    }
+
+    private void walkChildren(EntryTree entryTree, TreeVisitor visitor) throws Exception {
+        if (entryTree.children != null) {
+            for (EntryTree child : entryTree.children) {
+                walkEntry(child, visitor);
+            }
+        }
+    }
+
+    public int getEntryCount() {
+        int count = 1;
+        if (children != null) {
+            for (EntryTree entry : children) {
+                count += entry.getEntryCount();
+            }
+        }
+        return count;
+    }
+
+    @Override
+    public String toString() {
+        return "EntryTree: " + entry.getId() + ", count=" + getEntryCount();
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/fixture/EntryTree.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/Connection.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/Connection.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/Connection.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/Connection.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,29 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ *     Gabriele Columbro, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.http;
+
+import java.io.IOException;
+
+
+/**
+ * Http Connection
+ */
+public interface Connection {
+
+    public Response executeRequest(Request req) throws IOException;
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/Connection.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/ConnectionFactory.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/ConnectionFactory.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/ConnectionFactory.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/ConnectionFactory.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,29 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ *     Gabriele Columbro, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.http;
+
+
+/**
+ * Http Connection Factory
+ */
+public interface ConnectionFactory {
+    
+    public Connection createConnection();
+
+    public Connection createConnection(String username, String password);
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/ConnectionFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/DeleteRequest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/DeleteRequest.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/DeleteRequest.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/DeleteRequest.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,28 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ *     Gabriele Columbro, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.http;
+
+/**
+ * DELETE Request
+ */
+public class DeleteRequest extends Request {
+    
+    public DeleteRequest(String uri) {
+        super("delete", uri);
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/DeleteRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/GetRequest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/GetRequest.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/GetRequest.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/GetRequest.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,28 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ *     Gabriele Columbro, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.http;
+
+/**
+ * GET Request
+ */
+public class GetRequest extends Request {
+    
+    public GetRequest(String uri) {
+        super("get", uri);
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/GetRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/PatchRequest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/PatchRequest.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/PatchRequest.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/PatchRequest.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,38 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ *     Gabriele Columbro, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.http;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * PATCH Request
+ */
+public class PatchRequest extends Request {
+
+    public PatchRequest(String uri, String patch, String contentType) throws UnsupportedEncodingException {
+        super("patch", uri);
+        setBody(getEncoding() == null ? patch.getBytes() : patch.getBytes(getEncoding()));
+        setType(contentType);
+    }
+
+    public PatchRequest(String uri, byte[] patch, String contentType) {
+        super("patch", uri);
+        setBody(patch);
+        setType(contentType);
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/PatchRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/PostRequest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/PostRequest.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/PostRequest.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/PostRequest.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,38 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ *     Gabriele Columbro, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.http;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * POST Request
+ */
+public class PostRequest extends Request {
+    
+    public PostRequest(String uri, String post, String contentType) throws UnsupportedEncodingException {
+        super("post", uri);
+        setBody(getEncoding() == null ? post.getBytes() : post.getBytes(getEncoding()));
+        setType(contentType);
+    }
+
+    public PostRequest(String uri, byte[] post, String contentType) {
+        super("post", uri);
+        setBody(post);
+        setType(contentType);
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/PostRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/PutRequest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/PutRequest.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/PutRequest.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/PutRequest.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,38 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ *     Gabriele Columbro, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.http;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * PUT Request
+ */
+public class PutRequest extends Request {
+    
+    public PutRequest(String uri, String put, String contentType) throws UnsupportedEncodingException {
+        super("put", uri);
+        setBody(getEncoding() == null ? put.getBytes() : put.getBytes(getEncoding()));
+        setType(contentType);
+    }
+
+    public PutRequest(String uri, byte[] put, String contentType) {
+        super("put", uri);
+        setBody(put);
+        setType(contentType);
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/PutRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/Request.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/Request.java?rev=805426&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/Request.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/Request.java Tue Aug 18 14:27:55 2009
@@ -0,0 +1,116 @@
+/*
+ * 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:
+ *     David Caruana, Alfresco
+ *     Gabriele Columbro, Alfresco
+ */
+package org.apache.chemistry.tck.atompub.http;
+
+import java.util.Map;
+
+/**
+ * Request
+ */
+public class Request {
+    
+    private String method;
+    private String uri;
+    private Map<String, String> args;
+    private Map<String, String> headers;
+    private byte[] body;
+    private String encoding = "UTF-8";
+    private String contentType;
+
+    public Request(Request req) {
+        this.method = req.method;
+        this.uri = req.uri;
+        this.args = req.args;
+        this.headers = req.headers;
+        this.body = req.body;
+        this.encoding = req.encoding;
+        this.contentType = req.contentType;
+    }
+
+    public Request(String method, String uri) {
+        this.method = method;
+        this.uri = uri;
+    }
+
+    public String getMethod() {
+        return method;
+    }
+
+    public String getUri() {
+        return uri;
+    }
+
+    public String getFullUri() {
+        // calculate full uri
+        String fullUri = uri == null ? "" : uri;
+        if (args != null && args.size() > 0) {
+            char prefix = (uri.indexOf('?') == -1) ? '?' : '&';
+            for (Map.Entry<String, String> arg : args.entrySet()) {
+                fullUri += prefix + arg.getKey() + "=" + (arg.getValue() == null ? "" : arg.getValue());
+                prefix = '&';
+            }
+        }
+
+        return fullUri;
+    }
+
+    public Request setArgs(Map<String, String> args) {
+        this.args = args;
+        return this;
+    }
+
+    public Map<String, String> getArgs() {
+        return args;
+    }
+
+    public Request setHeaders(Map<String, String> headers) {
+        this.headers = headers;
+        return this;
+    }
+
+    public Map<String, String> getHeaders() {
+        return headers;
+    }
+
+    public Request setBody(byte[] body) {
+        this.body = body;
+        return this;
+    }
+
+    public byte[] getBody() {
+        return body;
+    }
+
+    public Request setEncoding(String encoding) {
+        this.encoding = encoding;
+        return this;
+    }
+
+    public String getEncoding() {
+        return encoding;
+    }
+
+    public Request setType(String contentType) {
+        this.contentType = contentType;
+        return this;
+    }
+
+    public String getType() {
+        return contentType;
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-tck-atompub/src/main/java/org/apache/chemistry/tck/atompub/http/Request.java
------------------------------------------------------------------------------
    svn:eol-style = native