/** * Copyright (C) 2010 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.xcmis.restatom; import org.apache.commons.codec.binary.Base64; import org.everrest.core.impl.ContainerResponse; import org.everrest.core.impl.MultivaluedMapImpl; import org.everrest.core.tools.ByteArrayContainerResponseWriter; import org.w3c.dom.NodeList; import org.xcmis.spi.BaseContentStream; import org.xcmis.spi.CmisConstants; import org.xcmis.spi.ConstraintException; import org.xcmis.spi.ContentStream; import org.xcmis.spi.ObjectNotFoundException; import org.xcmis.spi.model.CmisObject; import org.xcmis.spi.utils.MimeType; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MultivaluedMap; import javax.xml.parsers.DocumentBuilderFactory; /** * @author <a href="mailto:andrey.parfonov@exoplatform.com">Andrey Parfonov</a> * @version $Id: FolderChildrenCollectionTest.java 2 2010-02-04 17:21:49Z * andrew00x $ */ public class FolderChildrenCollectionTest extends BaseTest { public void testAllowableActions() throws Exception { String docId = createDocument(testFolderId, "doc1", null, null); String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/allowableactions/" + docId; ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); ContainerResponse resp = service("GET", requestURI, "http://localhost:8080/rest", null, null, writer); // printBody(writer.getBody()); assertEquals(200, resp.getStatus()); DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); f.setNamespaceAware(true); org.w3c.dom.Document xmlDoc = f.newDocumentBuilder().parse(new ByteArrayInputStream(writer.getBody())); org.w3c.dom.Node actions = getNode("cmis:allowableActions", xmlDoc); validateAllowableActions(actions); } public void testCreateDocument() throws Exception { String s = "<?xml version='1.0' encoding='utf-8'?>" // + "<entry xmlns='http://www.w3.org/2005/Atom'" + " xmlns:cmis='" + CmisConstants.CMIS_NS_URI + "'" // + " xmlns:cmisra='" + AtomCMIS.CMISRA_NS_URI + "'>" // + "<title>title</title><summary>summary</summary>" // + "<content type='text'>hello</content>" // + "<cmisra:object><cmis:properties>" // + "<cmis:propertyId localName='cmis:objectTypeId' propertyDefinitionId='cmis:objectTypeId'>" // + "<cmis:value>cmis:document</cmis:value></cmis:propertyId>" // + "</cmis:properties>" + "</cmisra:object></entry>"; String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/children/" + testFolderId; assertFalse(getChildren(testFolderId).getItems().iterator().hasNext()); ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); ContainerResponse resp = service("POST", requestURI, "http://localhost:8080/rest", null, s.getBytes(), writer); // printBody(writer.getBody()); assertEquals(201, resp.getStatus()); assertNotNull(resp.getHttpHeaders().getFirst(HttpHeaders.LOCATION)); assertTrue(getChildren(testFolderId).getItems().iterator().hasNext()); DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); f.setNamespaceAware(true); org.w3c.dom.Document xmlDoc = f.newDocumentBuilder().parse(new ByteArrayInputStream(writer.getBody())); org.w3c.dom.Node entry = getNode("atom:entry", xmlDoc); validateObjectEntry(entry, "cmis:document"); } public void testCreateDocumentInvalidName() throws Exception { String s = "<?xml version='1.0' encoding='utf-8'?>" // + "<entry xmlns='http://www.w3.org/2005/Atom'" + " xmlns:cmis='" + CmisConstants.CMIS_NS_URI + "'" // + " xmlns:cmisra='" + AtomCMIS.CMISRA_NS_URI + "'>" // + "<title>new_document</title><summary>summary</summary>" // + "<content type='text'>hello</content>" // + "<cmisra:object><cmis:properties>" // + "<cmis:propertyId localName='cmis:objectTypeId' propertyDefinitionId='cmis:objectTypeId'>" // + "<cmis:value>cmis:document</cmis:value></cmis:propertyId>" // + "</cmis:properties>" + "</cmisra:object></entry>"; String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/children/" + testFolderId; assertFalse(getChildren(testFolderId).getItems().iterator().hasNext()); ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); byte[] body = s.getBytes(); ContainerResponse resp = service("POST", requestURI, "http://localhost:8080/rest", null, body, writer); assertEquals(201, resp.getStatus()); // try create one more document with the same name 'new_document'. resp = service("POST", requestURI, "http://localhost:8080/rest", null, body, writer); assertEquals(409, resp.getStatus()); } public void testCreateDocumentCmisContent() throws Exception { String s = "<?xml version='1.0' encoding='utf-8'?>" // + "<entry xmlns='http://www.w3.org/2005/Atom'" + " xmlns:cmis='" + CmisConstants.CMIS_NS_URI + "'" // + " xmlns:cmisra='" + AtomCMIS.CMISRA_NS_URI + "'>" // + "<title>title</title><summary>summary</summary>" // + "<cmisra:content>" // + "<cmisra:mediatype>text/plain</cmisra:mediatype>" // + "<cmisra:base64>" + new String(Base64.encodeBase64("hello".getBytes())) + "</cmisra:base64>" // + "</cmisra:content>" // + "<cmisra:object><cmis:properties>" // + "<cmis:propertyId localName='cmis:objectTypeId' propertyDefinitionId='cmis:objectTypeId'>" // + "<cmis:value>cmis:document</cmis:value></cmis:propertyId>" // + "</cmis:properties>" + "</cmisra:object></entry>"; String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/children/" + testFolderId; assertFalse(getChildren(testFolderId).isHasMoreItems()); ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); ContainerResponse resp = service("POST", requestURI, "http://localhost:8080/rest", null, s.getBytes(), writer); // printBody(writer.getBody()); assertEquals(201, resp.getStatus()); assertNotNull(resp.getHttpHeaders().getFirst(HttpHeaders.LOCATION)); assertTrue(getChildren(testFolderId).getItems().iterator().hasNext()); CmisObject doc = getChildren(testFolderId).getItems().iterator().next(); byte[] buff = new byte[1024]; int rd = conn.getContentStream(doc.getObjectInfo().getId(), null).getStream().read(buff); assertEquals("hello", new String(buff, 0, rd)); DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); f.setNamespaceAware(true); org.w3c.dom.Document xmlDoc = f.newDocumentBuilder().parse(new ByteArrayInputStream(writer.getBody())); org.w3c.dom.Node entry = getNode("atom:entry", xmlDoc); validateObjectEntry(entry, "cmis:document"); } public void testCreateFolder() throws Exception { String s = "<?xml version='1.0' encoding='utf-8'?>" // + "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:cmis='" + CmisConstants.CMIS_NS_URI + "' "// + " xmlns:cmisra='" + AtomCMIS.CMISRA_NS_URI + "'>" // + "<title>title</title><summary>summary</summary>" // + "<cmisra:object><cmis:properties>" // + "<cmis:propertyId localName='cmis:objectTypeId' propertyDefinitionId='cmis:objectTypeId'>" // + "<cmis:value>cmis:folder</cmis:value></cmis:propertyId>" // + "</cmis:properties>" // + "</cmisra:object></entry>"; String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/children/" + testFolderId; assertFalse(getChildren(testFolderId).getItems().iterator().hasNext()); ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); ContainerResponse resp = service("POST", requestURI, "http://localhost:8080/rest", null, s.getBytes(), writer); // printBody(writer.getBody()); assertEquals(201, resp.getStatus()); assertNotNull(resp.getHttpHeaders().getFirst(HttpHeaders.LOCATION)); assertTrue(getChildren(testFolderId).getItems().iterator().hasNext()); DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); f.setNamespaceAware(true); org.w3c.dom.Document xmlDoc = f.newDocumentBuilder().parse(new ByteArrayInputStream(writer.getBody())); org.w3c.dom.Node entry = getNode("atom:entry", xmlDoc); validateObjectEntry(entry, "cmis:folder"); } public void testDeleteContent() throws Exception { ContentStream content = new BaseContentStream("to be or not to be".getBytes(), "file", MimeType .fromString("text/plain; charset=UTF-8")); String docId = createDocument(testFolderId, "doc1", null, content); ContentStream docStream = conn.getContentStream(docId, null); assertNotNull(docStream); String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/file/" + docId; ContainerResponse resp = service("DELETE", requestURI, "http://localhost:8080/rest", null, null); assertEquals(204, resp.getStatus()); try { docStream = conn.getContentStream(docId, null); fail("Should be the ConstraintException 'Object does not have content stream.'"); } catch (ConstraintException e) { // "Object does not have content stream." } } public void testDeleteObject() throws Exception { String docId = createDocument(testFolderId, "doc1", null, null); String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/object/" + docId; ContainerResponse resp = service("DELETE", requestURI, "http://localhost:8080/rest", null, null); assertEquals(204, resp.getStatus()); try { getCmisObject(docId); fail("Object should be removed."); } catch (ObjectNotFoundException e) { // ok } } public void testGetChildren() throws Exception { String doc1 = createDocument(testFolderId, "doc1", null, null); String doc2 = createDocument(testFolderId, "doc2", null, null); String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/children/" + testFolderId; ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); ContainerResponse resp = service("GET", requestURI, "http://localhost:8080/rest", null, null, writer); // printBody(writer.getBody()); assertEquals(200, resp.getStatus()); DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); f.setNamespaceAware(true); org.w3c.dom.Document xmlDoc = f.newDocumentBuilder().parse(new ByteArrayInputStream(writer.getBody())); org.w3c.dom.Node xmlFeed = getNode("atom:feed", xmlDoc); validateFeedCommons(xmlFeed); assertTrue(hasLink(AtomCMIS.LINK_SERVICE, xmlFeed)); assertTrue(hasLink(AtomCMIS.LINK_SELF, xmlFeed)); assertTrue(hasLink(AtomCMIS.LINK_VIA, xmlFeed)); assertTrue(hasLink(AtomCMIS.LINK_DOWN, xmlFeed)); assertTrue(hasLink(AtomCMIS.LINK_CMIS_FOLDERTREE, xmlFeed)); assertTrue(hasLink(AtomCMIS.LINK_UP, xmlFeed)); // assertEquals("", getStringElement("cmisra:numItems", xmlFeed)); NodeList entries = getNodeSet("atom:entry", xmlFeed); int length = entries.getLength(); assertEquals(2, length); List<String> docs = new ArrayList<String>(); for (int i = 0; i < length; i++) { org.w3c.dom.Node n = entries.item(i); validateObjectEntry(n, "cmis:document"); docs.add(getNodeValueWithNodeProperty("cmisra:object/cmis:properties", "cmis:propertyId", "cmis:objectId", n)); } assertEquals(2, docs.size()); assertTrue(docs.contains(doc1)); assertTrue(docs.contains(doc2)); } public void testGetChildrenWithAllowableActions() throws Exception { String document1 = createDocument(testFolderId, "doc1", null, null); String document2 = createDocument(testFolderId, "doc2", null, null); String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/children/" + testFolderId + "?includeAllowableActions=true"; ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); ContainerResponse resp = service("GET", requestURI, "http://localhost:8080/rest", null, null, writer); // printBody(writer.getBody()); assertEquals(200, resp.getStatus()); DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); f.setNamespaceAware(true); org.w3c.dom.Document xmlDoc = f.newDocumentBuilder().parse(new ByteArrayInputStream(writer.getBody())); org.w3c.dom.Node xmlFeed = getNode("atom:feed", xmlDoc); validateFeedCommons(xmlFeed); // assertEquals("2", getStringElement("cmisra:numItems", xmlFeed)); NodeList entries = getNodeSet("atom:entry", xmlFeed); int length = entries.getLength(); assertEquals(2, length); List<String> docs = new ArrayList<String>(); for (int i = 0; i < length; i++) { org.w3c.dom.Node n = entries.item(i); validateObjectEntry(n, "cmis:document"); validateAllowableActions(getNode("cmisra:object/cmis:allowableActions", n)); docs.add(getNodeValueWithNodeProperty("cmisra:object/cmis:properties", "cmis:propertyId", "cmis:objectId", n)); } assertEquals(2, docs.size()); assertTrue(docs.contains(document1)); assertTrue(docs.contains(document2)); } public void testGetContent() throws Exception { ContentStream content = new BaseContentStream("to be or not to be".getBytes(), "file", MimeType .fromString("text/plain; charset=UTF-8")); String docId = createDocument(testFolderId, "doc1", null, content); String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/file/" + docId; ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); ContainerResponse resp = service("GET", requestURI, "http://localhost:8080/rest", null, null, writer); assertEquals("to be or not to be", new String(writer.getBody())); assertEquals(200, resp.getStatus()); } public void testGetObject() throws Exception { String docId = createDocument(testFolderId, "doc1", null, null); String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/object/" + docId; ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); ContainerResponse resp = service("GET", requestURI, "http://localhost:8080/rest", null, null, writer); // printBody(writer.getBody()); assertEquals(200, resp.getStatus()); DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); f.setNamespaceAware(true); org.w3c.dom.Document xmlDoc = f.newDocumentBuilder().parse(new ByteArrayInputStream(writer.getBody())); org.w3c.dom.Node entry = getNode("atom:entry", xmlDoc); validateObjectEntry(entry, "cmis:document"); String resId = getNodeValueWithNodeProperty("cmisra:object/cmis:properties", "cmis:propertyId", "cmis:objectId", entry); assertEquals(docId, resId); } public void testGetObjectByPath() throws Exception { String docId = createDocument(testFolderId, "doc1", null, null); String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/objectbypath" + "?path=%2FtestRoot%2Fdoc1"; ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); ContainerResponse resp = service("GET", requestURI, "http://localhost:8080/rest", null, null, writer); // printBody(writer.getBody()); assertEquals(200, resp.getStatus()); DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); f.setNamespaceAware(true); org.w3c.dom.Document xmlDoc = f.newDocumentBuilder().parse(new ByteArrayInputStream(writer.getBody())); org.w3c.dom.Node entry = getNode("atom:entry", xmlDoc); validateObjectEntry(entry, "cmis:document"); String resId = getNodeValueWithNodeProperty("cmisra:object/cmis:properties", "cmis:propertyId", "cmis:objectId", entry); assertEquals(docId, resId); } public void testMoveObject() throws Exception { String id = createDocument(testFolderId, "doc1", null, null); String s = "<?xml version='1.0' encoding='utf-8'?>" // + "<entry xmlns='http://www.w3.org/2005/Atom'" + " xmlns:cmis='" + CmisConstants.CMIS_NS_URI + "'" // + " xmlns:cmisra='" + AtomCMIS.CMISRA_NS_URI + "'>" // + "<title>title</title><summary>summary</summary>" // + "<cmisra:object><cmis:properties>" // + "<cmis:propertyId localName='cmis:objectId' propertyDefinitionId='cmis:objectId'><cmis:value>" // + id // + "</cmis:value></cmis:propertyId>" // + "</cmis:properties></cmisra:object></entry>"; String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/children/" + rootFolderId + "?sourceFolderId=" + testFolderId; assertEquals(testFolderId, getParents(id).get(0).getObject().getObjectInfo().getId()); ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); ContainerResponse resp = service("POST", requestURI, "http://localhost:8080/rest", null, s.getBytes(), writer); // printBody(writer.getBody()); assertEquals(201, resp.getStatus()); assertNotNull(resp.getHttpHeaders().getFirst(HttpHeaders.LOCATION)); assertEquals(rootFolderId, getParents(id).get(0).getObject().getObjectInfo().getId()); DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); f.setNamespaceAware(true); org.w3c.dom.Document xmlDoc = f.newDocumentBuilder().parse(new ByteArrayInputStream(writer.getBody())); org.w3c.dom.Node entry = getNode("atom:entry", xmlDoc); validateObjectEntry(entry, "cmis:document"); } public void testSetContent() throws Exception { ContentStream content = new BaseContentStream("to be or not to be".getBytes(), "file", MimeType .fromString("text/plain; charset=UTF-8")); String docId = createDocument(testFolderId, "doc1", null, content); String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/file/" + docId; MultivaluedMap<String, String> headers = new MultivaluedMapImpl(); headers.putSingle(HttpHeaders.CONTENT_TYPE, "text/plain"); ContainerResponse resp = service("PUT", requestURI, "http://localhost:8080/rest", headers, "to be".getBytes()); assertEquals(201, resp.getStatus()); byte[] b = new byte[128]; ContentStream docStream = conn.getContentStream(docId, null); int r = docStream.getStream().read(b); assertEquals("to be", new String(b, 0, r)); } public void testSetContentNotUTF8() throws Exception { ContentStream content = new BaseContentStream("to be or not to be".getBytes(), "file", MimeType .fromString("text/plain; charset=UTF-8")); String docId = createDocument(testFolderId, "doc1", null, content); String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/file/" + docId; MultivaluedMap<String, String> headers = new MultivaluedMapImpl(); headers.putSingle(HttpHeaders.CONTENT_TYPE, "text/plain;charset=windows-1251"); ContainerResponse resp = service("PUT", requestURI, "http://localhost:8080/rest", headers, "тест".getBytes("windows-1251")); assertEquals(201, resp.getStatus()); byte[] b = new byte[128]; ContentStream docStream = conn.getContentStream(docId, null); // System.out.println(docStream.getMediaType()); int r = docStream.getStream().read(b); assertEquals("windows-1251", docStream.getMediaType().getParameter("charset")); assertEquals("тест", new String(b, 0, r, docStream.getMediaType().getParameter("charset"))); } public void testSetContentMultipart() throws Exception { String docId = createDocument(testFolderId, "doc1", null, null); String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/file/" + docId; MultivaluedMap<String, String> headers = new MultivaluedMapImpl(); headers.putSingle("content-type", "multipart/form-data; boundary=abcdef"); ByteArrayOutputStream out = new ByteArrayOutputStream(); PrintWriter w = new PrintWriter(out); w.write("--abcdef\r\n" // + "Content-Disposition: form-data; name=\"test-file\"; filename=\"test.txt\"\r\n" // + "Content-Type: text/plain\r\n" // + "\r\n" // + "to be or not to be" // + "\r\n" // + "--abcdef--\r\n"); w.flush(); byte[] data = out.toByteArray(); // printBody(data); ContainerResponse resp = service("POST", requestURI, "http://localhost:8080/rest", headers, data); assertEquals(201, resp.getStatus()); byte[] b = new byte[128]; ContentStream content = conn.getContentStream(docId, null); assertEquals("text/plain", content.getMediaType().getBaseType()); int r = content.getStream().read(b); assertEquals("to be or not to be", new String(b, 0, r)); } public void testUpdateProperties() throws Exception { String s = "<?xml version='1.0' encoding='utf-8'?>" // + "<entry xmlns='http://www.w3.org/2005/Atom'" // + " xmlns:cmis='" + CmisConstants.CMIS_NS_URI + "'" // + " xmlns:cmisra='" + AtomCMIS.CMISRA_NS_URI + "'>" // + "<title>title</title><summary>summary</summary>" // + "<cmisra:object><cmis:properties>" // // Do not update anything , all properties are read-only. + "</cmis:properties></cmisra:object></entry>"; String docId = createDocument(testFolderId, "doc1", null, null); String requestURI = "http://localhost:8080/rest/cmisatom/" + cmisRepositoryId + "/object/" + docId; ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); MultivaluedMap<String, String> headers = new MultivaluedMapImpl(); headers.putSingle(HttpHeaders.CONTENT_TYPE, "application/atom+xml;type=entry"); ContainerResponse resp = service("PUT", requestURI, "http://localhost:8080/rest", headers, s.getBytes(), writer); // printBody(writer.getBody()); assertEquals(200, resp.getStatus()); DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); f.setNamespaceAware(true); org.w3c.dom.Document xmlDoc = f.newDocumentBuilder().parse(new ByteArrayInputStream(writer.getBody())); org.w3c.dom.Node entry = getNode("atom:entry", xmlDoc); validateObjectEntry(entry, "cmis:document"); } }