KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > repo > node > BaseNodeServiceTest


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.repo.node;
18
19 import java.io.InputStream JavaDoc;
20 import java.io.Serializable JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.Collections JavaDoc;
24 import java.util.Date JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.Set JavaDoc;
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 /**
70  * Provides a base set of tests of the various {@link org.alfresco.service.cmr.repository.NodeService}
71  * implementations.
72  * <p>
73  * To test a specific incarnation of the service, the methods {@link #getStoreService()} and
74  * {@link #getNodeService()} must be implemented.
75  *
76  * @see #nodeService
77  * @see #rootNodeRef
78  * @see #buildNodeGraph()
79  *
80  * @author Derek Hulley
81  */

82 public abstract class BaseNodeServiceTest extends BaseSpringTest
83 {
84     public static final String JavaDoc NAMESPACE = "http://www.alfresco.org/test/BaseNodeServiceTest";
85     public static final String JavaDoc 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     /** populated during setup */
123     protected NodeRef rootNodeRef;
124
125     @Override JavaDoc
126     protected void onSetUpInTransaction() throws Exception JavaDoc
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         // load the system model
137
ClassLoader JavaDoc cl = BaseNodeServiceTest.class.getClassLoader();
138         InputStream JavaDoc modelStream = cl.getResourceAsStream("alfresco/model/contentModel.xml");
139         assertNotNull(modelStream);
140         M2Model model = M2Model.createModel(modelStream);
141         dictionaryDao.putModel(model);
142         // load the test model
143
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         // create a first store directly
155
StoreRef storeRef = nodeService.createStore(
156                 StoreRef.PROTOCOL_WORKSPACE,
157                 "Test_" + System.nanoTime());
158         rootNodeRef = nodeService.getRootNode(storeRef);
159     }
160     
161     @Override JavaDoc
162     protected void onTearDownInTransaction() throws Exception JavaDoc
163     {
164         try
165         {
166             authenticationComponent.clearCurrentSecurityContext();
167         }
168         catch (Throwable JavaDoc e)
169         {
170             // do nothing
171
}
172         super.onTearDownInTransaction();
173     }
174
175
176
177     /**
178      * Loads the test model required for building the node graphs
179      */

180     public static DictionaryService loadModel(ApplicationContext applicationContext)
181     {
182         DictionaryDAO dictionaryDao = (DictionaryDAO) applicationContext.getBean("dictionaryDAO");
183         // load the system model
184
ClassLoader JavaDoc cl = BaseNodeServiceTest.class.getClassLoader();
185         InputStream JavaDoc modelStream = cl.getResourceAsStream("alfresco/model/contentModel.xml");
186         assertNotNull(modelStream);
187         M2Model model = M2Model.createModel(modelStream);
188         dictionaryDao.putModel(model);
189         // load the test model
190
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         // done
198
return dictionary;
199     }
200     
201     /**
202      * Usually just implemented by fetching the bean directly from the bean factory,
203      * for example:
204      * <p>
205      * <pre>
206      * return (NodeService) applicationContext.getBean("dbNodeService");
207      * </pre>
208      *
209      * @return Returns the implementation of <code>NodeService</code> to be
210      * used for this test
211      */

212     protected abstract NodeService getNodeService();
213     
214     public void testSetUp() throws Exception JavaDoc
215     {
216         assertNotNull("StoreService not set", nodeService);
217         assertNotNull("NodeService not set", nodeService);
218         assertNotNull("rootNodeRef not created", rootNodeRef);
219     }
220
221     /**
222      * @see #buildNodeGraph(NodeService, NodeRef)
223      */

