001: /*
002: * Copyright 2004 Outerthought bvba and Schaubroeck nv
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: package org.outerj.daisy.repository.test;
017:
018: import org.outerj.daisy.repository.testsupport.AbstractDaisyTestCase;
019: import org.outerj.daisy.repository.*;
020: import org.outerj.daisy.repository.query.SortOrder;
021: import org.outerj.daisy.repository.comment.Comment;
022: import org.outerj.daisy.repository.comment.CommentManager;
023: import org.outerj.daisy.repository.comment.CommentVisibility;
024: import org.outerj.daisy.repository.acl.*;
025: import org.outerj.daisy.repository.user.UserManager;
026: import org.outerj.daisy.repository.user.Role;
027: import org.outerj.daisy.repository.user.User;
028: import org.outerj.daisy.repository.schema.*;
029:
030: import java.util.*;
031: import java.math.BigDecimal;
032:
033: public abstract class AbstractDocumentTest extends
034: AbstractDaisyTestCase {
035: protected boolean resetDataStores() {
036: return true;
037: }
038:
039: protected abstract RepositoryManager getRepositoryManager()
040: throws Exception;
041:
042: public void testDocument() throws Exception {
043: RepositoryManager repositoryManager = getRepositoryManager();
044: Repository adminRepository = repositoryManager
045: .getRepository(new Credentials("testuser", "testuser"));
046: adminRepository.switchRole(Role.ADMINISTRATOR);
047:
048: // create a user (without admin rights) which will do all operations
049: UserManager userManager = adminRepository.getUserManager();
050: Role role = userManager.getRole("User", false);
051: User user = userManager.createUser("ordinaryUser");
052: user.addToRole(role);
053: user.setDefaultRole(role);
054: user.setPassword("secret");
055: user.save();
056: Repository repository = repositoryManager
057: .getRepository(new Credentials("ordinaryUser", "secret"));
058:
059: User user2 = userManager.createUser("ordinaryUser2");
060: user2.addToRole(role);
061: user2.setDefaultRole(role);
062: user2.setPassword("secret");
063: user2.save();
064: Repository user2Repository = repositoryManager
065: .getRepository(new Credentials("ordinaryUser2",
066: "secret"));
067:
068: RepositorySchema schema = adminRepository.getRepositorySchema();
069:
070: // Create some field types
071: FieldType stringField1 = schema.createFieldType("StringField1",
072: ValueType.STRING);
073: stringField1.save();
074: FieldType dateField1 = schema.createFieldType("DateField1",
075: ValueType.DATE);
076: dateField1.save();
077: FieldType dateTimeField1 = schema.createFieldType(
078: "DateTimeField1", ValueType.DATETIME);
079: dateTimeField1.save();
080: FieldType decimalField1 = schema.createFieldType(
081: "DecimalField1", ValueType.DECIMAL);
082: decimalField1.save();
083: FieldType doubleField1 = schema.createFieldType("DoubleField1",
084: ValueType.DOUBLE);
085: doubleField1.save();
086: FieldType longField1 = schema.createFieldType("LongField1",
087: ValueType.LONG);
088: longField1.save();
089: FieldType booleanField1 = schema.createFieldType(
090: "BoolenField1", ValueType.BOOLEAN);
091: booleanField1.save();
092: FieldType linkField1 = schema.createFieldType("LinkField1",
093: ValueType.LINK);
094: linkField1.save();
095:
096: // Create some part types
097: PartType partType1 = schema.createPartType("PartType1",
098: "text/xml");
099: partType1.save();
100: PartType partType2 = schema.createPartType("PartType2", "");
101: partType2.save();
102: PartType partType3 = schema.createPartType("PartType3",
103: "image/gif,image/jpeg");
104: partType3.save();
105:
106: // Create a documenttype
107: DocumentType documentType1 = schema
108: .createDocumentType("DocumentType1");
109: documentType1.addFieldType(stringField1, true);
110: documentType1.addFieldType(dateField1, true);
111: documentType1.addFieldType(dateTimeField1, false);
112: documentType1.addFieldType(decimalField1, false);
113: documentType1.addFieldType(doubleField1, false);
114: documentType1.addFieldType(longField1, false);
115: documentType1.addFieldType(booleanField1, false);
116: documentType1.addFieldType(linkField1, false);
117: documentType1.addPartType(partType1, false);
118: documentType1.addPartType(partType2, true);
119: documentType1.addPartType(partType3, false);
120: documentType1.save();
121:
122: // Create a document type without any required fields or parts
123: DocumentType documentType2 = schema
124: .createDocumentType("DocumentType2");
125: documentType2.addFieldType(stringField1, false);
126: documentType2.addFieldType(dateField1, false);
127: documentType2.addFieldType(dateTimeField1, false);
128: documentType2.addFieldType(decimalField1, false);
129: documentType2.addFieldType(doubleField1, false);
130: documentType2.addFieldType(longField1, false);
131: documentType2.addFieldType(booleanField1, false);
132: documentType2.addFieldType(linkField1, false);
133: documentType2.addPartType(partType1, false);
134: documentType2.addPartType(partType2, false);
135: documentType2.addPartType(partType3, false);
136: documentType2.save();
137:
138: // Create an ACL
139: // Note: testing more meaningful ACL's is done by the separate ACL testcase.
140: AccessManager accessManager = adminRepository
141: .getAccessManager();
142: Acl acl = accessManager.getStagingAcl();
143: AclObject aclObject = acl.createNewObject("true");
144: AclEntry aclEntry = aclObject.createNewEntry(
145: AclSubjectType.EVERYONE, -1);
146: aclEntry.set(AclPermission.READ, AclActionType.GRANT);
147: aclEntry.set(AclPermission.WRITE, AclActionType.GRANT);
148: aclEntry.set(AclPermission.PUBLISH, AclActionType.GRANT);
149: aclEntry.set(AclPermission.DELETE, AclActionType.GRANT);
150: aclObject.add(aclEntry);
151: aclEntry = aclObject.createNewEntry(AclSubjectType.USER, user2
152: .getId());
153: aclEntry.set(AclPermission.READ, AclActionType.GRANT);
154: aclEntry.set(AclPermission.WRITE, AclActionType.DENY);
155: aclEntry.set(AclPermission.PUBLISH, AclActionType.DENY);
156: aclEntry.set(AclPermission.DELETE, AclActionType.DENY);
157: aclObject.add(aclEntry);
158: acl.add(aclObject);
159: acl.save();
160: accessManager.copyStagingToLive();
161:
162: //
163: // Basic document creation
164: //
165: Document document1 = repository.createDocument("Document 1",
166: documentType1.getId());
167:
168: // set a field using, once using id, once using name
169: document1.setField(stringField1.getId(), "hello");
170: document1.setField("DateField1", new Date());
171:
172: // set a part, once using id, once using name
173: byte[] part2Data = "meaningful data".getBytes();
174: byte[] part3Data = "myimage".getBytes();
175: document1.setPart(partType2.getId(),
176: "application/x-meaningful", part2Data);
177: document1.setPart("PartType3", "image/gif", part3Data);
178:
179: document1.save();
180:
181: //
182: // Test data is correctly saved and loaded
183: //
184: Document document1Reloaded = repository.getDocument(document1
185: .getId(), true);
186: assertEquals("hello", (String) document1Reloaded.getField(
187: "StringField1").getValue());
188: System.out.println(((Date) document1.getField(
189: dateField1.getId()).getValue()).getTime()
190: + " - "
191: + ((Date) document1Reloaded
192: .getField(dateField1.getId()).getValue())
193: .getTime());
194: assertEquals(document1.getField(dateField1.getId()).getValue(),
195: document1Reloaded.getField(dateField1.getId())
196: .getValue());
197: assertEquals(part2Data, document1Reloaded.getPart("PartType2")
198: .getData());
199: assertEquals(part3Data, document1Reloaded.getPart(
200: partType3.getId()).getData());
201:
202: //
203: // Calling save now on document should not create new version
204: //
205: document1.save();
206: assertEquals(1, document1.getLastVersionId());
207: assertEquals(1, document1.getLastVersion().getId());
208:
209: //
210: // Create document with missing field
211: //
212: Document document2 = repository.createDocument("Document 2",
213: documentType1.getId());
214: document2.setField(stringField1.getId(), "yo");
215: document2.setPart(partType2.getId(),
216: "application/x-meaningful", part2Data);
217: try {
218: document2.save();
219: fail("Saving document should have failed due to missing field.");
220: } catch (Exception e) {
221: }
222: // try saving with disabling validation
223: document2.save(false);
224: // now set missing field -- should now save successfully
225: document2.setField(dateField1.getId(), new Date());
226: document2.save(true);
227: // meanwhile test that the part isn't changed
228: assertEquals(1, document2.getPart(partType2.getId())
229: .getDataChangedInVersion());
230: // also not when document is completely reloaded
231: assertEquals(1, repository.getDocument(document2.getId(), true)
232: .getLastVersion().getPart(partType2.getId())
233: .getDataChangedInVersion());
234:
235: document2.deletePart(partType2.getId());
236: try {
237: document2.save();
238: fail("Saving document should have failed due to missing part.");
239: } catch (Exception e) {
240: }
241: // set missing part -- should now save succesfully
242: document2.setPart(partType2.getId(),
243: "application/x-meaningful", part2Data);
244: document2.save();
245:
246: //
247: // Test setting new data for a part
248: //
249: byte[] newPart2Data = "Apples and Oranges".getBytes();
250: document2.setPart(partType2.getId(),
251: "application/x-meaningful", newPart2Data);
252: document2.save();
253:
254: Document document2Reloaded = repository.getDocument(document2
255: .getId(), true);
256: assertEquals(newPart2Data, document2Reloaded.getPart(
257: partType2.getId()).getData());
258: assertEquals(document2.getLastVersionId(), document2Reloaded
259: .getPart(partType2.getId()).getDataChangedInVersion());
260:
261: //
262: // Test setting data with incorrect mimetype
263: //
264: try {
265: document2.setPart(partType1.getId(), "image/zarba",
266: part3Data);
267: fail("Setting data with incorrect mimetype should fail.");
268: } catch (Exception e) {
269: }
270:
271: //
272: // Test out all types of fields
273: //
274: Document document3 = repository.createDocument("Document 3",
275: documentType1.getId());
276: document3.setField(stringField1.getId(), "hello");
277: Date currentDate = getDate(new Date());
278: document3.setField(dateField1.getId(), currentDate);
279: Date currentDateTime = getDateTime(new Date());
280: document3.setField(dateTimeField1.getId(), currentDateTime);
281: document3.setField(decimalField1.getId(), new BigDecimal(
282: "33.43539"));
283: document3.setField(doubleField1.getId(), new Double(343.232d));
284: document3.setField(longField1.getId(), new Long(23234235));
285: document3.setField(booleanField1.getId(), Boolean.FALSE);
286: document3.setField(linkField1.getId(), new VariantKey(
287: "23-DSYTEST", 2, 8));
288: document3.setPart(partType2.getId(),
289: "application/x-meaningful", part2Data);
290: document3.save();
291:
292: // test field values are same after reloading document
293: document3 = repository.getDocument(document3.getId(), true);
294: assertEquals(currentDate, document3
295: .getField(dateField1.getId()).getValue());
296: assertEquals(currentDateTime, document3.getField(
297: dateTimeField1.getId()).getValue());
298: assertEquals(new BigDecimal("33.43539"), document3.getField(
299: decimalField1.getId()).getValue());
300: assertEquals(new Double(343.232d), document3.getField(
301: doubleField1.getId()).getValue());
302: assertEquals(new Long(23234235), document3.getField(
303: longField1.getId()).getValue());
304: assertEquals(Boolean.FALSE, document3.getField(
305: booleanField1.getId()).getValue());
306: assertEquals(new VariantKey("23-DSYTEST", 2, 8), document3
307: .getField(linkField1.getId()).getValue());
308:
309: //
310: // Test setting wrong type of value on a field
311: //
312: Document document12 = repository.createDocument("Document 12",
313: documentType1.getId());
314: try {
315: document12.setField(doubleField1.getId(), new Long(123));
316: fail("Setting wrong object as field value should give an exception.");
317: } catch (Exception e) {
318: }
319:
320: //
321: // Test retired and private flags
322: //
323: Document document4 = repository.createDocument("Document 4",
324: documentType1.getId());
325: document4.setField(stringField1.getId(), "hello");
326: document4.setField("DateField1", new Date());
327: document4.setPart(partType2.getId(),
328: "application/x-meaningful", part2Data);
329: document4.save();
330: assertEquals(false, document4.isRetired());
331: assertEquals(false, document4.isPrivate());
332: document4.setRetired(true);
333: document4.setPrivate(true);
334: document4.save();
335: document4 = repository.getDocument(document4.getId(), false);
336: assertEquals(true, document4.isRetired());
337: assertEquals(true, document4.isPrivate());
338:
339: //
340: // Test document cache
341: //
342: Document document5 = repository.createDocument("Document 5",
343: documentType1.getId());
344: document5.setField(stringField1.getId(), "hello");
345: document5.setField("DateField1", new Date());
346: document5.setPart(partType2.getId(),
347: "application/x-meaningful", part2Data);
348: document5.save();
349: Document document5ReadOnly = repository.getDocument(document5
350: .getId(), false);
351: try {
352: document5ReadOnly.save();
353: fail("Saving document should have failed because it is not modifiable.");
354: } catch (Exception e) {
355: }
356: // Do a document update and verify that cache has been refreshed
357: document5.setField(stringField1.getId(), "hello!");
358: document5.save();
359: document5ReadOnly = repository.getDocument(document5.getId(),
360: false);
361: assertEquals("hello!", (String) document5ReadOnly.getField(
362: stringField1.getId()).getValue());
363:
364: //
365: // Test comments
366: //
367: CommentManager commentManager = repository.getCommentManager();
368: Document document6 = repository.createDocument("Document 6",
369: documentType2.getId());
370: try {
371: commentManager.addComment(document6.getId(),
372: CommentVisibility.PUBLIC,
373: "Hi, I have something to say.");
374: fail("Adding comment to a non-saved document should fail.");
375: } catch (Exception e) {
376: }
377: document6.save();
378: String comment1Text = "Hi, I have something to say.";
379: commentManager.addComment(document6.getId(),
380: CommentVisibility.PUBLIC, comment1Text);
381: commentManager.addComment(document6.getId(),
382: CommentVisibility.PUBLIC,
383: "Hi, I have another thing to say.");
384: commentManager.addComment(document6.getId(),
385: CommentVisibility.PRIVATE, "This document sucks.");
386: commentManager.addComment(document6.getId(),
387: CommentVisibility.EDITORS, "Oh yes.");
388: Comment[] comments = commentManager.getComments(
389: document6.getId()).getArray();
390: assertEquals(4, comments.length);
391: assertEquals(comments[0].getCreatedBy(), user.getId());
392: assertEquals(comments[0].getText(), comment1Text);
393:
394: assertEquals(4, commentManager.getComments().getArray().length);
395: assertEquals(1, commentManager.getComments(
396: CommentVisibility.PRIVATE).getArray().length);
397: assertEquals(2, commentManager.getComments(
398: CommentVisibility.PUBLIC).getArray().length);
399: assertEquals(1, commentManager.getComments(
400: CommentVisibility.EDITORS).getArray().length);
401:
402: // another user should not see the private or editors-only comments
403: assertEquals(2, user2Repository.getCommentManager()
404: .getComments(document6.getId()).getArray().length);
405:
406: // admin user should see all comments except private comments
407: assertEquals(3, adminRepository.getCommentManager()
408: .getComments(document6.getId()).getArray().length);
409:
410: commentManager
411: .addComment(document6.getId(),
412: CommentVisibility.PUBLIC,
413: "This document is o so nice.");
414: // first user should see new comment without re-fetching document
415: assertEquals(5, commentManager.getComments(document6.getId())
416: .getArray().length);
417:
418: // test deleting comments
419: commentManager.deleteComment(document6.getId(), comments[0]
420: .getId());
421: assertEquals(4, commentManager.getComments(document6.getId())
422: .getArray().length);
423:
424: try {
425: commentManager.deleteComment(document6.getId(), 10);
426: fail("Deleting non-existing comment should give exception.");
427: } catch (Exception e) {
428: }
429:
430: // user without write rights should be able to make a private comment and delete it again
431: user2Repository.getCommentManager().addComment(
432: document6.getId(), CommentVisibility.PRIVATE,
433: "This is a comment.");
434: Comment[] user2Comments = user2Repository.getCommentManager()
435: .getComments(document6.getId()).getArray();
436: user2Repository.getCommentManager().deleteComment(
437: document6.getId(),
438: user2Comments[user2Comments.length - 1].getId());
439:
440: // ... but should not be able to delete other comments
441: try {
442: user2Repository.getCommentManager().deleteComment(
443: document6.getId(),
444: user2Comments[user2Comments.length - 2].getId());
445: fail("User without write rights should not be able to delete non-private comments.");
446: } catch (RepositoryException e) {
447: }
448:
449: commentManager.addComment(document6.getId(),
450: CommentVisibility.PRIVATE, "Private comment");
451: Comment[] comments2 = commentManager.getComments(
452: document6.getId()).getArray();
453: try {
454: user2Repository.getCommentManager().deleteComment(
455: document6.getId(),
456: comments2[comments2.length - 1].getId());
457: fail("Non-admin user should not be able to delete other users' private comments.");
458: } catch (RepositoryException e) {
459: }
460:
461: // admin user should be able to delete otehr users' private comments
462: adminRepository.getCommentManager().deleteComment(
463: document6.getId(),
464: comments2[comments2.length - 1].getId());
465:
466: //
467: // Test customfields
468: //
469: Document document7 = repository.createDocument("Document 7",
470: documentType2.getId());
471: document7.save();
472: document7.setCustomField("some field", "some value");
473: document7.setCustomField("some field 2", "123");
474: document7.save();
475: document7 = repository.getDocument(document7.getId(), true);
476: assertEquals("123", document7.getCustomField("some field 2"));
477: document7.deleteCustomField("some field 2");
478: assertNull(document7.getCustomField("some field 2"));
479: document7.save();
480:
481: //
482: // Test locks
483: //
484: Document document8 = repository.createDocument("Document 8",
485: documentType2.getId());
486: document8.save();
487: LockInfo lockInfo = document8.getLockInfo(false);
488: assertEquals(false, lockInfo.hasLock());
489: document8.lock(1000000, LockType.PESSIMISTIC);
490: // we have a lock, so should be able to save the document
491: // TODO this doesn't make sense anymore since saving is never done if document is not modified
492: document8.save();
493: // another user should not be able to save it...
494: Document document8OtherUser = adminRepository.getDocument(
495: document8.getId(), true);
496: try {
497: document8OtherUser.setCustomField("a", "b");
498: document8OtherUser.save();
499: fail("Saving document should have failed because lock belongs to another user.");
500: } catch (Exception e) {
501: }
502: // .. but if we remove the lock, it should work
503: document8.releaseLock();
504: document8OtherUser.save();
505: // test lock expires
506: document8.lock(1, LockType.PESSIMISTIC);
507: Thread.sleep(1200); // lock creation time is stored only with one-second precision, so take that and some margin
508: lockInfo = document8OtherUser.getLockInfo(true);
509: assertEquals(false, lockInfo.hasLock());
510:
511: // Try to create a never-expiring lock
512: document8.lock(-1, LockType.PESSIMISTIC);
513: assertEquals(-1, document8.getLockInfo(true).getDuration());
514:
515: //
516: // Test versions
517: //
518: Document document9 = repository.createDocument("Document 9",
519: documentType1.getId());
520: document9.setField(stringField1.getId(), "hello");
521: document9.setField("DateField1", new Date());
522: document9.setPart(partType2.getId(),
523: "application/x-meaningful", part2Data);
524: document9.save();
525:
526: Version version = document9.getVersion(1);
527: assertEquals(part2Data, version.getPart(partType2.getId())
528: .getData());
529:
530: //
531: // Test collections
532: //
533: CollectionManager collectionManager = adminRepository
534: .getCollectionManager();
535: DocumentCollection collection1 = collectionManager
536: .createCollection("Collection1");
537: collection1.save();
538: DocumentCollection collection2 = collectionManager
539: .createCollection("Collection2");
540: collection2.save();
541: DocumentCollection collection3 = collectionManager
542: .createCollection("Collection3");
543: collection3.save();
544:
545: Document document10 = repository.createDocument("Document 10",
546: documentType2.getId());
547: document10.addToCollection(collection1);
548: document10.save();
549: assertEquals(1, document10.getCollections().getArray().length);
550: document10 = repository.getDocument(document10.getId(), true);
551: assertEquals(1, document10.getCollections().getArray().length);
552:
553: document10.addToCollection(collection2);
554: document10.addToCollection(collection3);
555: document10.save();
556:
557: document10 = repository.getDocument(document10.getId(), true);
558: DocumentCollection[] collections = document10.getCollections()
559: .getArray();
560: HashSet names = new HashSet();
561: for (int i = 0; i < collections.length; i++) {
562: names.add(collections[i].getName());
563: }
564: assertEquals(true, names.contains("Collection1"));
565: assertEquals(true, names.contains("Collection2"));
566: assertEquals(true, names.contains("Collection3"));
567:
568: // delete a collection still belonging to the document, check it is removed after doc loading
569: collectionManager.deleteCollection(collection3.getId());
570: document10 = repository.getDocument(document10.getId(), true);
571: assertEquals(2, document10.getCollections().getArray().length);
572:
573: // remove a collection from the document
574: document10.removeFromCollection(collection2);
575: document10.save();
576: document10 = repository.getDocument(document10.getId(), true);
577: assertEquals(1, document10.getCollections().getArray().length);
578:
579: // delete a collection still belonging to the document, and then save the document
580: // (the document object has still the collection in it)
581: collectionManager.deleteCollection(collection1.getId());
582: document10.save();
583: document10 = repository.getDocument(document10.getId(), false);
584: assertEquals(0, document10.getCollections().getArray().length);
585:
586: // All these collection operations shouldn't have created any new versions
587: assertEquals(1, document10.getVersions().getArray().length);
588:
589: //
590: // Test links
591: //
592: Document document11 = repository.createDocument("Document 11",
593: documentType2.getId());
594: document11.addLink("Google", "http://www.google.be");
595: document11.save();
596: document11 = repository.getDocument(document11.getId(), true);
597: assertEquals(1, document11.getLinks().getArray().length);
598: document11.clearLinks();
599: document11.save();
600: document11 = repository.getDocument(document11.getId(), true);
601: assertEquals(0, document11.getLinks().getArray().length);
602:
603: //
604: // Test concurrent modification detection
605: //
606: Document document20 = repository.createDocument("Document 20",
607: documentType2.getId());
608: document20.save();
609: Document document20Parallel = repository.getDocument(document20
610: .getId(), true);
611: document20Parallel.setCustomField("p", "t");
612: document20Parallel.save();
613: try {
614: document20.setCustomField("r", "s");
615: document20.save();
616: fail("Saving document should have failed because of concurrent modifications.");
617: } catch (Exception e) {
618: }
619: ;
620:
621: //
622: // Test changing the document type
623: //
624: {
625: Document document30 = repository.createDocument(
626: "Document 30", documentType1.getId());
627: document30.setField(stringField1.getId(), "value30");
628: document30.setField(dateField1.getId(), new Date());
629: document30.setPart(partType2.getId(),
630: "application/x-meaningful", part2Data);
631: document30.save();
632: assertEquals("document type check", documentType1.getId(),
633: document30.getDocumentTypeId());
634:
635: FieldType fieldType = schema.createFieldType("MyString",
636: ValueType.STRING);
637: fieldType.save();
638:
639: // Create a document type with a field which was not present in the previous doc type, and vice versa
640: // This in order to check that validation happens against the new document type
641: DocumentType newDocType = schema.createDocumentType("Foo");
642: newDocType.addFieldType(fieldType, false);
643: newDocType.addFieldType(dateField1, false);
644: newDocType.save();
645:
646: document30.changeDocumentType(newDocType.getId());
647: document30.deleteField(stringField1.getId()); // delete field since it is not allowed anymore
648: document30.deletePart(partType2.getId()); // dito
649: document30.setField("MyString", "hallo hallo");
650: document30.save();
651:
652: document30 = repository.getDocument(document30.getId(),
653: true);
654: assertEquals("document type check", newDocType.getId(),
655: document30.getDocumentTypeId());
656: }
657:
658: //
659: // Test deleting documents
660: //
661: Document document40 = repository.createDocument("Document 40",
662: documentType1.getId());
663: document40.setField(stringField1.getId(), "value40");
664: document40.setField(dateField1.getId(), new Date());
665: document40.setPart(partType2.getId(),
666: "application/x-meaningful", part2Data);
667: document40.save();
668: repository.deleteDocument(document40.getId());
669:
670: //
671: // Test changing owner
672: //
673: DocumentType simpleDocType = adminRepository
674: .getRepositorySchema().createDocumentType(
675: "SimpleDocType");
676: simpleDocType.save();
677: Document document50 = repository.createDocument("Document 50",
678: "SimpleDocType");
679: document50.save();
680:
681: // test current owner is able to change role
682: document50.setOwner(user2.getId());
683: document50.save();
684:
685: document50 = repository.getDocument(document50.getId(), false);
686: assertEquals(user2.getId(), document50.getOwner());
687:
688: // changing role on non-modifiable document object should not be possible
689: try {
690: document50.setOwner(adminRepository.getUserId());
691: fail("Changing role on non-modifiable document object should not be possible.");
692: } catch (RuntimeException e) {
693: }
694:
695: // test non-admin non-owner is not able to change role
696: document50 = repository.getDocument(document50.getId(), true);
697: try {
698: document50.setOwner(adminRepository.getUserId());
699: fail("Ordinary user should not be able to change owner.");
700: } catch (RepositoryRuntimeException e) {
701: }
702:
703: // test admin is able to change role
704: document50 = adminRepository.getDocument(document50.getId(),
705: true);
706: document50.setOwner(user.getId());
707:
708: try {
709: repository.deleteDocument(document40.getId());
710: fail("Expected a DocumentNotFoundException.");
711: } catch (DocumentNotFoundException e) {
712: }
713:
714: //
715: // Test multivalue fields
716: //
717: FieldType mvType1 = schema.createFieldType("mv1",
718: ValueType.STRING, true);
719: mvType1.save();
720: FieldType mvType2 = schema.createFieldType("mv2",
721: ValueType.LONG, true);
722: mvType2.save();
723: DocumentType mvDoctype = schema
724: .createDocumentType("mvdoctype1");
725: mvDoctype.addFieldType(mvType1, true);
726: mvDoctype.addFieldType(mvType2, true);
727: mvDoctype.save();
728:
729: Document mvDoc = repository.createDocument(
730: "multivalue field test doc", mvDoctype.getId());
731: mvDoc.setField(mvType1.getId(), new String[] { "value1",
732: "value2" });
733: mvDoc.setField("mv2", new Object[] { new Long(12) });
734: mvDoc.save();
735:
736: mvDoc = repository.getDocument(mvDoc.getId(), true);
737: Object[] mvValues = (Object[]) mvDoc.getField(mvType1.getId())
738: .getValue();
739: assertEquals(2, mvValues.length);
740: assertEquals("value1", mvValues[0]);
741: assertEquals("value2", mvValues[1]);
742: mvValues = (Object[]) mvDoc.getField(mvType2.getId())
743: .getValue();
744: assertEquals(1, mvValues.length);
745: assertEquals(new Long(12), mvValues[0]);
746:
747: try {
748: mvDoc.setField("mv2", new Object[0]);
749: fail("Zero-length array should not be allowed for the value of a multivalue field.");
750: } catch (DocumentTypeInconsistencyException e) {
751: }
752:
753: //
754: // Test hierarchical fields
755: //
756: FieldType hfType1 = schema.createFieldType("hf1",
757: ValueType.STRING, false, true);
758: hfType1.save();
759: FieldType hfType2 = schema.createFieldType("hf2",
760: ValueType.STRING, true, true);
761: hfType2.save();
762:
763: DocumentType hfDoctype = schema
764: .createDocumentType("hfdoctype1");
765: hfDoctype.addFieldType(hfType1, true);
766: hfDoctype.addFieldType(hfType2, true);
767: hfDoctype.save();
768:
769: Document hfDoc = repository.createDocument(
770: "hierarchical field test doc", hfDoctype.getId());
771: HierarchyPath path1 = new HierarchyPath(new String[] { "path1",
772: "path2" });
773: hfDoc.setField(hfType1.getId(), path1);
774: HierarchyPath path2 = new HierarchyPath(new String[] { "A" });
775: HierarchyPath path3 = new HierarchyPath(
776: new String[] { "A", "B" });
777: HierarchyPath path4 = new HierarchyPath(new String[] { "A",
778: "B", "C" });
779: Object[] multiValueHierarchicalValue = new Object[] { path2,
780: path3, path4 };
781: hfDoc.setField("hf2", multiValueHierarchicalValue);
782: hfDoc.save();
783:
784: hfDoc = repository.getDocument(hfDoc.getId(), true);
785: assertEquals(path1, hfDoc.getField(hfType1.getId()).getValue());
786: assertTrue(Arrays.equals(multiValueHierarchicalValue,
787: (Object[]) hfDoc.getField(hfType2.getId()).getValue()));
788:
789: // test toString implementation
790: assertEquals("/path1/path2", hfDoc.getField(hfType1.getId())
791: .getValue().toString());
792:
793: //
794: // Test part file name and mime type update
795: //
796: Document document60 = repository.createDocument("doc60",
797: documentType2.getId());
798: document60
799: .setPart(partType2.getId(),
800: "application/x-ooktettenstroom", new byte[] {
801: 1, 2, 3 });
802: document60
803: .setPartFileName(partType2.getId(), "myfilename.data");
804: assertEquals("myfilename.data", document60.getPart(
805: partType2.getId()).getFileName());
806: document60.save();
807: document60 = repository.getDocument(document60.getId(), true);
808: assertEquals("myfilename.data", document60.getPart(
809: partType2.getId()).getFileName());
810:
811: document60.setPartFileName(partType2.getId(),
812: "myfilenamenew.data");
813: document60.save();
814: document60 = repository.getDocument(document60.getId(), true);
815: assertEquals("myfilenamenew.data", document60.getPart(
816: partType2.getId()).getFileName());
817: assertEquals(2, document60.getLastVersionId());
818:
819: // setting part file name to same value should not cause any update
820: document60.setPartFileName(partType2.getId(),
821: "myfilenamenew.data");
822: document60.save();
823: document60 = repository.getDocument(document60.getId(), true);
824: assertEquals(2, document60.getLastVersionId());
825:
826: document60.setPartFileName(partType2.getName(), null);
827: document60.save();
828: document60 = repository.getDocument(document60.getId(), true);
829: assertNull(document60.getPart(partType2.getId()).getFileName());
830: assertEquals(3, document60.getLastVersionId());
831:
832: document60.setPartMimeType(partType2.getName(),
833: "application/octet-stream");
834: document60.save();
835: document60 = repository.getDocument(document60.getId(), true);
836: assertEquals("application/octet-stream", document60.getPart(
837: partType2.getId()).getMimeType());
838: assertEquals(4, document60.getLastVersionId());
839:
840: //
841: // Test link query selection list
842: // tested here instead of in the SchemaTest since it is more meaningful if documents exist
843: //
844: FieldType myLinkField = schema.createFieldType("myLinkField",
845: ValueType.LINK);
846: myLinkField.createLinkQuerySelectionList("true", false);
847: List<? extends ListItem> linkFieldListItems = myLinkField
848: .getSelectionList().getItems();
849: assertTrue(linkFieldListItems.size() > 0);
850: assertNotNull(linkFieldListItems.get(0).getValue());
851: assertNotNull(linkFieldListItems.get(0).getLabel(Locale.US));
852:
853: // Test query selection list
854: stringField1 = schema.getFieldTypeByName("StringField1", true);
855: stringField1.createQuerySelectionList(
856: "select $StringField1 where $StringField1 is not null",
857: false, SortOrder.ASCENDING);
858: stringField1.save();
859: List<? extends ListItem> queryListItems = stringField1
860: .getSelectionList().getItems();
861: assertTrue(queryListItems.size() > 0);
862:
863: //
864: // Test creation of documents in foreign namespace
865: //
866: adminRepository.getNamespaceManager().registerNamespace("FOO");
867:
868: Document nsDoc = repository.createDocument(
869: "Foreign namespace test", documentType2.getId());
870: nsDoc.setRequestedId("1-FOO");
871: nsDoc.save();
872: assertEquals("1-FOO", nsDoc.getId());
873: assertNull(nsDoc.getRequestedId());
874:
875: nsDoc = repository.createDocument("Foreign namespace test",
876: documentType2.getId());
877: try {
878: nsDoc.setRequestedId("1-XYZ");
879: fail("Setting a document ID with a non-existing namespace should fail.");
880: } catch (InvalidDocumentIdException e) {
881: }
882: try {
883: nsDoc.setRequestedId("1-DSYTEST");
884: fail("Setting a document ID within the current repository's namespace should fail.");
885: } catch (RepositoryRuntimeException e) {
886: }
887: nsDoc.setRequestedId("2-FOO");
888: nsDoc.setRequestedId(null);
889: assertNull(nsDoc.getRequestedId());
890:
891: nsDoc.setRequestedId("2-FOO");
892: nsDoc.save();
893: try {
894: nsDoc.setRequestedId("3-FOO");
895: fail("Setting a document ID on an already-saved document should fail.");
896: } catch (RepositoryRuntimeException e) {
897: }
898:
899: nsDoc = repository.createDocument("Foreign namespace test",
900: documentType2.getId());
901: nsDoc.setRequestedId("1-FOO");
902: try {
903: nsDoc.save();
904: fail("Saving a document twice with the same ID should fail.");
905: } catch (RepositoryException e) {
906: }
907:
908: //
909: // Test the version methods. Not really document related but making a different testcase for this
910: // seems like overkill.
911: //
912: assertNotNull(repository.getClientVersion());
913: assertNotNull(repository.getServerVersion());
914: }
915:
916: public void assertEquals(byte[] data1, byte[] data2) {
917: if (data1.length != data2.length)
918: fail("byte arrays not of equals length");
919:
920: for (int i = 0; i < data1.length; i++) {
921: if (data1[i] != data2[i])
922: fail("byte arrays not equal, detected difference at byte "
923: + i);
924: }
925: }
926:
927: private Date getDate(Date date) {
928: Calendar calendar = new GregorianCalendar();
929: calendar.setTime(date);
930: calendar.set(Calendar.HOUR_OF_DAY, 0);
931: calendar.set(Calendar.MINUTE, 0);
932: calendar.set(Calendar.SECOND, 0);
933: calendar.set(Calendar.MILLISECOND, 0);
934: return calendar.getTime();
935: }
936:
937: private Date getDateTime(Date date) {
938: Calendar calendar = new GregorianCalendar();
939: calendar.setTime(date);
940: calendar.set(Calendar.MILLISECOND, 0);
941: return calendar.getTime();
942: }
943: }
|