1 17 package org.alfresco.repo.node; 18 19 import java.io.InputStream ; 20 import java.io.Serializable ; 21 import java.util.ArrayList ; 22 import java.util.Collection ; 23 import java.util.Collections ; 24 import java.util.Date ; 25 import java.util.HashMap ; 26 import java.util.List ; 27 import java.util.Map ; 28 import java.util.Set ; 29 30 import junit.framework.TestCase; 31 32 import org.alfresco.error.AlfrescoRuntimeException; 33 import org.alfresco.model.ContentModel; 34 import org.alfresco.repo.content.MimetypeMap; 35 import org.alfresco.repo.dictionary.DictionaryComponent; 36 import org.alfresco.repo.dictionary.DictionaryDAO; 37 import org.alfresco.repo.dictionary.M2Model; 38 import org.alfresco.repo.domain.hibernate.NodeImpl; 39 import org.alfresco.repo.node.db.NodeDaoService; 40 import org.alfresco.repo.policy.JavaBehaviour; 41 import org.alfresco.repo.policy.PolicyComponent; 42 import org.alfresco.repo.security.authentication.AuthenticationComponent; 43 import org.alfresco.repo.transaction.AlfrescoTransactionSupport; 44 import org.alfresco.repo.transaction.TransactionUtil; 45 import org.alfresco.repo.transaction.TransactionUtil.TransactionWork; 46 import org.alfresco.service.cmr.dictionary.ClassDefinition; 47 import org.alfresco.service.cmr.dictionary.DictionaryService; 48 import org.alfresco.service.cmr.dictionary.InvalidAspectException; 49 import org.alfresco.service.cmr.dictionary.PropertyDefinition; 50 import org.alfresco.service.cmr.repository.AssociationExistsException; 51 import org.alfresco.service.cmr.repository.AssociationRef; 52 import org.alfresco.service.cmr.repository.ChildAssociationRef; 53 import org.alfresco.service.cmr.repository.ContentData; 54 import org.alfresco.service.cmr.repository.CyclicChildRelationshipException; 55 import org.alfresco.service.cmr.repository.InvalidNodeRefException; 56 import org.alfresco.service.cmr.repository.NodeRef; 57 import org.alfresco.service.cmr.repository.NodeService; 58 import org.alfresco.service.cmr.repository.Path; 59 import org.alfresco.service.cmr.repository.StoreRef; 60 import org.alfresco.service.namespace.NamespaceService; 61 import org.alfresco.service.namespace.QName; 62 import org.alfresco.service.namespace.RegexQNamePattern; 63 import org.alfresco.service.transaction.TransactionService; 64 import org.alfresco.util.BaseSpringTest; 65 import org.alfresco.util.GUID; 66 import org.hibernate.Session; 67 import org.springframework.context.ApplicationContext; 68 69 82 public abstract class BaseNodeServiceTest extends BaseSpringTest 83 { 84 public static final String NAMESPACE = "http://www.alfresco.org/test/BaseNodeServiceTest"; 85 public static final String TEST_PREFIX = "test"; 86 public static final QName TYPE_QNAME_TEST_CONTENT = QName.createQName(NAMESPACE, "content"); 87 public static final QName ASPECT_QNAME_TEST_TITLED = QName.createQName(NAMESPACE, "titled"); 88 public static final QName ASPECT_QNAME_TEST_MARKER = QName.createQName(NAMESPACE, "marker"); 89 public static final QName ASPECT_QNAME_TEST_MARKER2 = QName.createQName(NAMESPACE, "marker2"); 90 public static final QName ASPECT_QNAME_MANDATORY = QName.createQName(NAMESPACE, "mandatoryaspect"); 91 public static final QName PROP_QNAME_TEST_TITLE = QName.createQName(NAMESPACE, "title"); 92 public static final QName PROP_QNAME_TEST_CONTENT = QName.createQName(NAMESPACE, "content"); 93 public static final QName ASSOC_TYPE_QNAME_TEST_CHILDREN = ContentModel.ASSOC_CHILDREN; 94 public static final QName ASSOC_TYPE_QNAME_TEST_NEXT = QName.createQName(NAMESPACE, "next"); 95 public static final QName TYPE_QNAME_TEST_MANY_PROPERTIES = QName.createQName(NAMESPACE, "many-properties"); 96 public static final QName PROP_QNAME_BOOLEAN_VALUE = QName.createQName(NAMESPACE, "booleanValue"); 97 public static final QName PROP_QNAME_INTEGER_VALUE = QName.createQName(NAMESPACE, "integerValue"); 98 public static final QName PROP_QNAME_LONG_VALUE = QName.createQName(NAMESPACE, "longValue"); 99 public static final QName PROP_QNAME_FLOAT_VALUE = QName.createQName(NAMESPACE, "floatValue"); 100 public static final QName PROP_QNAME_DOUBLE_VALUE = QName.createQName(NAMESPACE, "doubleValue"); 101 public static final QName PROP_QNAME_STRING_VALUE = QName.createQName(NAMESPACE, "stringValue"); 102 public static final QName PROP_QNAME_DATE_VALUE = QName.createQName(NAMESPACE, "dateValue"); 103 public static final QName PROP_QNAME_SERIALIZABLE_VALUE = QName.createQName(NAMESPACE, "serializableValue"); 104 public static final QName PROP_QNAME_NODEREF_VALUE = QName.createQName(NAMESPACE, "nodeRefValue"); 105 public static final QName PROP_QNAME_QNAME_VALUE = QName.createQName(NAMESPACE, "qnameValue"); 106 public static final QName PROP_QNAME_CONTENT_VALUE = QName.createQName(NAMESPACE, "contentValue"); 107 public static final QName PROP_QNAME_PATH_VALUE = QName.createQName(NAMESPACE, "pathValue"); 108 public static final QName PROP_QNAME_CATEGORY_VALUE = QName.createQName(NAMESPACE, "categoryValue"); 109 public static final QName PROP_QNAME_NULL_VALUE = QName.createQName(NAMESPACE, "nullValue"); 110 public static final QName PROP_QNAME_MULTI_VALUE = QName.createQName(NAMESPACE, "multiValue"); 111 public static final QName TYPE_QNAME_EXTENDED_CONTENT = QName.createQName(NAMESPACE, "extendedcontent"); 112 public static final QName PROP_QNAME_PROP1 = QName.createQName(NAMESPACE, "prop1"); 113 public static final QName ASPECT_QNAME_WITH_DEFAULT_VALUE = QName.createQName(NAMESPACE, "withDefaultValue"); 114 public static final QName PROP_QNAME_PROP2 = QName.createQName(NAMESPACE, "prop2"); 115 116 protected PolicyComponent policyComponent; 117 protected DictionaryService dictionaryService; 118 protected TransactionService transactionService; 119 protected AuthenticationComponent authenticationComponent; 120 protected NodeDaoService nodeDaoService; 121 protected NodeService nodeService; 122 123 protected NodeRef rootNodeRef; 124 125 @Override 126 protected void onSetUpInTransaction() throws Exception 127 { 128 super.onSetUpInTransaction(); 129 transactionService = (TransactionService) applicationContext.getBean("transactionComponent"); 130 policyComponent = (PolicyComponent) applicationContext.getBean("policyComponent"); 131 authenticationComponent = (AuthenticationComponent) applicationContext.getBean("authenticationComponent"); 132 133 authenticationComponent.setSystemUserAsCurrentUser(); 134 135 DictionaryDAO dictionaryDao = (DictionaryDAO) applicationContext.getBean("dictionaryDAO"); 136 ClassLoader cl = BaseNodeServiceTest.class.getClassLoader(); 138 InputStream modelStream = cl.getResourceAsStream("alfresco/model/contentModel.xml"); 139 assertNotNull(modelStream); 140 M2Model model = M2Model.createModel(modelStream); 141 dictionaryDao.putModel(model); 142 modelStream = cl.getResourceAsStream("org/alfresco/repo/node/BaseNodeServiceTest_model.xml"); 144 assertNotNull(modelStream); 145 model = M2Model.createModel(modelStream); 146 dictionaryDao.putModel(model); 147 148 DictionaryComponent dictionary = new DictionaryComponent(); 149 dictionary.setDictionaryDAO(dictionaryDao); 150 dictionaryService = loadModel(applicationContext); 151 152 nodeService = getNodeService(); 153 154 StoreRef storeRef = nodeService.createStore( 156 StoreRef.PROTOCOL_WORKSPACE, 157 "Test_" + System.nanoTime()); 158 rootNodeRef = nodeService.getRootNode(storeRef); 159 } 160 161 @Override 162 protected void onTearDownInTransaction() throws Exception 163 { 164 try 165 { 166 authenticationComponent.clearCurrentSecurityContext(); 167 } 168 catch (Throwable e) 169 { 170 } 172 super.onTearDownInTransaction(); 173 } 174 175 176 177 180 public static DictionaryService loadModel(ApplicationContext applicationContext) 181 { 182 DictionaryDAO dictionaryDao = (DictionaryDAO) applicationContext.getBean("dictionaryDAO"); 183 ClassLoader cl = BaseNodeServiceTest.class.getClassLoader(); 185 InputStream modelStream = cl.getResourceAsStream("alfresco/model/contentModel.xml"); 186 assertNotNull(modelStream); 187 M2Model model = M2Model.createModel(modelStream); 188 dictionaryDao.putModel(model); 189 modelStream = cl.getResourceAsStream("org/alfresco/repo/node/BaseNodeServiceTest_model.xml"); 191 assertNotNull(modelStream); 192 model = M2Model.createModel(modelStream); 193 dictionaryDao.putModel(model); 194 195 DictionaryComponent dictionary = new DictionaryComponent(); 196 dictionary.setDictionaryDAO(dictionaryDao); 197 return dictionary; 199 } 200 201 212 protected abstract NodeService getNodeService(); 213 214 public void testSetUp() throws Exception 215 { 216 assertNotNull("StoreService not set", nodeService); 217 assertNotNull("NodeService not set", nodeService); 218 assertNotNull("rootNodeRef not created", rootNodeRef); 219 } 220 221 224 public Map <QName, ChildAssociationRef> buildNodeGraph() throws Exception 225 { 226 return BaseNodeServiceTest.buildNodeGraph(nodeService, rootNodeRef); 227 } 228 229 265 public static Map <QName, ChildAssociationRef> buildNodeGraph( 266 NodeService nodeService, 267 NodeRef rootNodeRef) throws Exception 268 { 269 String ns = BaseNodeServiceTest.NAMESPACE; 270 QName qname = null; 271 ChildAssociationRef assoc = null; 272 Map <QName, Serializable > properties = new HashMap <QName, Serializable >(); 273 Map <QName, ChildAssociationRef> ret = new HashMap <QName, ChildAssociationRef>(13); 274 275 277 qname = QName.createQName(ns, "root_p_n1"); 279 assoc = nodeService.createNode(rootNodeRef, ASSOC_TYPE_QNAME_TEST_CHILDREN, qname, ContentModel.TYPE_CONTAINER); 280 ret.put(qname, assoc); 281 NodeRef n1 = assoc.getChildRef(); 282 283 qname = QName.createQName(ns, "root_p_n2"); 284 assoc = nodeService.createNode(rootNodeRef, ASSOC_TYPE_QNAME_TEST_CHILDREN, qname, ContentModel.TYPE_CONTAINER); 285 ret.put(qname, assoc); 286 NodeRef n2 = assoc.getChildRef(); 287 288 290 properties.clear(); 291 properties.put(QName.createQName(ns, "animal"), "monkey"); 292 properties.put(QName.createQName(ns, "UPPERANIMAL"), "MONKEY"); 293 properties.put(QName.createQName(ns, "reference"), n2.toString()); 294 properties.put(QName.createQName(ns, "text1"), "bun"); 295 properties.put(QName.createQName(ns, "text2"), "cake"); 296 properties.put(QName.createQName(ns, "text3"), "biscuit"); 297 properties.put(QName.createQName(ns, "text12"), "bun, cake"); 298 properties.put(QName.createQName(ns, "text13"), "bun, biscuit"); 299 properties.put(QName.createQName(ns, "text23"), "cake, biscuit"); 300 properties.put(QName.createQName(ns, "text123"), "bun, cake, biscuit"); 301 ArrayList <String > slist = new ArrayList <String >(); 302 slist.add("first"); 303 slist.add("second"); 304 slist.add("third"); 305 306 properties.put(QName.createQName(ns, "mvp"), slist); 307 308 ArrayList <Integer > ilist = new ArrayList <Integer >(); 309 ilist.add(new Integer (1)); 310 ilist.add(new Integer (2)); 311 ilist.add(new Integer (3)); 312 313 properties.put(QName.createQName(ns, "mvi"), ilist); 314 315 qname = QName.createQName(ns, "n1_p_n3"); 316 assoc = nodeService.createNode(n1, ASSOC_TYPE_QNAME_TEST_CHILDREN, qname, ContentModel.TYPE_CONTAINER, properties); 317 ret.put(qname, assoc); 318 NodeRef n3 = assoc.getChildRef(); 319 320 qname = QName.createQName(ns, "n2_p_n4"); 321 assoc = nodeService.createNode(n2, ASSOC_TYPE_QNAME_TEST_CHILDREN, qname, ContentModel.TYPE_CONTAINER); 322 ret.put(qname, assoc); 323 NodeRef n4 = assoc.getChildRef(); 324 325 qname = QName.createQName(ns, "n1_n4"); 326 assoc = nodeService.addChild(n1, n4, ASSOC_TYPE_QNAME_TEST_CHILDREN, qname); 327 ret.put(qname, assoc); 328 329 qname = QName.createQName(ns, "n2_p_n5"); 330 assoc = nodeService.createNode(n2, ASSOC_TYPE_QNAME_TEST_CHILDREN, qname, ContentModel.TYPE_CONTAINER); 331 ret.put(qname, assoc); 332 NodeRef n5 = assoc.getChildRef(); 333 334 qname = QName.createQName(ns, "n3_p_n6"); 336 assoc = nodeService.createNode(n3, ASSOC_TYPE_QNAME_TEST_CHILDREN, qname, ContentModel.TYPE_CONTAINER); 337 ret.put(qname, assoc); 338 NodeRef n6 = assoc.getChildRef(); 339 nodeService.addAspect(n6, 340 ContentModel.ASPECT_ROOT, 341 Collections.<QName, Serializable >emptyMap()); 342 343 qname = QName.createQName(ns, "n4_n6"); 344 assoc = nodeService.addChild(n4, n6, ASSOC_TYPE_QNAME_TEST_CHILDREN, qname); 345 ret.put(qname, assoc); 346 347 qname = QName.createQName(ns, "n5_p_n7"); 348 assoc = nodeService.createNode(n5, ASSOC_TYPE_QNAME_TEST_CHILDREN, qname, ContentModel.TYPE_CONTAINER); 349 ret.put(qname, assoc); 350 NodeRef n7 = assoc.getChildRef(); 351 352 properties.clear(); 354 properties.put(PROP_QNAME_TEST_CONTENT, new ContentData(null, MimetypeMap.MIMETYPE_TEXT_PLAIN, 0L, null)); 355 properties.put(PROP_QNAME_TEST_TITLE, "node8"); 356 qname = QName.createQName(ns, "n6_p_n8"); 357 assoc = nodeService.createNode(n6, ASSOC_TYPE_QNAME_TEST_CHILDREN, qname, TYPE_QNAME_TEST_CONTENT, properties); 358 ret.put(qname, assoc); 359 NodeRef n8 = assoc.getChildRef(); 360 361 qname = QName.createQName(ns, "n7_n8"); 362 assoc = nodeService.addChild(n7, n8, ASSOC_TYPE_QNAME_TEST_CHILDREN, qname); 363 ret.put(qname, assoc); 364 365 369 return ret; 371 } 372 373 private int countNodesById(NodeRef nodeRef) 374 { 375 String query = 376 "select count(node.key.guid)" + 377 " from " + 378 NodeImpl.class.getName() + " node" + 379 " where node.key.guid = ?"; 380 Session session = getSession(); 381 List results = session.createQuery(query) 382 .setString(0, nodeRef.getId()) 383 .list(); 384 Integer count = (Integer ) results.get(0); 385 return count.intValue(); 386 } 387 388 391 private StoreRef createStore() throws Exception 392 { 393 StoreRef storeRef = nodeService.createStore( 394 StoreRef.PROTOCOL_WORKSPACE, 395 getName() + "_" + System.nanoTime()); 396 assertNotNull("No reference returned", storeRef); 397 return storeRef; 399 } 400 401 public void testCreateStore() throws Exception 402 { 403 StoreRef storeRef = createStore(); 404 405 assertTrue("NodeService reports that store doesn't exist", nodeService.exists(storeRef)); 407 408 NodeRef storeRootNode = nodeService.getRootNode(storeRef); 410 boolean isRoot = nodeService.hasAspect(storeRootNode, ContentModel.ASPECT_ROOT); 412 assertTrue("Root node of store does not have root aspect", isRoot); 413 QName rootType = nodeService.getType(storeRootNode); 415 assertEquals("Store root node of incorrect type", ContentModel.TYPE_STOREROOT, rootType); 416 } 417 418 public void testGetStores() throws Exception 419 { 420 StoreRef storeRef = createStore(); 421 422 List <StoreRef> storeRefs = nodeService.getStores(); 424 425 assertTrue("New store not present is list of stores", storeRefs.contains(storeRef)); 427 } 428 429 public void testExists() throws Exception 430 { 431 StoreRef storeRef = createStore(); 432 boolean exists = nodeService.exists(storeRef); 433 assertEquals("Exists failed", true, exists); 434 StoreRef bogusRef = new StoreRef("What", "the"); 436 exists = nodeService.exists(bogusRef); 437 assertEquals("Exists failed", false, exists); 438 } 439 440 public void testGetRootNode() throws Exception 441 { 442 StoreRef storeRef = createStore(); 443 NodeRef rootNodeRef = nodeService.getRootNode(storeRef); 445 assertNotNull("No root node reference returned", rootNodeRef); 446 NodeRef rootNodeRefCheck = nodeService.getRootNode(storeRef); 448 assertEquals("Root nodes returned different refs", rootNodeRef, rootNodeRefCheck); 449 } 450 451 public void testCreateNode() throws Exception 452 { 453 ChildAssociationRef assocRef = nodeService.createNode(rootNodeRef, 454 ASSOC_TYPE_QNAME_TEST_CHILDREN, 455 QName.createQName("pathA"), 456 ContentModel.TYPE_CONTAINER); 457 assertEquals("Assoc type qname not set", ASSOC_TYPE_QNAME_TEST_CHILDREN, assocRef.getTypeQName()); 458 assertEquals("Assoc qname not set", QName.createQName("pathA"), assocRef.getQName()); 459 NodeRef childRef = assocRef.getChildRef(); 460 QName checkType = nodeService.getType(childRef); 461 assertEquals("Child node type incorrect", ContentModel.TYPE_CONTAINER, checkType); 462 } 463 464 467 public void testCreateNodeWithId() throws Exception 468 { 469 String uuid = GUID.generate(); 470 Map <QName, Serializable > properties = new HashMap <QName, Serializable >(5); 472 properties.put(ContentModel.PROP_NODE_UUID, uuid); 473 ChildAssociationRef assocRef = nodeService.createNode( 474 rootNodeRef, 475 ASSOC_TYPE_QNAME_TEST_CHILDREN, 476 QName.createQName("pathA"), 477 ContentModel.TYPE_CONTAINER, 478 properties); 479 NodeRef expectedNodeRef = new NodeRef(rootNodeRef.getStoreRef(), uuid); 481 NodeRef checkNodeRef = assocRef.getChildRef(); 482 assertEquals("Failed to create node with a chosen ID", expectedNodeRef, checkNodeRef); 483 } 484 485 public void testGetType() throws Exception 486 { 487 ChildAssociationRef assocRef = nodeService.createNode( 488 rootNodeRef, 489 ASSOC_TYPE_QNAME_TEST_CHILDREN, 490 QName.createQName("pathA"), 491 ContentModel.TYPE_CONTAINER); 492 NodeRef nodeRef = assocRef.getChildRef(); 493 QName type = nodeService.getType(nodeRef); 495 assertEquals("Type mismatch", ContentModel.TYPE_CONTAINER, type); 496 } 497 498 public void testSetType() throws Exception 499 { 500 NodeRef nodeRef = nodeService.createNode( 501 rootNodeRef, 502 ASSOC_TYPE_QNAME_TEST_CHILDREN, 503 QName.createQName("setTypeTest"), 504 TYPE_QNAME_TEST_CONTENT).getChildRef(); 505 assertEquals(TYPE_QNAME_TEST_CONTENT, this.nodeService.getType(nodeRef)); 506 507 this.nodeService.setType(nodeRef, TYPE_QNAME_EXTENDED_CONTENT); 509 assertEquals(TYPE_QNAME_EXTENDED_CONTENT, this.nodeService.getType(nodeRef)); 510 } 511 512 515 protected void fillProperties(QName qname, Map <QName, Serializable > properties) 516 { 517 ClassDefinition classDef = dictionaryService.getClass(qname); 518 if (classDef == null) 519 { 520 throw new RuntimeException ("No such class: " + qname); 521 } 522 Map <QName,PropertyDefinition> propertyDefs = classDef.getProperties(); 523 for (QName propertyName : propertyDefs.keySet()) 525 { 526 Serializable value = new Long (System.currentTimeMillis()); 527 properties.put(propertyName, value); 529 } 530 } 531 532 536 public void testAspects() throws Exception 537 { 538 ChildAssociationRef assocRef = nodeService.createNode( 540 rootNodeRef, 541 ASSOC_TYPE_QNAME_TEST_CHILDREN, 542 QName.createQName(BaseNodeServiceTest.NAMESPACE, "test-container"), 543 ContentModel.TYPE_CONTAINER); 544 NodeRef nodeRef = assocRef.getChildRef(); 545 Map <QName, Serializable > properties = new HashMap <QName, Serializable >(20); 547 nodeService.addAspect(nodeRef, BaseNodeServiceTest.ASPECT_QNAME_TEST_TITLED, properties); 548 549 fillProperties(BaseNodeServiceTest.ASPECT_QNAME_TEST_TITLED, properties); 551 Map <QName, Serializable > propertiesBefore = nodeService.getProperties(nodeRef); 553 nodeService.addAspect(nodeRef, BaseNodeServiceTest.ASPECT_QNAME_TEST_TITLED, properties); 555 Map <QName, Serializable > propertiesAfter = nodeService.getProperties(nodeRef); 557 assertEquals("Aspect properties not added", 558 propertiesBefore.size() + 2, 559 propertiesAfter.size()); 560 561 Set <QName> aspects = nodeService.getAspects(nodeRef); 563 assertTrue("Titled aspect not present", 564 aspects.contains(BaseNodeServiceTest.ASPECT_QNAME_TEST_TITLED)); 565 566 boolean hasAspect = nodeService.hasAspect(nodeRef, BaseNodeServiceTest.ASPECT_QNAME_TEST_TITLED); 568 assertTrue("Aspect not confirmed to be on node", hasAspect); 569 570 nodeService.removeAspect(nodeRef, BaseNodeServiceTest.ASPECT_QNAME_TEST_TITLED); 572 hasAspect = nodeService.hasAspect(nodeRef, BaseNodeServiceTest.ASPECT_QNAME_TEST_TITLED); 573 assertFalse("Aspect not removed from node", hasAspect); 574 575 propertiesAfter = nodeService.getProperties(nodeRef); 577 assertEquals("Aspect properties not removed", 578 propertiesBefore.size(), 579 propertiesAfter.size()); 580 } 581 582 public void testCreateNodeNoProperties() throws Exception 583 { 584 ChildAssociationRef assocRef = nodeService.createNode(rootNodeRef, 586 ASSOC_TYPE_QNAME_TEST_CHILDREN, 587 QName.createQName("path1"), 588 ContentModel.TYPE_CONTAINER); 589 NodeRef nodeRef = assocRef.getChildRef(); 590 int count = countNodesById(nodeRef); 592 assertEquals("Unexpected number of nodes present", 1, count); 593 } 594 595 598 public void testCreateNodeWithProperties() throws Exception 599 { 600 Map <QName, Serializable > properties = new HashMap <QName, Serializable >(5); 601 fillProperties(TYPE_QNAME_TEST_CONTENT, properties); 603 fillProperties(ASPECT_QNAME_TEST_TITLED, properties); 604 605 ChildAssociationRef assocRef = nodeService.createNode( 607 rootNodeRef, 608 ASSOC_TYPE_QNAME_TEST_CHILDREN, 609 QName.createQName("MyContent"), 610 TYPE_QNAME_TEST_CONTENT, 611 properties); 612 NodeRef nodeRef = assocRef.getChildRef(); 613 assertTrue("Titled aspect not present", 615 nodeService.hasAspect(nodeRef, ASPECT_QNAME_TEST_TITLED)); 616 617 try 619 { 620 nodeService.removeAspect(nodeRef, ASPECT_QNAME_TEST_TITLED); 621 fail("Failed to prevent removal of type-required aspect"); 622 } 623 catch (InvalidAspectException e) 624 { 625 } 627 } 628 629 public static class BadOnDeleteNodePolicy implements 630 NodeServicePolicies.OnDeleteNodePolicy, 631 NodeServicePolicies.BeforeDeleteNodePolicy 632 { 633 private NodeService nodeService; 634 private List <NodeRef> deletedNodeRefs; 635 636 public BadOnDeleteNodePolicy(NodeService nodeService, List <NodeRef> deletedNodeRefs) 637 { 638 this.nodeService = nodeService; 639 this.deletedNodeRefs = deletedNodeRefs; 640 } 641 642 public void beforeDeleteNode(NodeRef nodeRef) 643 { 644 ChildAssociationRef assocRef = nodeService.createNode( 646 nodeRef, 647 ASSOC_TYPE_QNAME_TEST_CHILDREN, 648 QName.createQName("pre-delete new child"), 649 ContentModel.TYPE_CONTAINER); 650 nodeService.setProperty(nodeRef, PROP_QNAME_BOOLEAN_VALUE, "true"); 652 nodeService.addAspect(nodeRef, ASPECT_QNAME_TEST_TITLED, null); 654 } 655 656 public void onDeleteNode(ChildAssociationRef childAssocRef) 657 { 658 deletedNodeRefs.add(childAssocRef.getChildRef()); 660 NodeRef parentRef = childAssocRef.getParentRef(); 662 NodeRef childRef = childAssocRef.getChildRef(); 663 ChildAssociationRef assocRef = nodeService.createNode( 664 parentRef, 665 ASSOC_TYPE_QNAME_TEST_CHILDREN, 666 QName.createQName("post-delete new child"), 667 ContentModel.TYPE_CONTAINER); 668 } 669 670 } 671 672 public void testDelete() throws Exception 673 { 674 final List <NodeRef> deletedNodeRefs = new ArrayList <NodeRef>(5); 675 676 NodeServicePolicies.OnDeleteNodePolicy policy = new BadOnDeleteNodePolicy(nodeService, deletedNodeRefs); 677 policyComponent.bindClassBehaviour( 679 QName.createQName(NamespaceService.ALFRESCO_URI, "onDeleteNode"), 680 policy, 681 new JavaBehaviour(policy, "onDeleteNode")); 682 683 Map <QName, ChildAssociationRef> assocRefs = buildNodeGraph(nodeService, rootNodeRef); 685 NodeRef n1Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "root_p_n1")).getChildRef(); 686 NodeRef n3Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n1_p_n3")).getChildRef(); 687 NodeRef n4Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n2_p_n4")).getChildRef(); 688 NodeRef n6Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n3_p_n6")).getChildRef(); 689 NodeRef n8Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n6_p_n8")).getChildRef(); 690 691 nodeService.deleteNode(n1Ref); 693 assertEquals("Node not directly deleted", 0, countNodesById(n1Ref)); 694 assertEquals("Node not cascade deleted", 0, countNodesById(n3Ref)); 695 assertEquals("Node incorrectly cascade deleted", 1, countNodesById(n4Ref)); 696 assertEquals("Node not cascade deleted", 0, countNodesById(n6Ref)); 697 assertEquals("Node not cascade deleted", 0, countNodesById(n8Ref)); 698 699 setComplete(); 701 endTransaction(); 702 } 703 704 private int countChildrenOfNode(NodeRef nodeRef) 705 { 706 String query = 707 "select node.childAssocs" + 708 " from " + 709 NodeImpl.class.getName() + " node" + 710 " where node.key.guid = ?"; 711 Session session = getSession(); 712 List results = session.createQuery(query) 713 .setString(0, nodeRef.getId()) 714 .list(); 715 int count = results.size(); 716 return count; 717 } 718 719 public void testAddBogusChild() throws Exception 720 { 721 NodeRef bogusChildRef = new NodeRef(rootNodeRef.getStoreRef(), "BOGUS"); 723 try 724 { 725 nodeService.addChild(rootNodeRef, bogusChildRef, ASSOC_TYPE_QNAME_TEST_CHILDREN, QName.createQName("BOGUS_PATH")); 726 fail("Failed to detect invalid child node reference"); 727 } 728 catch (InvalidNodeRefException e) 729 { 730 } 732 } 733 734 public void testAddChild() throws Exception 735 { 736 NodeRef childNodeRef = nodeService.createNode( 737 rootNodeRef, 738 ASSOC_TYPE_QNAME_TEST_CHILDREN, 739 QName.createQName("pathA"), 740 ContentModel.TYPE_CONTAINER).getChildRef(); 741 int countBefore = countChildrenOfNode(rootNodeRef); 742 assertEquals("Root children count incorrect", 1, countBefore); 743 nodeService.addChild( 745 rootNodeRef, 746 childNodeRef, 747 ASSOC_TYPE_QNAME_TEST_CHILDREN, 748 QName.createQName("pathB")); 749 int countAfter = countChildrenOfNode(rootNodeRef); 751 assertEquals("Root children count incorrect", 2, countAfter); 752 753 try 755 { 756 nodeService.addChild( 757 childNodeRef, 758 rootNodeRef, 759 ASSOC_TYPE_QNAME_TEST_CHILDREN, 760 QName.createQName("backToRoot")); 761 fail("Failed to detect cyclic child relationship during addition of child"); 762 } 763 catch (CyclicChildRelationshipException e) 764 { 765 } 767 } 768 769 public void testRemoveChildByRef() throws Exception 770 { 771 NodeRef parentRef = nodeService.createNode( 772 rootNodeRef, 773 ASSOC_TYPE_QNAME_TEST_CHILDREN, 774 QName.createQName("parent_child"), 775 ContentModel.TYPE_CONTAINER).getChildRef(); 776 ChildAssociationRef pathARef = nodeService.createNode( 777 parentRef, 778 ASSOC_TYPE_QNAME_TEST_CHILDREN, 779 QName.createQName("pathA"), 780 ContentModel.TYPE_CONTAINER); 781 NodeRef childARef = pathARef.getChildRef(); 782 ChildAssociationRef pathBRef = nodeService.addChild( 783 parentRef, childARef, ASSOC_TYPE_QNAME_TEST_CHILDREN, QName.createQName("pathB")); 784 ChildAssociationRef pathCRef = nodeService.addChild( 785 parentRef, childARef, ASSOC_TYPE_QNAME_TEST_CHILDREN, QName.createQName("pathC")); 786 AssociationRef pathDRef = nodeService.createAssociation( 787 parentRef, childARef, ASSOC_TYPE_QNAME_TEST_NEXT); 788 nodeService.removeChild(parentRef, childARef); 790 791 assertFalse("Primary child not deleted", nodeService.exists(childARef)); 792 assertEquals("Child assocs not removed", 793 0, nodeService.getChildAssocs( 794 parentRef, 795 ASSOC_TYPE_QNAME_TEST_CHILDREN, 796 new RegexQNamePattern(".*", "path*")).size()); 797 assertEquals("Node assoc not removed", 798 0, nodeService.getTargetAssocs(parentRef, RegexQNamePattern.MATCH_ALL).size()); 799 } 800 801 public void testAddAndRemoveChild() throws Exception 802 { 803 ChildAssociationRef pathARef = nodeService.createNode( 804 rootNodeRef, 805 ASSOC_TYPE_QNAME_TEST_CHILDREN, 806 QName.createQName("pathA"), 807 ContentModel.TYPE_CONTAINER); 808 NodeRef childRef = pathARef.getChildRef(); 809 nodeService.addChild( 811 rootNodeRef, 812 pathARef.getChildRef(), 813 pathARef.getTypeQName(), 814 pathARef.getQName()); 815 nodeService.removeChild(rootNodeRef, childRef); 817 } 818 819 public enum TestEnum 820 { 821 TEST_ONE, 822 TEST_TWO 823 } 824 825 public void testProperties() throws Exception 826 { 827 ChildAssociationRef assocRef = nodeService.createNode( 829 rootNodeRef, 830 ASSOC_TYPE_QNAME_TEST_CHILDREN, 831 QName.createQName("playThing"), 832 ContentModel.TYPE_CONTAINER); 833 NodeRef nodeRef = assocRef.getChildRef(); 834 835 QName qnameProperty1 = QName.createQName("PROPERTY1"); 836 String valueProperty1 = "VALUE1"; 837 QName qnameProperty2 = QName.createQName("PROPERTY2"); 838 String valueProperty2 = "VALUE2"; 839 QName qnameProperty3 = QName.createQName("PROPERTY3"); 840 QName qnameProperty4 = QName.createQName("PROPERTY4"); 841 842 Map <QName, Serializable > properties = new HashMap <QName, Serializable >(5); 843 properties.put(qnameProperty1, valueProperty1); 844 nodeService.setProperties(nodeRef, properties); 846 nodeService.setProperty(nodeRef, qnameProperty2, valueProperty2); 848 nodeService.setProperty(nodeRef, qnameProperty3, null); 850 nodeService.setProperty(nodeRef, qnameProperty4, TestEnum.TEST_ONE); 852 853 getSession().flush(); 855 getSession().clear(); 856 857 AlfrescoTransactionSupport.flush(); 859 860 Map <QName, Serializable > checkMap = nodeService.getProperties(nodeRef); 862 assertNotNull("Properties were not set/retrieved", checkMap); 863 assertNotNull("Name property not set automatically", checkMap.get(ContentModel.PROP_NAME)); 864 assertEquals("Name property to set to ID of node", nodeRef.getId(), checkMap.get(ContentModel.PROP_NAME)); 865 assertEquals("Property value incorrect", valueProperty1, checkMap.get(qnameProperty1)); 866 assertEquals("Property value incorrect", valueProperty2, checkMap.get(qnameProperty2)); 867 assertTrue("Null property not persisted", checkMap.containsKey(qnameProperty3)); 868 assertNull("Null value not persisted correctly", checkMap.get(qnameProperty3)); 869 assertEquals("Enum property not retrieved", TestEnum.TEST_ONE, checkMap.get(qnameProperty4)); 870 871 Serializable valueCheck = nodeService.getProperty(nodeRef, qnameProperty2); 873 assertNotNull("Property value not set", valueCheck); 874 assertEquals("Property value incorrect", "VALUE2", valueCheck); 875 876 try 878 { 879 nodeService.setProperty(nodeRef, qnameProperty2, null); 880 } 881 catch (IllegalArgumentException e) 882 { 883 fail("Null property values are allowed"); 884 } 885 try 887 { 888 properties = nodeService.getProperties(nodeRef); 889 properties.put(qnameProperty1, null); 890 nodeService.setProperties(nodeRef, properties); 891 } 892 catch (IllegalArgumentException e) 893 { 894 fail("Null property values are allowed in the map"); 895 } 896 } 897 898 902 public void testSerializableProperties() throws Exception 903 { 904 ContentData contentData = new ContentData(null, null, 0L, null); 905 QName qname = PROP_QNAME_CONTENT_VALUE; 906 907 Map <QName, Serializable > properties = new HashMap <QName, Serializable >(17); 908 properties.put(PROP_QNAME_CONTENT_VALUE, contentData); 909 properties.put(PROP_QNAME_SERIALIZABLE_VALUE, qname); 910 NodeRef nodeRef = nodeService.createNode( 912 rootNodeRef, 913 ASSOC_TYPE_QNAME_TEST_CHILDREN, 914 QName.createQName("pathA"), 915 ContentModel.TYPE_CONTAINER, 916 properties).getChildRef(); 917 flushAndClear(); 919 920 Map <QName, Serializable > checkProperties = nodeService.getProperties(nodeRef); 922 Serializable checkPropertyContentData = checkProperties.get(PROP_QNAME_CONTENT_VALUE); 923 Serializable checkPropertyQname = checkProperties.get(PROP_QNAME_SERIALIZABLE_VALUE); 924 assertTrue("Serialization/deserialization of ContentData failed", checkPropertyContentData instanceof ContentData); 925 assertTrue("Serialization/deserialization failed", checkPropertyQname instanceof QName); 926 } 927 928 931 public void testPropertyTypes() throws Exception 932 { 933 ArrayList <String > listProperty = new ArrayList <String >(2); 934 listProperty.add("ABC"); 935 listProperty.add("DEF"); 936 937 Path pathProperty = new Path(); 938 pathProperty.append(new Path.SelfElement()).append(new Path.AttributeElement(TYPE_QNAME_TEST_CONTENT)); 939 940 Map <QName, Serializable > properties = new HashMap <QName, Serializable >(17); 941 properties.put(PROP_QNAME_BOOLEAN_VALUE, true); 942 properties.put(PROP_QNAME_INTEGER_VALUE, 123); 943 properties.put(PROP_QNAME_LONG_VALUE, 123L); 944 properties.put(PROP_QNAME_FLOAT_VALUE, 123.0F); 945 properties.put(PROP_QNAME_DOUBLE_VALUE, 123.0); 946 properties.put(PROP_QNAME_STRING_VALUE, "123.0"); 947 properties.put(PROP_QNAME_DATE_VALUE, new Date ()); 948 properties.put(PROP_QNAME_SERIALIZABLE_VALUE, "456"); 949 properties.put(PROP_QNAME_NODEREF_VALUE, rootNodeRef); 950 properties.put(PROP_QNAME_QNAME_VALUE, TYPE_QNAME_TEST_CONTENT); 951 properties.put(PROP_QNAME_PATH_VALUE, pathProperty); 952 properties.put(PROP_QNAME_CONTENT_VALUE, new ContentData("url", "text/plain", 88L, "UTF-8")); 953 properties.put(PROP_QNAME_CATEGORY_VALUE, rootNodeRef); 954 properties.put(PROP_QNAME_NULL_VALUE, null); 955 properties.put(PROP_QNAME_MULTI_VALUE, listProperty); 956 957 NodeRef nodeRef = nodeService.createNode( 959 rootNodeRef, 960 ASSOC_TYPE_QNAME_TEST_CHILDREN, 961 QName.createQName("pathA"), 962 TYPE_QNAME_TEST_MANY_PROPERTIES, 963 properties).getChildRef(); 964 965 flushAndClear(); 967 968 Map <QName, Serializable > checkProperties = nodeService.getProperties(nodeRef); 970 for (QName qname : properties.keySet()) 972 { 973 Serializable value = properties.get(qname); 974 Serializable checkValue = checkProperties.get(qname); 975 assertEquals("Property mismatch - " + qname, value, checkValue); 976 } 977 978 nodeService.setProperty(nodeRef, PROP_QNAME_MULTI_VALUE, "GHI"); 980 Serializable checkProperty = nodeService.getProperty(nodeRef, PROP_QNAME_MULTI_VALUE); 981 assertTrue("Property not converted to a Collection", checkProperty instanceof Collection ); 982 assertTrue("Collection doesn't contain value", ((Collection )checkProperty).contains("GHI")); 983 } 984 985 989 public void testGetReferencableProperties() throws Exception 990 { 991 Serializable wsProtocol = nodeService.getProperty(rootNodeRef, ContentModel.PROP_STORE_PROTOCOL); 993 Serializable wsIdentifier = nodeService.getProperty(rootNodeRef, ContentModel.PROP_STORE_IDENTIFIER); 994 Serializable nodeUuid = nodeService.getProperty(rootNodeRef, ContentModel.PROP_NODE_UUID); 995 996 assertNotNull("Workspace Protocol property not present", wsProtocol); 997 assertNotNull("Workspace Identifier property not present", wsIdentifier); 998 assertNotNull("Node UUID property not present", nodeUuid); 999 1000 assertEquals("Workspace Protocol property incorrect", rootNodeRef.getStoreRef().getProtocol(), wsProtocol); 1001 assertEquals("Workspace Identifier property incorrect", rootNodeRef.getStoreRef().getIdentifier(), wsIdentifier); 1002 assertEquals("Node UUID property incorrect", rootNodeRef.getId(), nodeUuid); 1003 1004 Map <QName, Serializable > properties = nodeService.getProperties(rootNodeRef); 1006 assertTrue("Workspace Protocol property not present in map", properties.containsKey(ContentModel.PROP_STORE_PROTOCOL)); 1007 assertTrue("Workspace Identifier property not present in map", properties.containsKey(ContentModel.PROP_STORE_IDENTIFIER)); 1008 assertTrue("Node UUID property not present in map", properties.containsKey(ContentModel.PROP_NODE_UUID)); 1009 } 1010 1011 public void testGetParentAssocs() throws Exception 1012 { 1013 Map <QName, ChildAssociationRef> assocRefs = buildNodeGraph(); 1014 ChildAssociationRef n3pn6Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n3_p_n6")); 1015 ChildAssociationRef n5pn7Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n5_p_n7")); 1016 ChildAssociationRef n6pn8Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n6_p_n8")); 1017 ChildAssociationRef n7n8Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n7_n8")); 1018 NodeRef n8Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n6_p_n8")).getChildRef(); 1020 List <ChildAssociationRef> parentAssocs = nodeService.getParentAssocs(n8Ref); 1021 assertEquals("Incorrect number of parents", 2, parentAssocs.size()); 1022 assertTrue("Expected assoc not found", parentAssocs.contains(n6pn8Ref)); 1023 assertTrue("Expected assoc not found", parentAssocs.contains(n7n8Ref)); 1024 1025 ChildAssociationRef primaryParentAssocCheck = nodeService.getPrimaryParent(n8Ref); 1027 assertEquals("Primary parent assoc not retrieved", n6pn8Ref, primaryParentAssocCheck); 1028 1029 ChildAssociationRef rootNodePrimaryAssoc = nodeService.getPrimaryParent(rootNodeRef); 1031 assertNull("Expected null primary parent for root node", rootNodePrimaryAssoc.getParentRef()); 1032 1033 List <ChildAssociationRef> parentAssocRefsByQName = nodeService.getParentAssocs( 1035 n8Ref, 1036 RegexQNamePattern.MATCH_ALL, 1037 QName.createQName(BaseNodeServiceTest.NAMESPACE, "n7_n8")); 1038 assertEquals("Expected to get exactly one match", 1, parentAssocRefsByQName.size()); 1039 1040 List <ChildAssociationRef> childAssocRefsByTypeQName = nodeService.getChildAssocs( 1042 n8Ref, 1043 ASSOC_TYPE_QNAME_TEST_CHILDREN, 1044 RegexQNamePattern.MATCH_ALL); 1045 } 1046 1047 public void testGetChildAssocs() throws Exception 1048 { 1049 Map <QName, ChildAssociationRef> assocRefs = buildNodeGraph(); 1050 NodeRef n1Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE,"root_p_n1")).getChildRef(); 1051 ChildAssociationRef n1pn3Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE,"n1_p_n3")); 1052 ChildAssociationRef n1n4Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE,"n1_n4")); 1053 1054 List <ChildAssociationRef> childAssocRefs = nodeService.getChildAssocs(n1Ref); 1056 assertEquals("Incorrect number of children", 2, childAssocRefs.size()); 1057 assertEquals("First child added to n1 was primary to n3: Order of refs is wrong", 1059 n1pn3Ref, childAssocRefs.get(0)); 1060 assertEquals("Second child added to n1 was to n4: Order of refs is wrong", 1061 n1n4Ref, childAssocRefs.get(1)); 1062 nodeService.setChildAssociationIndex(n1pn3Ref, 1); 1064 nodeService.setChildAssociationIndex(n1n4Ref, 0); 1065 1066 childAssocRefs = nodeService.getChildAssocs(n1Ref); 1068 assertEquals("Order of refs is wrong", n1pn3Ref, childAssocRefs.get(1)); 1069 assertEquals("Order of refs is wrong", n1n4Ref, childAssocRefs.get(0)); 1070 1071 List <ChildAssociationRef> childAssocRefsByQName = nodeService.getChildAssocs( 1073 n1Ref, 1074 RegexQNamePattern.MATCH_ALL, 1075 QName.createQName(BaseNodeServiceTest.NAMESPACE, "n1_p_n3")); 1076 assertEquals("Expected to get exactly one match", 1, childAssocRefsByQName.size()); 1077 1078 List <ChildAssociationRef> childAssocRefsByTypeQName = nodeService.getChildAssocs( 1080 n1Ref, 1081 ASSOC_TYPE_QNAME_TEST_CHILDREN, 1082 RegexQNamePattern.MATCH_ALL); 1083 } 1084 1085 public void testMoveNode() throws Exception 1086 { 1087 Map <QName, ChildAssociationRef> assocRefs = buildNodeGraph(); 1088 ChildAssociationRef n2pn4Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n2_p_n4")); 1089 ChildAssociationRef n5pn7Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n5_p_n7")); 1090 ChildAssociationRef n6pn8Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n6_p_n8")); 1091 NodeRef n4Ref = n2pn4Ref.getChildRef(); 1092 NodeRef n5Ref = n5pn7Ref.getParentRef(); 1093 NodeRef n6Ref = n6pn8Ref.getParentRef(); 1094 NodeRef n8Ref = n6pn8Ref.getChildRef(); 1095 ChildAssociationRef assocRef = nodeService.moveNode( 1097 n8Ref, 1098 n5Ref, 1099 ASSOC_TYPE_QNAME_TEST_CHILDREN, 1100 QName.createQName(BaseNodeServiceTest.NAMESPACE, "n5_p_n8")); 1101 List <ChildAssociationRef> n6ChildRefs = nodeService.getChildAssocs( 1103 n6Ref, 1104 RegexQNamePattern.MATCH_ALL, QName.createQName(BaseNodeServiceTest.NAMESPACE, "n6_p_n8")); 1105 assertEquals("Primary child assoc is still present", 0, n6ChildRefs.size()); 1106 ChildAssociationRef checkRef = nodeService.getPrimaryParent(n8Ref); 1108 assertEquals("Primary assoc incorrent", assocRef, checkRef); 1109 1110 try 1112 { 1113 nodeService.moveNode( 1115 n4Ref, 1116 n6Ref, 1117 ASSOC_TYPE_QNAME_TEST_CHILDREN, 1118 QName.createQName(BaseNodeServiceTest.NAMESPACE, "n6_p_n4")); 1119 fail("Failed to detect cyclic relationship during move"); 1120 } 1121 catch (CyclicChildRelationshipException e) 1122 { 1123 } 1125 } 1126 1127 1132 private AssociationRef createAssociation() throws Exception 1133 { 1134 Map <QName, Serializable > properties = new HashMap <QName, Serializable >(5); 1135 fillProperties(TYPE_QNAME_TEST_CONTENT, properties); 1136 fillProperties(ASPECT_QNAME_TEST_TITLED, properties); 1137 1138 ChildAssociationRef childAssocRef = nodeService.createNode( 1139 rootNodeRef, 1140 ASSOC_TYPE_QNAME_TEST_CHILDREN, 1141 QName.createQName(null, "N1"), 1142 TYPE_QNAME_TEST_CONTENT, 1143 properties); 1144 NodeRef sourceRef = childAssocRef.getChildRef(); 1145 childAssocRef = nodeService.createNode( 1146 rootNodeRef, 1147 ASSOC_TYPE_QNAME_TEST_CHILDREN, 1148 QName.createQName(null, "N2"), 1149 TYPE_QNAME_TEST_CONTENT, 1150 properties); 1151 NodeRef targetRef = childAssocRef.getChildRef(); 1152 1153 AssociationRef assocRef = nodeService.createAssociation( 1154 sourceRef, 1155 targetRef, 1156 ASSOC_TYPE_QNAME_TEST_NEXT); 1157 return assocRef; 1159 } 1160 1161 public void testAssociationToIncorrectNodeType() throws Exception 1162 { 1163 AssociationRef assocRef = createAssociation(); 1164 NodeRef sourceRef = assocRef.getSourceRef(); 1165 NodeRef targetRef = assocRef.getTargetRef(); 1166 QName qname = assocRef.getTypeQName(); 1167 try 1168 { 1169 nodeService.createAssociation(sourceRef, targetRef, qname); 1171 fail("Incorrect node type not detected"); 1172 } 1173 catch (RuntimeException e) 1174 { 1175 } 1177 } 1178 1179 public void testDuplicateAssociationDetection() throws Exception 1180 { 1181 AssociationRef assocRef = createAssociation(); 1182 NodeRef sourceRef = assocRef.getSourceRef(); 1183 NodeRef targetRef = assocRef.getTargetRef(); 1184 QName qname = assocRef.getTypeQName(); 1185 try 1186 { 1187 nodeService.createAssociation(sourceRef, targetRef, qname); 1189 fail("Duplicate assocation not detected"); 1190 } 1191 catch (AssociationExistsException e) 1192 { 1193 } 1195 } 1196 1197 public void testCreateAndRemoveAssociation() throws Exception 1198 { 1199 AssociationRef assocRef = createAssociation(); 1200 NodeRef sourceRef = assocRef.getSourceRef(); 1201 1202 Map <QName, Serializable > properties = new HashMap <QName, Serializable >(5); 1204 fillProperties(TYPE_QNAME_TEST_CONTENT, properties); 1205 fillProperties(ASPECT_QNAME_TEST_TITLED, properties); 1206 ChildAssociationRef childAssocRef = nodeService.createNode( 1207 rootNodeRef, 1208 ASSOC_TYPE_QNAME_TEST_CHILDREN, 1209 QName.createQName(null, "N3"), 1210 TYPE_QNAME_TEST_CONTENT, 1211 properties); 1212 NodeRef anotherTargetRef = childAssocRef.getChildRef(); 1213 AssociationRef anotherAssocRef = nodeService.createAssociation( 1214 sourceRef, 1215 anotherTargetRef, 1216 ASSOC_TYPE_QNAME_TEST_NEXT); 1217 1218 List <AssociationRef> assocs = nodeService.getTargetAssocs(sourceRef, ASSOC_TYPE_QNAME_TEST_NEXT); 1220 for (AssociationRef assoc : assocs) 1221 { 1222 nodeService.removeAssociation( 1223 assoc.getSourceRef(), 1224 assoc.getTargetRef(), 1225 assoc.getTypeQName()); 1226 } 1227 } 1228 1229 public void testGetTargetAssocs() throws Exception 1230 { 1231 AssociationRef assocRef = createAssociation(); 1232 NodeRef sourceRef = assocRef.getSourceRef(); 1233 NodeRef targetRef = assocRef.getTargetRef(); 1234 QName qname = assocRef.getTypeQName(); 1235 List <AssociationRef> targetAssocs = nodeService.getTargetAssocs(sourceRef, qname); 1237 assertEquals("Incorrect number of targets", 1, targetAssocs.size()); 1238 assertTrue("Target not found", targetAssocs.contains(assocRef)); 1239 } 1240 1241 public void testGetSourceAssocs() throws Exception 1242 { 1243 AssociationRef assocRef = createAssociation(); 1244 NodeRef sourceRef = assocRef.getSourceRef(); 1245 NodeRef targetRef = assocRef.getTargetRef(); 1246 QName qname = assocRef.getTypeQName(); 1247 List <AssociationRef> sourceAssocs = nodeService.getSourceAssocs(targetRef, qname); 1249 assertEquals("Incorrect number of source assocs", 1, sourceAssocs.size()); 1250 assertTrue("Source not found", sourceAssocs.contains(assocRef)); 1251 } 1252 1253 1256 public void testGetPath() throws Exception 1257 { 1258 Map <QName, ChildAssociationRef> assocRefs = buildNodeGraph(); 1259 NodeRef n8Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE,"n6_p_n8")).getChildRef(); 1260 1261 Path path = nodeService.getPath(n8Ref); 1263 assertEquals("Primary path incorrect", 1264 "/{" + BaseNodeServiceTest.NAMESPACE + "}root_p_n1/{" + BaseNodeServiceTest.NAMESPACE + "}n1_p_n3/{" + BaseNodeServiceTest.NAMESPACE + "}n3_p_n6/{" + BaseNodeServiceTest.NAMESPACE + "}n6_p_n8", 1265 path.toString()); 1266 } 1267 1268 1271 public void testGetPaths() throws Exception 1272 { 1273 Map <QName, ChildAssociationRef> assocRefs = buildNodeGraph(); 1274 NodeRef n1Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "root_p_n1")).getChildRef(); 1275 NodeRef n6Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n3_p_n6")).getChildRef(); 1276 NodeRef n8Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n6_p_n8")).getChildRef(); 1277 1278 Collection <Path> paths = nodeService.getPaths(rootNodeRef, false); 1280 assertEquals("Root node must have exactly 1 path", 1, paths.size()); 1281 Path rootPath = paths.toArray(new Path[1])[0]; 1282 assertNotNull("Root node path must have 1 element", rootPath.last()); 1283 assertEquals("Root node path must have 1 element", rootPath.first(), rootPath.last()); 1284 1285 paths = nodeService.getPaths(n8Ref, false); 1287 assertEquals("Incorrect path count", 5, paths.size()); for (Path path : paths) 1290 { 1291 for (Path.Element element : path) 1293 { 1294 assertTrue("Path element of incorrect type", element instanceof Path.ChildAssocElement); 1295 Path.ChildAssocElement childAssocElement = (Path.ChildAssocElement) element; 1296 ChildAssociationRef ref = childAssocElement.getRef(); 1297 if (childAssocElement != path.first()) 1298 { 1299 assertNotNull("Parent node ref not set", ref.getParentRef()); 1301 assertNotNull("QName not set", ref.getQName()); 1302 } 1303 assertNotNull("Child node ref not set", ref.getChildRef()); 1305 } 1306 } 1307 1308 paths = nodeService.getPaths(n8Ref, true); 1310 assertEquals("Incorrect path count", 1, paths.size()); 1311 1312 try 1314 { 1315 nodeService.addChild(n6Ref, n1Ref, ASSOC_TYPE_QNAME_TEST_CHILDREN, QName.createQName("n6_n1")); 1316 nodeService.getPaths(n6Ref, false); 1317 fail("Cyclic relationship not detected"); 1318 } 1319 catch (CyclicChildRelationshipException e) 1320 { 1321 } 1323 catch (StackOverflowError e) 1324 { 1325 throw e; 1326 } 1327 } 1328 1329 public void testPrimaryPathCascadeDelete() throws Exception 1330 { 1331 Map <QName, ChildAssociationRef> assocRefs = buildNodeGraph(); 1332 NodeRef n1Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "root_p_n1")).getChildRef(); 1333 NodeRef n6Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n3_p_n6")).getChildRef(); 1334 NodeRef n8Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n6_p_n8")).getChildRef(); 1335 1336 nodeService.deleteNode(n1Ref); 1338 assertFalse("n6 not cascade deleted", nodeService.exists(n6Ref)); 1340 assertFalse("n8 not cascade deleted", nodeService.exists(n8Ref)); 1341 } 1342 1343 1348 public void testDefaultValues() throws Exception 1349 { 1350 NodeRef nodeRef = nodeService.createNode( 1351 rootNodeRef, 1352 ASSOC_TYPE_QNAME_TEST_CHILDREN, 1353 QName.createQName("testDefaultValues"), 1354 TYPE_QNAME_EXTENDED_CONTENT).getChildRef(); 1355 assertEquals("defaultValue", this.nodeService.getProperty(nodeRef, PROP_QNAME_PROP1)); 1356 this.nodeService.addAspect(nodeRef, ASPECT_QNAME_WITH_DEFAULT_VALUE, null); 1357 assertEquals("defaultValue", this.nodeService.getProperty(nodeRef, PROP_QNAME_PROP2)); 1358 1359 Map <QName, Serializable > props = new HashMap <QName, Serializable >(1); 1361 props.put(PROP_QNAME_PROP1, "notDefaultValue"); 1362 NodeRef nodeRef2 = nodeService.createNode( 1363 rootNodeRef, 1364 ASSOC_TYPE_QNAME_TEST_CHILDREN, 1365 QName.createQName("testDefaultValues"), 1366 TYPE_QNAME_EXTENDED_CONTENT, 1367 props).getChildRef(); 1368 assertEquals("notDefaultValue", this.nodeService.getProperty(nodeRef2, PROP_QNAME_PROP1)); 1369 Map <QName, Serializable > prop2 = new HashMap <QName, Serializable >(1); 1370 prop2.put(PROP_QNAME_PROP2, "notDefaultValue"); 1371 this.nodeService.addAspect(nodeRef2, ASPECT_QNAME_WITH_DEFAULT_VALUE, prop2); 1372 assertEquals("notDefaultValue", this.nodeService.getProperty(nodeRef2, PROP_QNAME_PROP2)); 1373 1374 } 1375 1376 public void testMandatoryAspects() 1377 { 1378 NodeRef nodeRef = nodeService.createNode( 1379 rootNodeRef, 1380 ASSOC_TYPE_QNAME_TEST_CHILDREN, 1381 QName.createQName("testDefaultValues"), 1382 TYPE_QNAME_TEST_CONTENT).getChildRef(); 1383 1384 assertTrue(this.nodeService.hasAspect(nodeRef, ASPECT_QNAME_TEST_TITLED)); 1386 assertTrue(this.nodeService.hasAspect(nodeRef, ASPECT_QNAME_MANDATORY)); 1387 1388 this.nodeService.addAspect(nodeRef, ASPECT_QNAME_TEST_MARKER, null); 1390 1391 assertTrue(this.nodeService.hasAspect(nodeRef, ASPECT_QNAME_TEST_MARKER)); 1393 assertTrue(this.nodeService.hasAspect(nodeRef, ASPECT_QNAME_TEST_MARKER2)); 1394 } 1395 1396 private void garbageCollect() throws Exception 1397 { 1398 for (int i = 0; i < 50; i++) 1400 { 1401 Runtime.getRuntime().gc(); 1402 synchronized(this) 1403 { 1404 this.wait(20); 1405 } 1406 } 1407 } 1408 1409 private void reportFlushPerformance( 1410 String msg, 1411 Map <QName, ChildAssociationRef> lastNodeGraph, 1412 int testCount, 1413 long startBytes, 1414 long startTime) throws Exception 1415 { 1416 long endTime = System.nanoTime(); 1417 double deltaTime = (double)(endTime - startTime)/1000000000D; 1418 System.out.println(msg + "\n" + 1419 " Build and flushed " + testCount + " node graphs: \n" + 1420 " total time: " + deltaTime + "s \n" + 1421 " average: " + (double)testCount/deltaTime + " graphs/s"); 1422 1423 garbageCollect(); 1424 long endBytes = Runtime.getRuntime().freeMemory(); 1425 double diffBytes = (double)(startBytes - endBytes); 1426 System.out.println( 1427 " total bytes: " + diffBytes/1024D/1024D + " MB \n" + 1428 " average: " + (double)diffBytes/testCount/1024D + " kb/graph"); 1429 1430 1431 int assocsPerGraph = lastNodeGraph.size(); 1432 int nodesPerGraph = 0; 1433 for (ChildAssociationRef assoc : lastNodeGraph.values()) 1434 { 1435 if (assoc.getQName().toString().contains("_p_")) 1436 { 1437 nodesPerGraph++; 1438 } 1439 } 1440 int totalAssocs = assocsPerGraph * testCount; 1441 int totalNodes = nodesPerGraph * testCount; 1442 System.out.println( 1443 " assocs per graph: " + assocsPerGraph + "\n" + 1444 " nodes per graph: " + nodesPerGraph + "\n" + 1445 " total nodes: " + totalNodes + "\n" + 1446 " total assocs: " + totalAssocs); 1447 } 1448 1449 1457 public void testFlush() throws Exception 1458 { 1459 setComplete(); 1460 endTransaction(); 1461 1462 final int testCount = 500; 1463 1464 garbageCollect(); 1465 1466 final long startBytes = Runtime.getRuntime().freeMemory(); 1467 final long startTime = System.nanoTime(); 1468 1469 TransactionWork<Map <QName, ChildAssociationRef>> buildWork = new TransactionWork<Map <QName, ChildAssociationRef>>() 1470 { 1471 public Map <QName, ChildAssociationRef> doWork() 1472 { 1473 Map <QName, ChildAssociationRef> nodeGraph = Collections.emptyMap(); 1474 try 1475 { 1476 for (int i = 0; i < testCount; i++) 1477 { 1478 nodeGraph = buildNodeGraph(); 1479 AlfrescoTransactionSupport.flush(); 1480 } 1481 1482 reportFlushPerformance("Statistics pre-commit", nodeGraph, testCount, startBytes, startTime); 1484 } 1485 catch (OutOfMemoryError e) 1486 { 1487 fail("Flush not clearing memory"); 1488 } 1489 catch (Exception e) 1490 { 1491 throw new AlfrescoRuntimeException("Node graph building failed", e); 1492 } 1493 return nodeGraph; 1494 } 1495 }; 1496 Map <QName, ChildAssociationRef> nodeGraph = TransactionUtil.executeInNonPropagatingUserTransaction(transactionService, buildWork); 1497 1498 reportFlushPerformance("Statistics post-commit", nodeGraph, testCount, startBytes, startTime); 1500 } 1501} 1502 | Popular Tags |