224     public Map JavaDoc<QName, ChildAssociationRef> buildNodeGraph() throws Exception JavaDoc
225     {
226         return BaseNodeServiceTest.buildNodeGraph(nodeService, rootNodeRef);
227     }
228
229     /**
230      * Builds a graph of child associations as follows:
231      * <pre>
232      * Level 0: root
233      * Level 1: root_p_n1 root_p_n2
234      * Level 2: n1_p_n3 n2_p_n4 n1_n4 n2_p_n5
235      * Level 3: n3_p_n6 n4_n6 n5_p_n7
236      * Level 4: n6_p_n8 n7_n8
237      * </pre>
238      * <p>
239      * <ul>
240      * <li>Apart from the root node having the root aspect, node 6 (<b>n6</b>) also has the
241      * root aspect.</li>
242      * <li><b>n3</b> has properties <code>animal = monkey</code> and
243      * <code>reference = <b>n2</b>.toString()</code>.</li>
244      * <li>All nodes are of type {@link ContentModel#TYPE_CONTAINER container}
245      * with the exception of <b>n8</b>, which is of type {@link #TYPE_QNAME_TEST_CONTENT test:content}</li>
246      * </ul>
247      * <p>
248      * The namespace URI for all associations is <b>{@link BaseNodeServiceTest#NAMESPACE}</b>.
249      * <p>
250      * The naming convention is:
251      * <pre>
252      * n2_p_n5
253      * n4_n5
254      * where
255      * n5 is the node number of the node
256      * n2 is the primary parent node number
257      * n4 is any other non-primary parent
258      * </pre>
259      * <p>
260      * The session is flushed to ensure that persistence occurs correctly. It is
261      * cleared to ensure that fetches against the created data are correct.
262      *
263      * @return Returns a map <code>ChildAssocRef</code> instances keyed by qualified assoc name
264      */

