Content Modeling Behavior


Published on

This session starts by giving an overview of components of an Alfresco content model. We then examine the various forms of call-backs and hook-points available to the developer and give some examples of how these can be used to enforce custom business logic and model consistency.

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • Other foundation services include Content Service, Search Service …Other higher-level services include FileFolderService, CheckoutCheckInService, VersionService, CopyService …
  • ALF-680 - Previously valid content models now fail with CMISAbstractDictionaryService$DictionaryRegistry exception (r20488)CHK-8823 -Dictionary/Constraint improvements (required by MOB-1276) (r15913)
  • ALF-955 - Deletion of dynamic custom model (Ent 3.2.1 / Com 3.3)ALF-4119 - NodeService: beforeDeleteNode archiving (WIP – targeted for Com 3.4b)
  • ALF-3885 - Allow multiple policies through type hierarchy (r21253) (Com 3.4.a / Ent 3.4.0)CHK-2720 - Fixed AR-401 Can only have one policy handler (r8698)
  • Content Modeling Behavior

    1. 1. Content Modelling and Policy Behaviors<br />0<br />Jan Vonka<br />Repository Team, Alfresco<br />
    2. 2. Introduction - Contents<br />1<br />Introduction<br />Modelling<br />Overview<br />Components<br />Examples<br />Behaviours<br />Overview<br />Components<br />Examples<br />Past, present & future<br />Q & A … feedback<br />
    3. 3. Introduction – Hi<br />2<br />About me<br />I’ve been with Alfresco since early 2007<br />primarily working in the core repository team<br />worked for various companies in UK & California<br />I enjoy flying hot-air balloons ;-)<br />Spelling<br />to be consistent I’ll stick with the British spelling<br />Modelling <=> Modeling<br />Behaviour <=> Behavior<br />About you<br />Modelling vs Behaviours … how much time (50/50) ?<br />I’d like to allow enough time for <br />Q & A and general feedback (your experience)<br />
    4. 4. Introduction - Assumptions<br />3<br />How many of you have … ?<br />attended training course<br />DevConJumpStart course<br />Intensive Developers course<br />and/or read<br />Professional Alfresco book (chapter 5)<br />Jeff Pott’sAlfresco Developer Guide (chapters 3 & 4)<br />Alfresco wiki (“Data Dictionary” and related pages)<br />and/or hands-on experience<br />followed examples (eg. Books and/or Alfresco SDK)<br />developed your own custom content model & app’<br />
    5. 5. Introduction – “Dictionary” Definitions<br />4<br />[something] used as an example to follow or imitate<br />to make [something] conform to a chosen standard<br />Modelling<br />the way in which [something] behaves in response to a particular situation or stimulus<br />Behaviour<br />
    6. 6. Introduction – Alfresco Content Repository<br />5<br />which enables storage of a potentially arbitrary network of entity data<br />content entities <br />“metadata” (about the entities)<br />relationships (between the entities)<br />Stores<br />store ref(erence)<br />root node<br />Nodes<br />unique node ref(erence)<br />Properties<br />on nodes<br />(Peer) Associations<br />from source to target node<br />Child associations<br />between parent & child node<br />primary & secondary<br />Domain<br />Embeds a storage engine<br />
    7. 7. Introduction – model / domain consistency<br />6<br />Model / domain consistency can be maintained via …<br />Content Model + Integrity Checker<br />formal model definition<br />including built-in constraints<br />option to also write & plug-in custom constraints (not specifically covered here)<br />Behaviours<br />custom business logic bound to policies<br />Rules & Actions<br />not covered here … see separate session<br />
    8. 8. Modelling<br />7<br />[something] used as an example to follow or imitate<br />to make [something] conform to a chosen standard<br />
    9. 9. Modelling overview – Content Models<br />8<br />Content models<br />are all about metadata (data that describes data)<br />constrain otherwise arbitrary nodes, properties and associations<br />are named and define one or more namespaces<br />can import namespaces in order to allow references to other models<br />must be configured and loaded in dependent order<br />“bootstrap” models are statically loaded from the filesystem (“extensions” classpath) when repo starts<br />“dynamic” models are dynamically loaded from the repo (“Models” space) when models are added or changed<br />integrity checks fire when transaction commits<br />mandatory can be enforced (else node is marked as incomplete)<br />
    10. 10. Modelling overview – Services<br />9<br />Get def’ (or all QNames)<br />model<br />types / aspect<br />property<br />datatype<br />constraint<br />association<br />also: is sub-class ?<br />Also refers to<br />QName<br />NamespaceService (prefix resolver)<br />Dictionary Service<br />Nodes<br />create, move, delete, restore<br />Properties<br />set, get, remove<br />Associations<br />create, remove, <br />get sources, get targets<br />Child Associations<br />get children, get parents<br />get primary parent<br />Node Service<br />
    11. 11. Modelling overview - M2 (meta-)model<br />10<br />Aspect<br />Type<br />Association<br />Class<br />Child Association<br />Data Type<br />Property<br />Constraint<br />
    12. 12. Modelling overview – M2 (meta-)model<br />11<br />modelSchema.xsd<br />Imports<br />Namespaces<br />Data-types<br />Constraints<br />Types / Aspects<br />Properties<br />Constraints<br />Associations<br />Child Associations<br />Summary<br />
    13. 13. Model components – Types & Aspects (Nodes)<br />12<br />Node<br />must be of a given type when created<br />can also setType (ie. specialise / change type)<br />may have zero or more aspects attached<br />either from type or at runtime<br />may have a set of properties <br />defined by type & aspects (including inherited types & aspects)<br />may be associated with other nodes<br />defined by type & aspects (including inherited types & aspects)<br />
    14. 14. Model components – Properties<br />13<br />Property<br />must be named<br />must be of a given datatype<br />may be single-valued (default) or multi-valued<br />may have zero or more constraints (inline or referenced)<br />may be mandatory<br />either: enforced <br />or: relaxed (if missing, node marked with incomplete aspect)<br />may have default value<br />may be “residual”<br />in this case there is no associated property definition<br />can be overridden in terms of inheritance<br />to a limited extent – mandatory, default, constraints<br />
    15. 15. Model components – Constraints<br />14<br />Built-in constraint types:<br />LIST (“ListOfValuesConstraint)<br />LENGTH (“StringLengthConstraint”)<br />MINMAX (“NumericRangeConstraint”)<br />REGEXP (“RegexConstraint”)<br />Other examples, eg. RM caveats use:<br />“RMListOfValuesConstraint” (extends “ListOfValuesConstraint”)<br />You can hook in your own constraint implementations<br />implement “Constraint” interface<br />typically extend “AbstractConstraint”<br />must have default constructor (as it’s used to instantiate it)<br />in model, define constraint with “type” attribute set to fully-qualified class name<br />make sure you unit test your constraint (it is performance sensitive)<br />Constraints execute<br />as part of integrity checks prior to commit (ie. at the end of a server transaction)<br />
    16. 16. Model components – Associations (Peer)<br />15<br />(Peer) Association<br />association type is named<br />source node may be associated with zero or more target nodes<br />may be mandatory<br />enforced or relaxed (missing => node marked with incomplete aspect)<br />cardinality can be defined via many / mandatory<br />0 or 1(mandatory = false, many = false)<br />1 (mandatory = true, many = false)<br />0 or more (mandatory = false, many = true)<br />1 or more (mandatory = true, many = true)<br />
    17. 17. Model components – Child Associations<br />16<br />Child Association<br />defined in same way as peer association with extra features<br />parent node may be associated with zero or more child nodes<br />affects certain operations, eg. delete will cascade<br />also defines if child name can be duplicated or unique within parent<br />a node can have one primary child association<br />a node may have one or more secondary child associations<br />
    18. 18. Model components – Admin Node Browser<br />17<br />Don’t forget “the Node Browser is your friend !”<br />in theory never lies …<br />… although be careful with browser back button (JSF issue)<br />
    19. 19. Model components – some changes since 3.x<br />18<br />Dynamic models<br />since 3.0<br />reduces need for server restart, also enables multi-tenancy option<br />CMIS mapping<br />CMIS type, CMIS property, CMIS relationship (peer assoc)<br />CMIS document (cm:content), CMIS folder (cm:folder)<br />Constraints support title & description (needed by RM)<br />since 3.2<br />Tightened validation check for content models<br />since 3.4<br />unfortunately, due to a long standing bug, it has always been possible to define new model elements using a namespace that wasn't defined by the containing model (eg. using an imported namespace)<br />with the recent bug fix, it is now only possible to create model elements whose namespace is also defined by the containing model<br />“DataModel” split out from “Repository”<br />since 3.4<br />split into separate JAR / Eclipse project – for future SOLR integration<br />
    20. 20. Model components – example<br />19<br />sys:referenceable<br /><ul><li>sys:store-protocol
    21. 21. sys:store-identifier
    22. 22. sys:node-uuid
    23. 23. sys:node-dbid</li></ul>sys:base<br />cm:auditable<br /><ul><li>cm:created
    24. 24. cm:creator
    25. 25. cm:modified
    26. 26. cm:modifier</li></ul>cm:cmobject<br />- cm:name<br />cm:folder<br />cm:content<br />
    27. 27. Example – custom model<br />20<br />cm:folder<br />cm:content<br />my:customBaseFolder<br />my:customBaseAspect<br />my:customBaseContent<br />my:customContent<br />my:customSubFolder<br />my:customSubAspect<br />
    28. 28. Model demo – Sample XMI generator<br />21<br />… more here …<br />Map<String, Object> fmModel = new HashMap<String, Object>();<br />fmModel.put("prefixDelimiter", prefixDelimiter);<br />fmModel.put("classes", allM2Classes);<br />fmModel.put("datatypes", datatypes);<br />Configuration cfg = new Configuration();<br />cfg.setObjectWrapper(ObjectWrapper.DEFAULT_WRAPPER);<br />String userDir = System.getProperty("user.dir");<br />cfg.setDirectoryForTemplateLoading(newFile(userDir+"/source/test-resources/SimpleXMI"));<br />// UML 1.4 / XMI 1.2 - suitable for ArgoUML (eg. 0.30.2)<br />Template temp = cfg.getTemplate("simple-Xmi1.2-Uml1.4.ftl");<br />File f = new File(userDir, "simpleXMI-"+System.currentTimeMillis()+".xmi");<br />Writer out = new FileWriter(f);<br />temp.process(fmModel, out);<br />out.flush();<br />out.close();<br />… more here …<br /> (extract)<br />… more here …<br /><#list datatypesas datatype><br /> <#assign":")><br /> < = 'id-datatype:${}'<br /> name = '${}'isSpecification= 'false' isRoot = 'false' isLeaf = 'false'<br />isAbstract= 'false'/><br /> </#list><br /> <#list classes as class><br /> < = 'id-class:${}'<br /> name = '${":",prefixDelimiter)}’ isSpecification= 'false' isRoot = 'false'<br />isLeaf= 'false' isAbstract = 'false' isActive = 'false'><br /> <#if class.isAspect() == true ><br /> <UML:ModelElement.stereotype><br /> <UML:Stereotypexmi.idref = 'id-stereotype:aspect'/><br /> </UML:ModelElement.stereotype><br /> <#else><br />… more here …<br />simple-Xmi1.2-Uml1.4.ftl (extract)<br />
    29. 29. Model examples –DevCon sample<br />22<br />
    30. 30. Model examples – Web Quick Start (WQS)<br />23<br />
    31. 31. Model examples – many “OOTB”<br />24<br />Many examples “out-of-the-box”<br />Search for “*Model.xml” across the Alfresco source tree<br />Core model files (with defined namespaces) include:<br />dictionaryModel.xml<br /> (alf)<br /> (d)<br /> (view)<br />systemModel.xml<br /> (sys)<br /> (reg)<br /> (module)<br />contentModel.xml<br /> (cm)<br /> (rn)<br /> (exif)<br />
    32. 32. Model examples – modules (eg. RM, WQS)<br />25<br />Alfresco modules also provide some great examples, eg.<br />Records Management (RM / DOD5015)<br />dod5015Model.xml<br /> (dod)<br />recordsCustomModel.xml (dynamically managed)<br /> (rmc)<br />Web Quick Start (WQS)<br />webSiteModel.xml<br /> (ws)<br />
    33. 33. Behaviours<br />26<br />the way in which [something] behaves in response to a particular situation or stimulus<br />
    34. 34. Behaviours overview – policy + behaviour <br />27<br />Policies provide hook points to which you can bind behaviours to events based on class or association<br />behaviours are (policy) handlers that execute specific business logic<br />behaviours can be implemented in Java and/or JavaScript<br />Behaviours can be bound to a type or aspect<br />node in the content repository must be of a single type<br />node may have one or more aspects attached<br />aspects are either inherited from its type (defined by the model)<br />or can be attached (or detached) at runtime …<br />allowing a node to dynamically inherit features and capabilities<br />aspects can be interpreted by the repository to change behaviour<br />eg. by the presence of an aspect (even with no properties)<br />
    35. 35. Behaviours overview – policy component <br />28<br />From JavaDoc (org.alfresco.repo.policy) …<br />The Policy Component manages Policies and Behaviours. It provides the<br />ability to:<br />a) Register policies<br />b) Bind behaviours to policies<br />c) Invoke policy behaviours<br />A behaviour may be bound to a Policy before the Policy is registered. In<br />this case, the behaviour is not validated (i.e. checked to determine if it<br />Supports the policy interface) until the Policy is registered. Otherwise,<br />the behaviour is validated at bind-time.<br />Policies may be selectively "turned off" by the Behaviour Filter.<br />
    36. 36. Behaviour components – behaviour interface<br />29<br />Behaviour<br />BaseBehaviour<br />JavaBehaviour<br />ScriptBehaviour<br />
    37. 37. Behaviour components – policy interface<br />30<br /> Policy<br />ClassPolicy (type or aspect)<br />AssociationPolicy (peer or parent-child)<br />PropertyPolicy (not used)<br />
    38. 38. Behaviour components – some OOTB policies<br />31<br />Search for “*” across the Alfresco source tree<br />Examples include:<br />NodeServicePolicies<br />before/onCreateNode, <br />beforeDeleteNode (don’t use “on”)<br />before/onUpdateNode<br />onUpdateProperties<br />before/onAddAspect<br />before/onRemoveAspect<br />before/onCreateChildAssociation<br />before/onDeleteChildAssocation<br />onCreateAssociation<br />onDeleteAssociation<br />….<br />ContentServicePolicies<br />onContentUpdate<br />onContentPropertyUpdate<br />
    39. 39. Behaviour components - other policy examples<br />32<br />CopyServicePolicies<br />before/onCopy<br />onCopyComplete<br />CheckOutCheckInServicePolicies<br />before/OnCheckOut<br />before/OnCheckIn<br />before/OnCancelCheckOut<br />And more …<br />VersionServicePolicies<br />StoreSelectorPolicies<br />AsynchronousActionExecutionQueuePolicies<br />RecordsManagementPolicies<br />Note: you can define, register and invoke you own custom policies, eg.<br />RecordsManagementPolicies <= RecordsManagementActionServiceImpl<br />
    40. 40. Behaviour components – register & invoke<br />33<br />public interface NodeServicePolicies<br />{ <br /> public interface OnAddAspectPolicy extends ClassPolicy<br /> {<br /> public static final QName QNAME = QName.createQName(NamespaceService.ALFRESCO_URI, "onAddAspect");<br /> // Called after an <b>aspect</b> has been added to a node<br /> public void onAddAspect(NodeRefnodeRef, QNameaspectTypeQName);<br /> }<br />}<br />public abstract class AbstractNodeServiceImpl implements NodeService<br />{<br /> // note: policyComponent is injected … (not shown here)<br /> public void init()<br /> {<br /> // Register the policy<br />onAddAspectDelegate = policyComponent.registerClassPolicy<br /> (NodeServicePolicies.OnAddAspectPolicy.class);<br /> }<br /> protected void invokeOnAddAspect(NodeRefnodeRef, QNameaspectTypeQName)<br /> { <br />NodeServicePolicies.OnAddAspectPolicy policy = onAddAspectDelegate.get(nodeRef, aspectTypeQName);<br />policy.onAddAspect(nodeRef, aspectTypeQName);<br /> }<br />}<br />
    41. 41. Behaviour components – bind & implement<br />34<br />public class XyzAspect implements NodeServicePolicies.OnAddAspectPolicy, ...<br />{<br /> // note: policyComponent is injected … (not shown here)<br /> public void init()<br /> {<br /> // bind to the policy<br />policyComponent.bindClassBehaviour(<br />OnAddAspectPolicy.QNAME,<br />ContentModel.ASPECT_XYZ,<br /> new JavaBehaviour(this, "onAddAspect”, <br />Behaviour.NotificationFrequency.TRANSACTION_COMMIT));<br /> }<br /> public void onAddAspect(NodeRefnodeRef, QNameaspectTypeQName)<br /> {<br /> // implement behaviour here … (for when aspect XYZ is added)<br /> }<br />}<br />
    42. 42. Behaviour components – class vs service binding<br />35<br />…<br />//<br />// note: usually try to bind on specific class (type/aspect) rather than service method<br />//<br />// class binding – specific type or aspect<br />policyComponent.bindClassBehaviour(<br />NodeServicePolicies.OnUpdatePropertiesPolicy.QNAME,<br />ContentModel.TYPE_PERSON, <br /> new JavaBehaviour(this, <br /> "onUpdateProperties”,<br />Behaviour.NotificationFrequency.EVERY_EVENT));<br />// service binding – all types/aspects<br />policyComponent.bindClassBehaviour( <br />NodeServicePolicies.OnUpdatePropertiesPolicy.QNAME,<br />this,<br /> new JavaBehaviour(this, <br /> "onUpdateProperties”,<br />Behaviour.NotificationFrequency.EVERY_EVENT));<br />…<br />
    43. 43. Behaviour components - handle now or later<br />36<br />Notification Frequency<br />behaviours can be defined with a notification frequency – “every event” (default), “first event”, “transaction commit”<br />consider that during a given transaction, certain policies may fire multiple times (ie. “every event”)<br />can set notification frequency to “first event” or “transaction commit”<br />Using Transactional Resource<br />option to execute logic immediately or queue (eg. via transactional resource) until commit (beforeCommit and/or afterCommit)<br />AlfrescoTransactionSupport.bindResource(K, V)<br />V = AlfrescoTransactionSupport.getResource(K)<br />
    44. 44. Behaviour components – disable / (re-)enable<br />37<br />Behaviours can be temporarily disabled<br />BehaviourFilterinterface<br />for current transaction only<br />for “class” (type or aspect) or “node + class”<br />disableBehaviour<br />enableBehaviour<br />isEnabled<br />for “node”<br />enableBehaviours<br />for “all”<br />disableAllBehaviours<br />enableAllBehaviours<br />isActivated<br />Behaviour interface<br />for current thread only<br />disable / enable, eg. in try / finally block<br />Examples – importer, transfer – disable behaviours<br />
    45. 45. Behaviour components - delete is delete !<br />38<br /><ul><li>From the perspective of the custom behaviour</li></ul>delete is delete (you should not need to care whether it is archived)<br />create is create (even if it is restored from the archive)<br /><ul><li>Bind to beforeDeleteNode (not onDeleteNode)</li></ul>note: will fire for parent and recursively for each of it’s cascade deleted children (if any)<br /><ul><li>Don’t rely (or be dependent) on the archive store</li></ul>deleted node may not be archived<br />archived node may never be restored<br />you should not need to check for archive store<br /><ul><li>One exception is peer associations</li></ul>assocs to “archived” nodes may remain (pending ALF-4119 for 3.4+)<br />
    46. 46. Behaviour components - delete is delete ! (cont)<br />39<br />“live” store<br />“archive” store<br />deleteNode<br />(purgeArchivedNode)<br />deleteNode<br />restoreNode<br />archive://SpacesStore<br />version://version2Store<br />workspace://SpacesStore<br />deleteNode<br />“version” store<br />createVersion<br />deleteVersion<br />deleteVersionHistory<br />
    47. 47. Behaviour components – some changes in 3.x<br />40<br />More than one handler can be registered for a given policy<br />since 3.0<br />We now also trigger policies through the type hierarchy<br />since 3.4<br />if you use earlier Alfresco and yet to upgrade then workaround is to bind to service bind and use “isSubClassOf” to check type<br />You should not need to check for archive store<br />since 3.3<br />operations on archive store no longer fire polices<br />also applies to version store<br />
    48. 48. Example behaviours - more<br />41<br />Search through the code for policy bindings or use Eclipse to find call hierarchy for<br />bindClassBehaviour (x2)<br />bindAssociationBehaviour (x3)<br />Many examples both in core services as well as module extensions such as<br />Web Quick Start<br /><br />DOD 5015 (Records Management)<br />You can refer to the SDK for a simple example<br />Also, for JavaScript Behaviours, refer to *old* RM module<br />
    49. 49. Modelling & Behaviours – some general tips<br />42<br />Modelling<br />consider using dynamic models during dev & test cycles<br />beware of deep class hierarchies<br />consider performance of any custom registered constraints<br />Behaviours<br />consider notification frequency<br />add debug logging<br />don’t rely on archive store<br />can temporarily disable/re-enable (thread or transaction)<br />General<br />start with the SDK and if needed move to complete SVN source tree<br />write unit tests (+ve & -ve) to exercise custom models & behaviours<br />run existing regression tests (eg. “ant test-repository” or continuous)<br />develop and package as an AMP (Alfresco Module Package)<br />
    50. 50. Past, present and future<br />43<br />Modelling<br />integrity checks do not apply to version store<br />data model has been split off (eg. for future SOLR integration)<br />now only possible to create model elements whose namespace is also defined by the containing model<br />composite content (anticipated for Project “Swift”)<br />major model enhancement<br />will also impact various foundation services<br />see wiki for more details (early draft - subject to change)<br />Behaviours<br />more than one handler can be registered for a policy<br />policies do not fire for archive store & version store<br />policies are now triggered through the type hierarchy<br />maybe some consolidation & rationalisation<br />also potentially new policies (to hook into)<br />
    51. 51. References & examples<br />44<br />Alfresco wiki / forums<br />Books<br />Professional Alfresco (Wrox)<br />Alfresco Developer Guide (Packt Publishing)<br />Alfresco Training courses<br />Intensive Developers Course (5 day)<br />Fundamentals (2 day) – new<br />Advanced Content Modelling – TBC<br />and obviously the source code itself <br />including modules, such as RM (DOD 5015)<br />
    52. 52. Feedback … Q & A<br />45<br />
    53. 53. Learn More<br />46<br /><br /><br />twitter: @AlfrescoECM<br />
    54. 54. Another Code Sample (Screenshot)<br />47<br />
    55. 55. 48<br />Shape & Color Pallette<br />Normal Text<br />Normal Text<br />Normal Text<br />
    56. 56. 49<br />
    57. 57. Content Model ex1 – model, import, namespace<br />50<br /><?xml version="1.0" encoding="UTF-8"?><br /><model name="cm:contentmodel" <br />xmlns="" <br />xmlns:xsi=""><br /> <description>Alfresco Content Domain Model</description><br /> <author>Alfresco</author><br /> <published>2009-06-04</published><br /> <version>1.1</version><br /> <imports><br /> <import uri="" prefix="d"/><br /> <import uri="" prefix="sys"/><br /> </imports><br /> <namespaces><br /> <namespace uri="" prefix="cm"/><br /> <namespace uri="" prefix="rn"/><br /> <namespace uri="" prefix="exif"/><br /> </namespaces><br />
    58. 58. Content Model ex2 - type, property, constraint<br />51<br /> <type name="cm:cmobject"><br /> <title>Object</title><br /> <parent>sys:base</parent><br /> <properties><br /> <property name="cm:name"><br /> <title>Name</title><br /> <type>d:text</type><br /> <mandatory enforced="true">true</mandatory><br /> <index enabled="true"><br /> <atomic>true</atomic><br /> <stored>false</stored> <br /> <tokenised>both</tokenised><br /> </index><br /> <constraints><br /> <constraint ref="cm:filename" /><br /> </constraints><br /> </property><br /> </properties><br /> <mandatory-aspects><br /> <aspect>cm:auditable</aspect><br /> </mandatory-aspects><br /> </type><br />
    59. 59. Content Model ex3 – child assoc …<br />52<br /> <type name="cm:folder"><br /> <title>Folder</title><br /> <parent>cm:cmobject</parent><br /> <archive>true</archive><br /> <associations><br /> <child-association name="cm:contains"><br /> <source><br /> <mandatory>false</mandatory><br /> <many>true</many><br /> </source><br /> <target><br /> <class>sys:base</class><br /> <mandatory>false</mandatory><br /> <many>true</many><br /> </target><br /> <duplicate>false</duplicate><br /> <propagateTimestamps>true</propagateTimestamps><br /> </child-association><br /> </associations><br /> </type><br />