001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Florent Guillaume 018 */ 019package org.nuxeo.ecm.core.opencmis.tests; 020 021import java.io.ByteArrayOutputStream; 022import java.io.IOException; 023import java.io.InputStream; 024import java.io.Serializable; 025import java.util.Calendar; 026import java.util.GregorianCalendar; 027import java.util.HashMap; 028import java.util.Map; 029import java.util.TimeZone; 030 031import org.apache.commons.codec.digest.DigestUtils; 032import org.nuxeo.ecm.core.api.Blob; 033import org.nuxeo.ecm.core.api.Blobs; 034import org.nuxeo.ecm.core.api.CoreSession; 035import org.nuxeo.ecm.core.api.DocumentModel; 036import org.nuxeo.ecm.core.api.DocumentRef; 037import org.nuxeo.ecm.core.api.NuxeoException; 038import org.nuxeo.ecm.core.api.PathRef; 039import org.nuxeo.ecm.core.api.VersioningOption; 040import org.nuxeo.ecm.core.api.impl.DocumentModelImpl; 041import org.nuxeo.ecm.core.api.security.ACE; 042import org.nuxeo.ecm.core.api.security.ACL; 043import org.nuxeo.ecm.core.api.security.ACP; 044import org.nuxeo.ecm.core.api.security.SecurityConstants; 045import org.nuxeo.ecm.core.api.security.impl.ACLImpl; 046import org.nuxeo.ecm.core.api.security.impl.ACPImpl; 047import org.nuxeo.ecm.core.api.trash.TrashService; 048import org.nuxeo.ecm.platform.thumbnail.ThumbnailConstants; 049import org.nuxeo.runtime.api.Framework; 050import org.nuxeo.runtime.transaction.TransactionHelper; 051 052/** 053 * Various static methods used in several test cases. 054 */ 055public class Helper { 056 057 public static final String FILE1_CONTENT = "Noodles with rice"; 058 059 /** 060 * Reads a stream into a string. 061 */ 062 public static String read(InputStream in, String charset) throws IOException { 063 ByteArrayOutputStream os = new ByteArrayOutputStream(); 064 byte[] buf = new byte[256]; 065 try { 066 int n; 067 while ((n = in.read(buf)) != -1) { 068 os.write(buf, 0, n); 069 } 070 } finally { 071 in.close(); 072 } 073 return os.toString(charset); 074 } 075 076 /** 077 * Gets a Calendar object. 078 */ 079 public static GregorianCalendar getCalendar(int year, int month, int day, int hours, int minutes, int seconds) { 080 TimeZone tz = TimeZone.getTimeZone("GMT-02:00"); // in the Atlantic 081 return getCalendar(year, month, day, hours, minutes, seconds, tz); 082 } 083 084 /** 085 * Gets a Calendar object with a specific timezone 086 */ 087 public static GregorianCalendar getCalendar(int year, int month, int day, int hours, int minutes, int seconds, 088 TimeZone tz) { 089 GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance(tz); 090 cal.set(Calendar.YEAR, year); 091 cal.set(Calendar.MONTH, month - 1); // 0-based 092 cal.set(Calendar.DAY_OF_MONTH, day); 093 cal.set(Calendar.HOUR_OF_DAY, hours); 094 cal.set(Calendar.MINUTE, minutes); 095 cal.set(Calendar.SECOND, seconds); 096 cal.set(Calendar.MILLISECOND, 0); 097 return cal; 098 } 099 100 public static Map<String, String> makeNuxeoRepository(CoreSession session) { 101 return makeNuxeoRepository(session, false); 102 } 103 104 /** 105 * Creates data in the repository using the Nuxeo API. This is then used as a starting point by unit tests. 106 */ 107 public static Map<String, String> makeNuxeoRepository(CoreSession session, boolean addProxy) { 108 // remove default-domain 109 DocumentRef defaultDomain = new PathRef("/default-domain"); 110 if (session.exists(defaultDomain)) { 111 session.removeDocument(defaultDomain); 112 } 113 114 Map<String, String> info = new HashMap<>(); 115 116 DocumentModel folder1 = session.createDocumentModel("/", "testfolder1", "Folder"); 117 folder1.setPropertyValue("dc:title", "testfolder1_Title"); 118 folder1 = createDocument(session, folder1); 119 120 DocumentModel file1 = session.createDocumentModel("/testfolder1", "testfile1", "File"); 121 file1.setPropertyValue("dc:title", "testfile1_Title"); 122 file1.setPropertyValue("dc:description", "testfile1_description"); 123 String content = FILE1_CONTENT; 124 String filename = "testfile.txt"; 125 Blob blob1 = Blobs.createBlob(content); 126 blob1.setDigest(DigestUtils.md5Hex(content)); 127 blob1.setFilename(filename); 128 file1.setPropertyValue("content", (Serializable) blob1); 129 Calendar cal1 = getCalendar(2007, 3, 1, 12, 0, 0, TimeZone.getDefault()); 130 file1.setPropertyValue("dc:created", cal1); 131 file1.setPropertyValue("dc:modified", cal1); 132 file1.setPropertyValue("dc:creator", "michael"); 133 file1.setPropertyValue("dc:lastContributor", "john"); 134 file1.setPropertyValue("dc:coverage", "foo/bar"); 135 file1.setPropertyValue("dc:subjects", new String[] { "foo", "gee/moo" }); 136 file1.addFacet(ThumbnailConstants.THUMBNAIL_FACET); 137 Blob thumbnailBlob; 138 String digest; 139 try { 140 thumbnailBlob = Blobs.createBlob(Helper.class.getResource("/text.png").openStream(), "image/png"); 141 try (InputStream stream = thumbnailBlob.getStream()) { 142 digest = DigestUtils.md5Hex(stream); 143 } 144 } catch (IOException e) { 145 throw new RuntimeException(e); 146 } 147 thumbnailBlob.setDigest(digest); 148 thumbnailBlob.setFilename("test.png"); 149 file1.setPropertyValue(ThumbnailConstants.THUMBNAIL_PROPERTY_NAME, (Serializable) thumbnailBlob); 150 file1 = createDocument(session, file1); 151 152 ACPImpl acp; 153 ACL acl; 154 acl = new ACLImpl(); 155 acl.add(new ACE("bob", SecurityConstants.BROWSE, true)); 156 acp = new ACPImpl(); 157 acp.addACL(acl); 158 file1.setACP(acp, true); 159 160 DocumentModel file2 = session.createDocumentModel("/testfolder1", "testfile2", "File"); 161 file2.setPropertyValue("dc:title", "testfile2_Title"); 162 file2.setPropertyValue("dc:description", "something"); 163 Calendar cal2 = getCalendar(2007, 4, 1, 12, 0, 0); 164 file2.setPropertyValue("dc:created", cal2); 165 file2.setPropertyValue("dc:creator", "pete"); 166 file2.setPropertyValue("dc:contributors", new String[] { "pete", "bob" }); 167 file2.setPropertyValue("dc:lastContributor", "bob"); 168 file2.setPropertyValue("dc:coverage", "football"); 169 file2 = createDocument(session, file2); 170 171 acl = new ACLImpl(); 172 acl.add(new ACE("bob", SecurityConstants.BROWSE, true)); 173 acp = new ACPImpl(); 174 acp.addACL(acl); 175 file2.setACP(acp, true); 176 177 DocumentModel file3 = session.createDocumentModel("/testfolder1", "testfile3", "Note"); 178 file3.setPropertyValue("note", "this is a note"); 179 file3.setPropertyValue("dc:title", "testfile3_Title"); 180 file3.setPropertyValue("dc:description", "testfile3_desc1 testfile3_desc2, testfile3_desc3"); 181 file3.setPropertyValue("dc:contributors", new String[] { "bob", "john" }); 182 file3.setPropertyValue("dc:lastContributor", "john"); 183 file3 = createDocument(session, file3); 184 185 DocumentModel folder2 = session.createDocumentModel("/", "testfolder2", "Folder"); 186 folder2.setPropertyValue("dc:title", "testfolder2_Title"); 187 folder2 = createDocument(session, folder2); 188 189 DocumentModel folder3 = session.createDocumentModel("/testfolder2", "testfolder3", "Folder"); 190 folder3.setPropertyValue("dc:title", "testfolder3_Title"); 191 folder3 = createDocument(session, folder3); 192 193 DocumentModel folder4 = session.createDocumentModel("/testfolder2", "testfolder4", "Folder"); 194 folder4.setPropertyValue("dc:title", "testfolder4_Title"); 195 folder4 = createDocument(session, folder4); 196 197 DocumentModel file4 = session.createDocumentModel("/testfolder2/testfolder3", "testfile4", "File"); 198 file4.setPropertyValue("dc:title", "testfile4_Title"); 199 file4.setPropertyValue("dc:description", "something"); 200 file4 = createDocument(session, file4); 201 202 DocumentModel file5 = session.createDocumentModel("/testfolder1", "testfile5", "File"); 203 file5.setPropertyValue("dc:title", "title5"); 204 file5 = createDocument(session, file5); 205 sleepForAuditGranularity(); 206 Framework.getService(TrashService.class).trashDocument(file5); 207 file5 = saveDocument(session, file5); 208 info.put("file5id", file5.getId()); 209 210 DocumentModel file6 = session.createDocumentModel("/testfolder2/testfolder3", "testfile6", "Note"); 211 file6.setPropertyValue("dc:title", "title6"); 212 file6 = createDocument(session, file6); 213 214 if (addProxy) { 215 sleepForAuditGranularity(); 216 file6.putContextData("disableDublinCoreListener", Boolean.TRUE); 217 DocumentRef file6verref = file6.checkIn(VersioningOption.MINOR, null); 218 219 sleepForAuditGranularity(); 220 DocumentModel proxy = session.createProxy(file6verref, folder2.getRef()); 221 info.put("file6verid", proxy.getSourceId()); 222 info.put("proxyid", proxy.getId()); 223 } 224 225 return info; 226 } 227 228 /** 229 * For audit, make sure event dates don't have the same millisecond. 230 */ 231 public static void sleepForAuditGranularity() { 232 try { 233 Thread.sleep(2); 234 } catch (InterruptedException e) { 235 Thread.currentThread().interrupt(); 236 throw new NuxeoException(e); 237 } 238 } 239 240 public static DocumentModel createDocument(CoreSession session, DocumentModel doc) { 241 sleepForAuditGranularity(); 242 // avoid changes in last contributor in these tests 243 doc.putContextData("disableDublinCoreListener", Boolean.TRUE); 244 return session.createDocument(doc); 245 } 246 247 public static DocumentModel saveDocument(CoreSession session, DocumentModel doc) { 248 sleepForAuditGranularity(); 249 return session.saveDocument(doc); 250 } 251 252 public static String createUserWorkspace(CoreSession repo, String username) { 253 254 DocumentModel container = repo.createDocumentModel("/", "UserWorkspaceRoot", "UserWorkspaceRoot"); 255 container = repo.createDocument(container); 256 { 257 ACP acp = new ACPImpl(); 258 ACL acl = new ACLImpl(); 259 acl.setACEs(new ACE[] { new ACE(SecurityConstants.EVERYONE, SecurityConstants.EVERYTHING, false) }); 260 acp.addACL(acl); 261 container.setACP(acp, true); 262 } 263 264 DocumentModel ws = new DocumentModelImpl(container.getPathAsString(), username, "Workspace"); 265 ws = repo.createDocument(ws); 266 ACP acp = new ACPImpl(); 267 { 268 ACL acl = new ACLImpl(); 269 acl.setACEs(new ACE[] { new ACE(username, SecurityConstants.EVERYTHING, true) }); 270 acp.addACL(acl); 271 ws.setACP(acp, true); 272 } 273 274 repo.save(); 275 if (TransactionHelper.isTransactionActive()) { 276 TransactionHelper.commitOrRollbackTransaction(); 277 TransactionHelper.startTransaction(); 278 } 279 return ws.getPathAsString(); 280 } 281}