265     public static Map JavaDoc<QName, ChildAssociationRef> buildNodeGraph(
266             NodeService nodeService,
267             NodeRef rootNodeRef) throws Exception JavaDoc
268     {
269         String JavaDoc ns = BaseNodeServiceTest.NAMESPACE;
270         QName qname = null;
271         ChildAssociationRef assoc = null;
272         Map JavaDoc<QName, Serializable JavaDoc> properties = new HashMap JavaDoc<QName, Serializable JavaDoc>();
273         Map JavaDoc<QName, ChildAssociationRef> ret = new HashMap JavaDoc<QName, ChildAssociationRef>(13);
274         
275         // LEVEL 0
276

277         // LEVEL 1
278
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         // LEVEL 2
289

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 JavaDoc<String JavaDoc> slist = new ArrayList JavaDoc<String JavaDoc>();
302         slist.add("first");
303         slist.add("second");
304         slist.add("third");
305        
306         properties.put(QName.createQName(ns, "mvp"), slist);
307         
308         ArrayList JavaDoc<Integer JavaDoc> ilist = new ArrayList JavaDoc<Integer JavaDoc>();
309         ilist.add(new Integer JavaDoc(1));
310         ilist.add(new Integer JavaDoc(2));
311         ilist.add(new Integer JavaDoc(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         // LEVEL 3
335
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 JavaDoc>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         // LEVEL 4
353
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 // // flush and clear
366
// getSession().flush();
367
// getSession().clear();
368

369         // done
370
return ret;
371     }
372     
373     private int countNodesById(NodeRef nodeRef)
374     {
375         String JavaDoc 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 JavaDoc results = session.createQuery(query)
382             .setString(0, nodeRef.getId())
383             .list();
384         Integer JavaDoc count = (Integer JavaDoc) results.get(0);
385         return count.intValue();
386     }
387     
388     /**
389      * @return Returns a reference to the created store
390      */

391     private StoreRef createStore() throws Exception JavaDoc
392     {
393         StoreRef storeRef = nodeService.createStore(
394                 StoreRef.PROTOCOL_WORKSPACE,
395                 getName() + "_" + System.nanoTime());
396         assertNotNull("No reference returned", storeRef);
397         // done
398
return storeRef;
399     }
400     
401     public void testCreateStore() throws Exception JavaDoc
402     {
403         StoreRef storeRef = createStore();
404         
405         // check that it exists
406
assertTrue("NodeService reports that store doesn't exist", nodeService.exists(storeRef));
407         
408         // get the root node
409
NodeRef storeRootNode = nodeService.getRootNode(storeRef);
410         // make sure that it has the root aspect
411
boolean isRoot = nodeService.hasAspect(storeRootNode, ContentModel.ASPECT_ROOT);
412         assertTrue("Root node of store does not have root aspect", isRoot);
413         // and is of the correct type
414
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 JavaDoc
419     {
420         StoreRef storeRef = createStore();
421         
422         // get all stores
423
List JavaDoc<StoreRef> storeRefs = nodeService.getStores();
424         
425         // check that the store ref is present
426
assertTrue("New store not present is list of stores", storeRefs.contains(storeRef));
427     }
428     
429     public void testExists() throws Exception JavaDoc
430     {
431         StoreRef storeRef = createStore();
432         boolean exists = nodeService.exists(storeRef);
433         assertEquals("Exists failed", true, exists);
434         // create bogus ref
435
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 JavaDoc
441     {
442         StoreRef storeRef = createStore();
443         // get the root node
444
NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
445         assertNotNull("No root node reference returned", rootNodeRef);
446         // get the root node again
447
NodeRef rootNodeRefCheck = nodeService.getRootNode(storeRef);
448         assertEquals("Root nodes returned different refs", rootNodeRef, rootNodeRefCheck);
449     }
450     
451     public void testCreateNode() throws Exception JavaDoc
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     /**
465      * Tests node creation with a pre-determined {@link ContentModel#PROP_NODE_UUID uuid}.
466      */

467     public void testCreateNodeWithId() throws Exception JavaDoc
468     {
469         String JavaDoc uuid = GUID.generate();
470         // create a node with an explicit UUID
471
Map JavaDoc<QName, Serializable JavaDoc> properties = new HashMap JavaDoc<QName, Serializable JavaDoc>(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         // check it
480
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 JavaDoc
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         // get the type
494
QName type = nodeService.getType(nodeRef);
495         assertEquals("Type mismatch", ContentModel.TYPE_CONTAINER, type);
496     }
497     
498     public void testSetType() throws Exception JavaDoc
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         // Now change the type
508
this.nodeService.setType(nodeRef, TYPE_QNAME_EXTENDED_CONTENT);
509         assertEquals(TYPE_QNAME_EXTENDED_CONTENT, this.nodeService.getType(nodeRef));
510     }
511     
512     /**
513      * Fills the given property map with some values according to the property definitions on the given class
514      */

515     protected void fillProperties(QName qname, Map JavaDoc<QName, Serializable JavaDoc> properties)
516     {
517         ClassDefinition classDef = dictionaryService.getClass(qname);
518         if (classDef == null)
519         {
520             throw new RuntimeException JavaDoc("No such class: " + qname);
521         }
522         Map JavaDoc<QName,PropertyDefinition> propertyDefs = classDef.getProperties();
523         // make up a property value for each property
524
for (QName propertyName : propertyDefs.keySet())
525         {
526             Serializable JavaDoc value = new Long JavaDoc(System.currentTimeMillis());
527             // add it
528
properties.put(propertyName, value);
529         }
530     }
531     
532     /**
533      * Checks that aspects can be added, removed and queried. Failure to detect
534      * inadequate properties is also checked.
535      */

536     public void testAspects() throws Exception JavaDoc
537     {
538         // create a regular base node
539
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         // add the content aspect to the node, but don't supply any properties
546
Map JavaDoc<QName, Serializable JavaDoc> properties = new HashMap JavaDoc<QName, Serializable JavaDoc>(20);
547         nodeService.addAspect(nodeRef, BaseNodeServiceTest.ASPECT_QNAME_TEST_TITLED, properties);
548
549         // get the properties required for the aspect
550
fillProperties(BaseNodeServiceTest.ASPECT_QNAME_TEST_TITLED, properties);
551         // get the node properties before
552
Map JavaDoc<QName, Serializable JavaDoc> propertiesBefore = nodeService.getProperties(nodeRef);
553         // add the aspect
554
nodeService.addAspect(nodeRef, BaseNodeServiceTest.ASPECT_QNAME_TEST_TITLED, properties);
555         // get the properties after and check
556
Map JavaDoc<QName, Serializable JavaDoc> propertiesAfter = nodeService.getProperties(nodeRef);
557         assertEquals("Aspect properties not added",
558                 propertiesBefore.size() + 2,
559                 propertiesAfter.size());
560         
561         // check that we know that the aspect is present
562
Set JavaDoc<QName> aspects = nodeService.getAspects(nodeRef);
563         assertTrue("Titled aspect not present",
564                 aspects.contains(BaseNodeServiceTest.ASPECT_QNAME_TEST_TITLED));
565         
566         // check that hasAspect works
567
boolean hasAspect = nodeService.hasAspect(nodeRef, BaseNodeServiceTest.ASPECT_QNAME_TEST_TITLED);
568         assertTrue("Aspect not confirmed to be on node", hasAspect);
569         
570         // remove the aspect
571
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         // check that the associated properties were removed
576
propertiesAfter = nodeService.getProperties(nodeRef);
577         assertEquals("Aspect properties not removed",
578                 propertiesBefore.size(),
579                 propertiesAfter.size());
580     }
581     
582     public void testCreateNodeNoProperties() throws Exception JavaDoc
583     {
584         // flush to ensure that the pure JDBC query will work
585
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         // count the nodes with the given id
591
int count = countNodesById(nodeRef);
592         assertEquals("Unexpected number of nodes present", 1, count);
593     }
594     
595     /**
596      * @see #ASPECT_QNAME_TEST_TITLED
597      */

598     public void testCreateNodeWithProperties() throws Exception JavaDoc
599     {
600         Map JavaDoc<QName, Serializable JavaDoc> properties = new HashMap JavaDoc<QName, Serializable JavaDoc>(5);
601         // fill properties
602
fillProperties(TYPE_QNAME_TEST_CONTENT, properties);
603         fillProperties(ASPECT_QNAME_TEST_TITLED, properties);
604         
605         // create node for real
606
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         // check that the titled aspect is present
614
assertTrue("Titled aspect not present",
615                 nodeService.hasAspect(nodeRef, ASPECT_QNAME_TEST_TITLED));
616         
617         // attempt to remove the aspect
618
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             // expected
626
}
627     }
628     
629     public static class BadOnDeleteNodePolicy implements
630             NodeServicePolicies.OnDeleteNodePolicy,
631             NodeServicePolicies.BeforeDeleteNodePolicy
632     {
633         private NodeService nodeService;
634         private List JavaDoc<NodeRef> deletedNodeRefs;
635         
636         public BadOnDeleteNodePolicy(NodeService nodeService, List JavaDoc<NodeRef> deletedNodeRefs)
637         {
638             this.nodeService = nodeService;
639             this.deletedNodeRefs = deletedNodeRefs;
640         }
641         
642         public void beforeDeleteNode(NodeRef nodeRef)
643         {
644             // add a new child to the child, i.e. just before it is deleted
645
ChildAssociationRef assocRef = nodeService.createNode(
646                     nodeRef,
647                     ASSOC_TYPE_QNAME_TEST_CHILDREN,
648                     QName.createQName("pre-delete new child"),
649                     ContentModel.TYPE_CONTAINER);
650             // set some child node properties
651
nodeService.setProperty(nodeRef, PROP_QNAME_BOOLEAN_VALUE, "true");
652             // add an aspect to the child
653
nodeService.addAspect(nodeRef, ASPECT_QNAME_TEST_TITLED, null);
654         }
655
656         public void onDeleteNode(ChildAssociationRef childAssocRef)
657         {
658             // add the child to the list
659
deletedNodeRefs.add(childAssocRef.getChildRef());
660             // now perform some nasties on the node's parent, i.e. add a new child
661
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 JavaDoc
673     {
674         final List JavaDoc<NodeRef> deletedNodeRefs = new ArrayList JavaDoc<NodeRef>(5);
675         
676         NodeServicePolicies.OnDeleteNodePolicy policy = new BadOnDeleteNodePolicy(nodeService, deletedNodeRefs);
677         // bind to listen to the deletion of a node
678
policyComponent.bindClassBehaviour(
679                 QName.createQName(NamespaceService.ALFRESCO_URI, "onDeleteNode"),
680                 policy,
681                 new JavaBehaviour(policy, "onDeleteNode"));
682         
683         // build the node and commit the node graph
684
Map JavaDoc<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         // delete n1
692
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         // commit to check
700
setComplete();
701         endTransaction();
702     }
703     
704     private int countChildrenOfNode(NodeRef nodeRef)
705     {
706         String JavaDoc query =
707                 "select node.childAssocs" +
708                 " from " +
709                 NodeImpl.class.getName() + " node" +
710                 " where node.key.guid = ?";
711         Session session = getSession();
712         List JavaDoc 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 JavaDoc
720     {
721         // create a bogus reference
722
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             // expected
731
}
732     }
733     
734     public void testAddChild() throws Exception JavaDoc
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         // associate the two nodes
744
nodeService.addChild(
745                 rootNodeRef,
746                 childNodeRef,
747                 ASSOC_TYPE_QNAME_TEST_CHILDREN,
748                 QName.createQName("pathB"));
749         // there should now be 2 child assocs on the root
750
int countAfter = countChildrenOfNode(rootNodeRef);
751          assertEquals("Root children count incorrect", 2, countAfter);
752          
753          // now attempt to create a cyclical relationship
754
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              // expected
766
}
767     }
768     
769     public void testRemoveChildByRef() throws Exception JavaDoc
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         // remove the child - this must cascade
789
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 JavaDoc
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         // make a duplication, but non-primary, child associaton
810
nodeService.addChild(
811                 rootNodeRef,
812                 pathARef.getChildRef(),
813                 pathARef.getTypeQName(),
814                 pathARef.getQName());
815         // now remove the association - it will cascade to the child
816
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 JavaDoc
826     {
827         // create a node to play with
828
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 JavaDoc valueProperty1 = "VALUE1";
837         QName qnameProperty2 = QName.createQName("PROPERTY2");
838         String JavaDoc valueProperty2 = "VALUE2";
839         QName qnameProperty3 = QName.createQName("PROPERTY3");
840         QName qnameProperty4 = QName.createQName("PROPERTY4");
841         
842         Map JavaDoc<QName, Serializable JavaDoc> properties = new HashMap JavaDoc<QName, Serializable JavaDoc>(5);
843         properties.put(qnameProperty1, valueProperty1);
844         // add some properties to the root node
845
nodeService.setProperties(nodeRef, properties);
846         // set a single property
847
nodeService.setProperty(nodeRef, qnameProperty2, valueProperty2);
848         // set a null property
849
nodeService.setProperty(nodeRef, qnameProperty3, null);
850         // set an enum property
851
nodeService.setProperty(nodeRef, qnameProperty4, TestEnum.TEST_ONE);
852         
853         // force a flush
854
getSession().flush();
855         getSession().clear();
856         
857         // make sure that our integrity allows this
858
AlfrescoTransactionSupport.flush();
859         
860         // now get them back
861
Map JavaDoc<QName, Serializable JavaDoc> 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         // get a single property direct from the node
872
Serializable JavaDoc valueCheck = nodeService.getProperty(nodeRef, qnameProperty2);
873         assertNotNull("Property value not set", valueCheck);
874         assertEquals("Property value incorrect", "VALUE2", valueCheck);
875         
876         // set the property value to null
877
try
878         {
879             nodeService.setProperty(nodeRef, qnameProperty2, null);
880         }
881         catch (IllegalArgumentException JavaDoc e)
882         {
883             fail("Null property values are allowed");
884         }
885         // try setting null value as part of complete set
886
try
887         {
888             properties = nodeService.getProperties(nodeRef);
889             properties.put(qnameProperty1, null);
890             nodeService.setProperties(nodeRef, properties);
891         }
892         catch (IllegalArgumentException JavaDoc e)
893         {
894             fail("Null property values are allowed in the map");
895         }
896     }
897     
898     /**
899      * Ensures that the type you get out of a <b>d:any</b> property is the type that you
900      * put in.
901      */

902     public void testSerializableProperties() throws Exception JavaDoc
903     {
904         ContentData contentData = new ContentData(null, null, 0L, null);
905         QName qname = PROP_QNAME_CONTENT_VALUE;
906         
907         Map JavaDoc<QName, Serializable JavaDoc> properties = new HashMap JavaDoc<QName, Serializable JavaDoc>(17);
908         properties.put(PROP_QNAME_CONTENT_VALUE, contentData);
909         properties.put(PROP_QNAME_SERIALIZABLE_VALUE, qname);
910         // create node
911
NodeRef nodeRef = nodeService.createNode(
912                 rootNodeRef,
913                 ASSOC_TYPE_QNAME_TEST_CHILDREN,
914                 QName.createQName("pathA"),
915                 ContentModel.TYPE_CONTAINER,
916                 properties).getChildRef();
917         // persist
918
flushAndClear();
919         
920         // get the properties back
921
Map JavaDoc<QName, Serializable JavaDoc> checkProperties = nodeService.getProperties(nodeRef);
922         Serializable JavaDoc checkPropertyContentData = checkProperties.get(PROP_QNAME_CONTENT_VALUE);
923         Serializable JavaDoc 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     /**
929      * Check that properties go in and come out in the correct format
930      */

931     public void testPropertyTypes() throws Exception JavaDoc
932     {
933         ArrayList JavaDoc<String JavaDoc> listProperty = new ArrayList JavaDoc<String JavaDoc>(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 JavaDoc<QName, Serializable JavaDoc> properties = new HashMap JavaDoc<QName, Serializable JavaDoc>(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 JavaDoc());
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         // create a new node
958
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         // persist
966
flushAndClear();
967         
968         // get the properties back
969
Map JavaDoc<QName, Serializable JavaDoc> checkProperties = nodeService.getProperties(nodeRef);
970         // check
971
for (QName qname : properties.keySet())
972         {
973             Serializable JavaDoc value = properties.get(qname);
974             Serializable JavaDoc checkValue = checkProperties.get(qname);
975             assertEquals("Property mismatch - " + qname, value, checkValue);
976         }
977         
978         // check multi-valued properties are created where necessary
979
nodeService.setProperty(nodeRef, PROP_QNAME_MULTI_VALUE, "GHI");
980         Serializable JavaDoc checkProperty = nodeService.getProperty(nodeRef, PROP_QNAME_MULTI_VALUE);
981         assertTrue("Property not converted to a Collection", checkProperty instanceof Collection JavaDoc);
982         assertTrue("Collection doesn't contain value", ((Collection JavaDoc)checkProperty).contains("GHI"));
983     }
984     
985     /**
986      * Checks that the {@link ContentModel#ASPECT_REFERENCEABLE referencable} properties
987      * are present
988      */

989     public void testGetReferencableProperties() throws Exception JavaDoc
990     {
991         // check individual property retrieval
992
Serializable JavaDoc wsProtocol = nodeService.getProperty(rootNodeRef, ContentModel.PROP_STORE_PROTOCOL);
993         Serializable JavaDoc wsIdentifier = nodeService.getProperty(rootNodeRef, ContentModel.PROP_STORE_IDENTIFIER);
994         Serializable JavaDoc 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        // check mass property retrieval
1005
Map JavaDoc<QName, Serializable JavaDoc> 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 JavaDoc
1012    {
1013        Map JavaDoc<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        // get a child node's parents
1019
NodeRef n8Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n6_p_n8")).getChildRef();
1020        List JavaDoc<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        // check that we can retrieve the primary parent
1026
ChildAssociationRef primaryParentAssocCheck = nodeService.getPrimaryParent(n8Ref);
1027        assertEquals("Primary parent assoc not retrieved", n6pn8Ref, primaryParentAssocCheck);
1028        
1029        // check that the root node returns a null primary parent
1030
ChildAssociationRef rootNodePrimaryAssoc = nodeService.getPrimaryParent(rootNodeRef);
1031        assertNull("Expected null primary parent for root node", rootNodePrimaryAssoc.getParentRef());
1032        
1033        // get the parent associations based on pattern
1034
List JavaDoc<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        // get the parent association based on type pattern
1041
List JavaDoc<ChildAssociationRef> childAssocRefsByTypeQName = nodeService.getChildAssocs(
1042                n8Ref,
1043                ASSOC_TYPE_QNAME_TEST_CHILDREN,
1044                RegexQNamePattern.MATCH_ALL);
1045    }
1046    
1047    public void testGetChildAssocs() throws Exception JavaDoc
1048    {
1049        Map JavaDoc<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        // get the parent node's children
1055
List JavaDoc<ChildAssociationRef> childAssocRefs = nodeService.getChildAssocs(n1Ref);
1056        assertEquals("Incorrect number of children", 2, childAssocRefs.size());
1057        // checks that the order of the children is correct
1058
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        // now set the child ordering explicitly - change the order
1063
nodeService.setChildAssociationIndex(n1pn3Ref, 1);
1064        nodeService.setChildAssociationIndex(n1n4Ref, 0);
1065        
1066        // repeat
1067
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        // get the child associations based on pattern
1072
List JavaDoc<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        // get the child association based on type pattern
1079
List JavaDoc<ChildAssociationRef> childAssocRefsByTypeQName = nodeService.getChildAssocs(
1080                n1Ref,
1081                ASSOC_TYPE_QNAME_TEST_CHILDREN,
1082                RegexQNamePattern.MATCH_ALL);
1083    }
1084    
1085    public void testMoveNode() throws Exception JavaDoc
1086    {
1087        Map JavaDoc<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        // move n8 to n5
1096
ChildAssociationRef assocRef = nodeService.moveNode(
1097                n8Ref,
1098                n5Ref,
1099                ASSOC_TYPE_QNAME_TEST_CHILDREN,
1100                QName.createQName(BaseNodeServiceTest.NAMESPACE, "n5_p_n8"));
1101        // check that n6 is no longer the parent
1102
List JavaDoc<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        // check that n5 is the parent
1107
ChildAssociationRef checkRef = nodeService.getPrimaryParent(n8Ref);
1108        assertEquals("Primary assoc incorrent", assocRef, checkRef);
1109        
1110        // check that cyclic associations are disallowed
1111
try
1112        {
1113            // n6 is a non-primary child of n4. Move n4 into n6
1114
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            // expected
1124
}
1125    }
1126    
1127    /**
1128     * Creates a named association between two nodes
1129     *
1130     * @return Returns an array of [source real NodeRef][target reference NodeRef][assoc name String]
1131     */

1132    private AssociationRef createAssociation() throws Exception JavaDoc
1133    {
1134        Map JavaDoc<QName, Serializable JavaDoc> properties = new HashMap JavaDoc<QName, Serializable JavaDoc>(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        // done
1158
return assocRef;
1159    }
1160    
1161    public void testAssociationToIncorrectNodeType() throws Exception JavaDoc
1162    {
1163        AssociationRef assocRef = createAssociation();
1164        NodeRef sourceRef = assocRef.getSourceRef();
1165        NodeRef targetRef = assocRef.getTargetRef();
1166        QName qname = assocRef.getTypeQName();
1167        try
1168        {
1169            // attempt the association in reverse
1170
nodeService.createAssociation(sourceRef, targetRef, qname);
1171            fail("Incorrect node type not detected");
1172        }
1173        catch (RuntimeException JavaDoc e)
1174        {
1175            // expected
1176
}
1177    }
1178    
1179    public void testDuplicateAssociationDetection() throws Exception JavaDoc
1180    {
1181        AssociationRef assocRef = createAssociation();
1182        NodeRef sourceRef = assocRef.getSourceRef();
1183        NodeRef targetRef = assocRef.getTargetRef();
1184        QName qname = assocRef.getTypeQName();
1185        try
1186        {
1187            // attempt repeat
1188
nodeService.createAssociation(sourceRef, targetRef, qname);
1189            fail("Duplicate assocation not detected");
1190        }
1191        catch (AssociationExistsException e)
1192        {
1193            // expected
1194
}
1195    }
1196    
1197    public void testCreateAndRemoveAssociation() throws Exception JavaDoc
1198    {
1199        AssociationRef assocRef = createAssociation();
1200        NodeRef sourceRef = assocRef.getSourceRef();
1201        
1202        // create another
1203
Map JavaDoc<QName, Serializable JavaDoc> properties = new HashMap JavaDoc<QName, Serializable JavaDoc>(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        // remove assocs
1219
List JavaDoc<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 JavaDoc
1230    {
1231        AssociationRef assocRef = createAssociation();
1232        NodeRef sourceRef = assocRef.getSourceRef();
1233        NodeRef targetRef = assocRef.getTargetRef();
1234        QName qname = assocRef.getTypeQName();
1235        // get the target assocs
1236
List JavaDoc<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 JavaDoc
1242    {
1243        AssociationRef assocRef = createAssociation();
1244        NodeRef sourceRef = assocRef.getSourceRef();
1245        NodeRef targetRef = assocRef.getTargetRef();
1246        QName qname = assocRef.getTypeQName();
1247        // get the source assocs
1248
List JavaDoc<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    /**
1254     * @see #buildNodeGraph()
1255     */

1256    public void testGetPath() throws Exception JavaDoc
1257    {
1258        Map JavaDoc<QName, ChildAssociationRef> assocRefs = buildNodeGraph();
1259        NodeRef n8Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE,"n6_p_n8")).getChildRef();
1260
1261        // get the primary node path for n8
1262
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    /**
1269     * @see #buildNodeGraph()
1270     */

1271    public void testGetPaths() throws Exception JavaDoc
1272    {
1273        Map JavaDoc<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        // get all paths for the root node
1279
Collection JavaDoc<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        // get all paths for n8
1286
paths = nodeService.getPaths(n8Ref, false);
1287        assertEquals("Incorrect path count", 5, paths.size()); // n6 is a root as well
1288
// check that each path element has parent node ref, qname and child node ref
1289
for (Path path : paths)
1290        {
1291            // get the path elements
1292
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                    // for all but the first element, the parent and assoc qname must be set
1300
assertNotNull("Parent node ref not set", ref.getParentRef());
1301                    assertNotNull("QName not set", ref.getQName());
1302                }
1303                // all associations must have a child ref
1304
assertNotNull("Child node ref not set", ref.getChildRef());
1305            }
1306        }
1307
1308        // get primary path for n8
1309
paths = nodeService.getPaths(n8Ref, true);
1310        assertEquals("Incorrect path count", 1, paths.size());
1311        
1312        // check that a cyclic path is detected - make n6_n1
1313
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            // expected
1322
}
1323        catch (StackOverflowError JavaDoc e)
1324        {
1325            throw e;
1326        }
1327    }
1328    
1329    public void testPrimaryPathCascadeDelete() throws Exception JavaDoc
1330    {
1331        Map JavaDoc<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        // delete n1
1337
nodeService.deleteNode(n1Ref);
1338        // check that the rest disappeared
1339
assertFalse("n6 not cascade deleted", nodeService.exists(n6Ref));
1340        assertFalse("n8 not cascade deleted", nodeService.exists(n8Ref));
1341    }
1342    
1343    /**
1344     * Test that default values are set when nodes are created and aspects applied
1345     *
1346     * @throws Exception
1347     */

1348    public void testDefaultValues() throws Exception JavaDoc
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        // Ensure that default values do not overrite already set values
1360
Map JavaDoc<QName, Serializable JavaDoc> props = new HashMap JavaDoc<QName, Serializable JavaDoc>(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 JavaDoc<QName, Serializable JavaDoc> prop2 = new HashMap JavaDoc<QName, Serializable JavaDoc>(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        // Check that the required mandatory aspects have been applied
1385
assertTrue(this.nodeService.hasAspect(nodeRef, ASPECT_QNAME_TEST_TITLED));
1386        assertTrue(this.nodeService.hasAspect(nodeRef, ASPECT_QNAME_MANDATORY));
1387        
1388        // Add an aspect with dependacies
1389
this.nodeService.addAspect(nodeRef, ASPECT_QNAME_TEST_MARKER, null);
1390        
1391        // Check that the dependant aspect has been applied
1392
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 JavaDoc
1397    {
1398        // garbage collect and wait
1399
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 JavaDoc msg,
1411            Map JavaDoc<QName, ChildAssociationRef> lastNodeGraph,
1412            int testCount,
1413            long startBytes,
1414            long startTime) throws Exception JavaDoc
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    /**
1450     * Builds N node graphs, flushing after each build. Checks that memory is being cleared
1451     * adequately.
1452     * <p>
1453     * This is also a good test of performance, so that is dumped.
1454     *
1455     * @see BaseNodeServiceTest#buildNodeGraph()
1456     */

1457    public void testFlush() throws Exception JavaDoc
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 JavaDoc<QName, ChildAssociationRef>> buildWork = new TransactionWork<Map JavaDoc<QName, ChildAssociationRef>>()
1470        {
1471            public Map JavaDoc<QName, ChildAssociationRef> doWork()
1472            {
1473                Map JavaDoc<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                    // report
1483
reportFlushPerformance("Statistics pre-commit", nodeGraph, testCount, startBytes, startTime);
1484                }
1485                catch (OutOfMemoryError JavaDoc e)
1486                {
1487                    fail("Flush not clearing memory");
1488                }
1489                catch (Exception JavaDoc e)
1490                {
1491                    throw new AlfrescoRuntimeException("Node graph building failed", e);
1492                }
1493                return nodeGraph;
1494            }
1495        };
1496        Map JavaDoc<QName, ChildAssociationRef> nodeGraph = TransactionUtil.executeInNonPropagatingUserTransaction(transactionService, buildWork);
1497        
1498        // report post-commit stats
1499
reportFlushPerformance("Statistics post-commit", nodeGraph, testCount, startBytes, startTime);
1500    }
1501}
1502
Popular Tags