Your SlideShare is downloading. ×
0
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Content Modeling Behavior
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Content Modeling Behavior

6,479

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 …

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
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
6,479
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
148
Comments
0
Likes
4
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
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)
  • Transcript

    • 1. Content Modelling and Policy Behaviors
      0
      Jan Vonka
      Repository Team, Alfresco
    • 2. Introduction - Contents
      1
      Introduction
      Modelling
      Overview
      Components
      Examples
      Behaviours
      Overview
      Components
      Examples
      Past, present & future
      Q & A … feedback
    • 3. Introduction – Hi
      2
      About me
      I’ve been with Alfresco since early 2007
      primarily working in the core repository team
      worked for various companies in UK & California
      I enjoy flying hot-air balloons ;-)
      Spelling
      to be consistent I’ll stick with the British spelling
      Modelling <=> Modeling
      Behaviour <=> Behavior
      About you
      Modelling vs Behaviours … how much time (50/50) ?
      I’d like to allow enough time for
      Q & A and general feedback (your experience)
    • 4. Introduction - Assumptions
      3
      How many of you have … ?
      attended training course
      DevConJumpStart course
      Intensive Developers course
      and/or read
      Professional Alfresco book (chapter 5)
      Jeff Pott’sAlfresco Developer Guide (chapters 3 & 4)
      Alfresco wiki (“Data Dictionary” and related pages)
      and/or hands-on experience
      followed examples (eg. Books and/or Alfresco SDK)
      developed your own custom content model & app’
    • 5. Introduction – “Dictionary” Definitions
      4
      [something] used as an example to follow or imitate
      to make [something] conform to a chosen standard
      Modelling
      the way in which [something] behaves in response to a particular situation or stimulus
      Behaviour
    • 6. Introduction – Alfresco Content Repository
      5
      which enables storage of a potentially arbitrary network of entity data
      content entities
      “metadata” (about the entities)
      relationships (between the entities)
      Stores
      store ref(erence)
      root node
      Nodes
      unique node ref(erence)
      Properties
      on nodes
      (Peer) Associations
      from source to target node
      Child associations
      between parent & child node
      primary & secondary
      Domain
      Embeds a storage engine
    • 7. Introduction – model / domain consistency
      6
      Model / domain consistency can be maintained via …
      Content Model + Integrity Checker
      formal model definition
      including built-in constraints
      option to also write & plug-in custom constraints (not specifically covered here)
      Behaviours
      custom business logic bound to policies
      Rules & Actions
      not covered here … see separate session
    • 8. Modelling
      7
      [something] used as an example to follow or imitate
      to make [something] conform to a chosen standard
    • 9. Modelling overview – Content Models
      8
      Content models
      are all about metadata (data that describes data)
      constrain otherwise arbitrary nodes, properties and associations
      are named and define one or more namespaces
      can import namespaces in order to allow references to other models
      must be configured and loaded in dependent order
      “bootstrap” models are statically loaded from the filesystem (“extensions” classpath) when repo starts
      “dynamic” models are dynamically loaded from the repo (“Models” space) when models are added or changed
      integrity checks fire when transaction commits
      mandatory can be enforced (else node is marked as incomplete)
    • 10. Modelling overview – Services
      9
      Get def’ (or all QNames)
      model
      types / aspect
      property
      datatype
      constraint
      association
      also: is sub-class ?
      Also refers to
      QName
      NamespaceService (prefix resolver)
      Dictionary Service
      Nodes
      create, move, delete, restore
      Properties
      set, get, remove
      Associations
      create, remove,
      get sources, get targets
      Child Associations
      get children, get parents
      get primary parent
      Node Service
    • 11. Modelling overview - M2 (meta-)model
      10
      Aspect
      Type
      Association
      Class
      Child Association
      Data Type
      Property
      Constraint
    • 12. Modelling overview – M2 (meta-)model
      11
      modelSchema.xsd
      Imports
      Namespaces
      Data-types
      Constraints
      Types / Aspects
      Properties
      Constraints
      Associations
      Child Associations
      Summary
    • 13. Model components – Types & Aspects (Nodes)
      12
      Node
      must be of a given type when created
      can also setType (ie. specialise / change type)
      may have zero or more aspects attached
      either from type or at runtime
      may have a set of properties
      defined by type & aspects (including inherited types & aspects)
      may be associated with other nodes
      defined by type & aspects (including inherited types & aspects)
    • 14. Model components – Properties
      13
      Property
      must be named
      must be of a given datatype
      may be single-valued (default) or multi-valued
      may have zero or more constraints (inline or referenced)
      may be mandatory
      either: enforced
      or: relaxed (if missing, node marked with incomplete aspect)
      may have default value
      may be “residual”
      in this case there is no associated property definition
      can be overridden in terms of inheritance
      to a limited extent – mandatory, default, constraints
    • 15. Model components – Constraints
      14
      Built-in constraint types:
      LIST (“ListOfValuesConstraint)
      LENGTH (“StringLengthConstraint”)
      MINMAX (“NumericRangeConstraint”)
      REGEXP (“RegexConstraint”)
      Other examples, eg. RM caveats use:
      “RMListOfValuesConstraint” (extends “ListOfValuesConstraint”)
      You can hook in your own constraint implementations
      implement “Constraint” interface
      typically extend “AbstractConstraint”
      must have default constructor (as it’s used to instantiate it)
      in model, define constraint with “type” attribute set to fully-qualified class name
      make sure you unit test your constraint (it is performance sensitive)
      Constraints execute
      as part of integrity checks prior to commit (ie. at the end of a server transaction)
    • 16. Model components – Associations (Peer)
      15
      (Peer) Association
      association type is named
      source node may be associated with zero or more target nodes
      may be mandatory
      enforced or relaxed (missing => node marked with incomplete aspect)
      cardinality can be defined via many / mandatory
      0 or 1(mandatory = false, many = false)
      1 (mandatory = true, many = false)
      0 or more (mandatory = false, many = true)
      1 or more (mandatory = true, many = true)
    • 17. Model components – Child Associations
      16
      Child Association
      defined in same way as peer association with extra features
      parent node may be associated with zero or more child nodes
      affects certain operations, eg. delete will cascade
      also defines if child name can be duplicated or unique within parent
      a node can have one primary child association
      a node may have one or more secondary child associations
    • 18. Model components – Admin Node Browser
      17
      Don’t forget “the Node Browser is your friend !”
      in theory never lies …
      … although be careful with browser back button (JSF issue)
    • 19. Model components – some changes since 3.x
      18
      Dynamic models
      since 3.0
      reduces need for server restart, also enables multi-tenancy option
      CMIS mapping
      CMIS type, CMIS property, CMIS relationship (peer assoc)
      CMIS document (cm:content), CMIS folder (cm:folder)
      Constraints support title & description (needed by RM)
      since 3.2
      Tightened validation check for content models
      since 3.4
      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)
      with the recent bug fix, it is now only possible to create model elements whose namespace is also defined by the containing model
      “DataModel” split out from “Repository”
      since 3.4
      split into separate JAR / Eclipse project – for future SOLR integration
    • 20. Model components – example
      19
      sys:referenceable
      • sys:store-protocol
      • 21. sys:store-identifier
      • 22. sys:node-uuid
      • 23. sys:node-dbid
      sys:base
      cm:auditable
      cm:cmobject
      - cm:name
      cm:folder
      cm:content
    • 27. Example – custom model
      20
      cm:folder
      cm:content
      my:customBaseFolder
      my:customBaseAspect
      my:customBaseContent
      my:customContent
      my:customSubFolder
      my:customSubAspect
    • 28. Model demo – Sample XMI generator
      21
      … more here …
      Map<String, Object> fmModel = new HashMap<String, Object>();
      fmModel.put("prefixDelimiter", prefixDelimiter);
      fmModel.put("classes", allM2Classes);
      fmModel.put("datatypes", datatypes);
      Configuration cfg = new Configuration();
      cfg.setObjectWrapper(ObjectWrapper.DEFAULT_WRAPPER);
      String userDir = System.getProperty("user.dir");
      cfg.setDirectoryForTemplateLoading(newFile(userDir+"/source/test-resources/SimpleXMI"));
      // UML 1.4 / XMI 1.2 - suitable for ArgoUML (eg. 0.30.2)
      Template temp = cfg.getTemplate("simple-Xmi1.2-Uml1.4.ftl");
      File f = new File(userDir, "simpleXMI-"+System.currentTimeMillis()+".xmi");
      Writer out = new FileWriter(f);
      temp.process(fmModel, out);
      out.flush();
      out.close();
      … more here …
      GenSimpleXMIFromModel.java (extract)
      … more here …
      <#list datatypesas datatype>
      <#assign split=datatype.name?index_of(":")>
      <UML:DataTypexmi.id = 'id-datatype:${datatype.name}'
      name = '${datatype.name?substring(split+1)}'isSpecification= 'false' isRoot = 'false' isLeaf = 'false'
      isAbstract= 'false'/>
      </#list>
      <#list classes as class>
      <UML:Classxmi.id = 'id-class:${class.name}'
      name = '${class.name?replace(":",prefixDelimiter)}’ isSpecification= 'false' isRoot = 'false'
      isLeaf= 'false' isAbstract = 'false' isActive = 'false'>
      <#if class.isAspect() == true >
      <UML:ModelElement.stereotype>
      <UML:Stereotypexmi.idref = 'id-stereotype:aspect'/>
      </UML:ModelElement.stereotype>
      <#else>
      … more here …
      simple-Xmi1.2-Uml1.4.ftl (extract)
    • 29. Model examples –DevCon sample
      22
    • 30. Model examples – Web Quick Start (WQS)
      23
    • 31. Model examples – many “OOTB”
      24
      Many examples “out-of-the-box”
      Search for “*Model.xml” across the Alfresco source tree
      Core model files (with defined namespaces) include:
      dictionaryModel.xml
      http://www.alfresco.org (alf)
      http://www.alfresco.org/model/dictionary/1.0 (d)
      http://www.alfresco.org/view/repository/1.0 (view)
      systemModel.xml
      http://www.alfresco.org/model/system/1.0 (sys)
      http://www.alfresco.org/system/registry/1.0 (reg)
      http://www.alfresco.org/system/modules/1.0 (module)
      contentModel.xml
      http://www.alfresco.org/model/content/1.0 (cm)
      http://www.alfresco.org/model/rendition/1.0 (rn)
      http://www.alfresco.org/model/exif/1.0 (exif)
    • 32. Model examples – modules (eg. RM, WQS)
      25
      Alfresco modules also provide some great examples, eg.
      Records Management (RM / DOD5015)
      dod5015Model.xml
      http://www.alfresco.org/model/dod5015/1.0 (dod)
      recordsCustomModel.xml (dynamically managed)
      http://www.alfresco.org/model/rmcustom/1.0 (rmc)
      Web Quick Start (WQS)
      webSiteModel.xml
      http://www.alfresco.org/model/website/1.0 (ws)
    • 33. Behaviours
      26
      the way in which [something] behaves in response to a particular situation or stimulus
    • 34. Behaviours overview – policy + behaviour
      27
      Policies provide hook points to which you can bind behaviours to events based on class or association
      behaviours are (policy) handlers that execute specific business logic
      behaviours can be implemented in Java and/or JavaScript
      Behaviours can be bound to a type or aspect
      node in the content repository must be of a single type
      node may have one or more aspects attached
      aspects are either inherited from its type (defined by the model)
      or can be attached (or detached) at runtime …
      allowing a node to dynamically inherit features and capabilities
      aspects can be interpreted by the repository to change behaviour
      eg. by the presence of an aspect (even with no properties)
    • 35. Behaviours overview – policy component
      28
      From JavaDoc (org.alfresco.repo.policy) …
      The Policy Component manages Policies and Behaviours. It provides the
      ability to:
      a) Register policies
      b) Bind behaviours to policies
      c) Invoke policy behaviours
      A behaviour may be bound to a Policy before the Policy is registered. In
      this case, the behaviour is not validated (i.e. checked to determine if it
      Supports the policy interface) until the Policy is registered. Otherwise,
      the behaviour is validated at bind-time.
      Policies may be selectively "turned off" by the Behaviour Filter.
    • 36. Behaviour components – behaviour interface
      29
      Behaviour
      BaseBehaviour
      JavaBehaviour
      ScriptBehaviour
    • 37. Behaviour components – policy interface
      30
      Policy
      ClassPolicy (type or aspect)
      AssociationPolicy (peer or parent-child)
      PropertyPolicy (not used)
    • 38. Behaviour components – some OOTB policies
      31
      Search for “*Policies.java” across the Alfresco source tree
      Examples include:
      NodeServicePolicies
      before/onCreateNode,
      beforeDeleteNode (don’t use “on”)
      before/onUpdateNode
      onUpdateProperties
      before/onAddAspect
      before/onRemoveAspect
      before/onCreateChildAssociation
      before/onDeleteChildAssocation
      onCreateAssociation
      onDeleteAssociation
      ….
      ContentServicePolicies
      onContentUpdate
      onContentPropertyUpdate
    • 39. Behaviour components - other policy examples
      32
      CopyServicePolicies
      before/onCopy
      onCopyComplete
      CheckOutCheckInServicePolicies
      before/OnCheckOut
      before/OnCheckIn
      before/OnCancelCheckOut
      And more …
      VersionServicePolicies
      StoreSelectorPolicies
      AsynchronousActionExecutionQueuePolicies
      RecordsManagementPolicies
      Note: you can define, register and invoke you own custom policies, eg.
      RecordsManagementPolicies <= RecordsManagementActionServiceImpl
    • 40. Behaviour components – register & invoke
      33
      public interface NodeServicePolicies
      {
      public interface OnAddAspectPolicy extends ClassPolicy
      {
      public static final QName QNAME = QName.createQName(NamespaceService.ALFRESCO_URI, "onAddAspect");
      // Called after an <b>aspect</b> has been added to a node
      public void onAddAspect(NodeRefnodeRef, QNameaspectTypeQName);
      }
      }
      public abstract class AbstractNodeServiceImpl implements NodeService
      {
      // note: policyComponent is injected … (not shown here)
      public void init()
      {
      // Register the policy
      onAddAspectDelegate = policyComponent.registerClassPolicy
      (NodeServicePolicies.OnAddAspectPolicy.class);
      }
      protected void invokeOnAddAspect(NodeRefnodeRef, QNameaspectTypeQName)
      {
      NodeServicePolicies.OnAddAspectPolicy policy = onAddAspectDelegate.get(nodeRef, aspectTypeQName);
      policy.onAddAspect(nodeRef, aspectTypeQName);
      }
      }
    • 41. Behaviour components – bind & implement
      34
      public class XyzAspect implements NodeServicePolicies.OnAddAspectPolicy, ...
      {
      // note: policyComponent is injected … (not shown here)
      public void init()
      {
      // bind to the policy
      policyComponent.bindClassBehaviour(
      OnAddAspectPolicy.QNAME,
      ContentModel.ASPECT_XYZ,
      new JavaBehaviour(this, "onAddAspect”,
      Behaviour.NotificationFrequency.TRANSACTION_COMMIT));
      }
      public void onAddAspect(NodeRefnodeRef, QNameaspectTypeQName)
      {
      // implement behaviour here … (for when aspect XYZ is added)
      }
      }
    • 42. Behaviour components – class vs service binding
      35

      //
      // note: usually try to bind on specific class (type/aspect) rather than service method
      //
      // class binding – specific type or aspect
      policyComponent.bindClassBehaviour(
      NodeServicePolicies.OnUpdatePropertiesPolicy.QNAME,
      ContentModel.TYPE_PERSON,
      new JavaBehaviour(this,
      "onUpdateProperties”,
      Behaviour.NotificationFrequency.EVERY_EVENT));
      // service binding – all types/aspects
      policyComponent.bindClassBehaviour(
      NodeServicePolicies.OnUpdatePropertiesPolicy.QNAME,
      this,
      new JavaBehaviour(this,
      "onUpdateProperties”,
      Behaviour.NotificationFrequency.EVERY_EVENT));

    • 43. Behaviour components - handle now or later
      36
      Notification Frequency
      behaviours can be defined with a notification frequency – “every event” (default), “first event”, “transaction commit”
      consider that during a given transaction, certain policies may fire multiple times (ie. “every event”)
      can set notification frequency to “first event” or “transaction commit”
      Using Transactional Resource
      option to execute logic immediately or queue (eg. via transactional resource) until commit (beforeCommit and/or afterCommit)
      AlfrescoTransactionSupport.bindResource(K, V)
      V = AlfrescoTransactionSupport.getResource(K)
    • 44. Behaviour components – disable / (re-)enable
      37
      Behaviours can be temporarily disabled
      BehaviourFilterinterface
      for current transaction only
      for “class” (type or aspect) or “node + class”
      disableBehaviour
      enableBehaviour
      isEnabled
      for “node”
      enableBehaviours
      for “all”
      disableAllBehaviours
      enableAllBehaviours
      isActivated
      Behaviour interface
      for current thread only
      disable / enable, eg. in try / finally block
      Examples – importer, transfer – disable behaviours
    • 45. Behaviour components - delete is delete !
      38
      • From the perspective of the custom behaviour
      delete is delete (you should not need to care whether it is archived)
      create is create (even if it is restored from the archive)
      • Bind to beforeDeleteNode (not onDeleteNode)
      note: will fire for parent and recursively for each of it’s cascade deleted children (if any)
      • Don’t rely (or be dependent) on the archive store
      deleted node may not be archived
      archived node may never be restored
      you should not need to check for archive store
      • One exception is peer associations
      assocs to “archived” nodes may remain (pending ALF-4119 for 3.4+)
    • 46. Behaviour components - delete is delete ! (cont)
      39
      “live” store
      “archive” store
      deleteNode
      (purgeArchivedNode)
      deleteNode
      restoreNode
      archive://SpacesStore
      version://version2Store
      workspace://SpacesStore
      deleteNode
      “version” store
      createVersion
      deleteVersion
      deleteVersionHistory
    • 47. Behaviour components – some changes in 3.x
      40
      More than one handler can be registered for a given policy
      since 3.0
      We now also trigger policies through the type hierarchy
      since 3.4
      if you use earlier Alfresco and yet to upgrade then workaround is to bind to service bind and use “isSubClassOf” to check type
      You should not need to check for archive store
      since 3.3
      operations on archive store no longer fire polices
      also applies to version store
    • 48. Example behaviours - more
      41
      Search through the code for policy bindings or use Eclipse to find call hierarchy for
      bindClassBehaviour (x2)
      bindAssociationBehaviour (x3)
      Many examples both in core services as well as module extensions such as
      Web Quick Start
      http://wiki.alfresco.com/wiki/Web_Quick_Start_Developer_Guide#Behaviours
      DOD 5015 (Records Management)
      You can refer to the SDK for a simple example
      Also, for JavaScript Behaviours, refer to *old* RM module
    • 49. Modelling & Behaviours – some general tips
      42
      Modelling
      consider using dynamic models during dev & test cycles
      beware of deep class hierarchies
      consider performance of any custom registered constraints
      Behaviours
      consider notification frequency
      add debug logging
      don’t rely on archive store
      can temporarily disable/re-enable (thread or transaction)
      General
      start with the SDK and if needed move to complete SVN source tree
      write unit tests (+ve & -ve) to exercise custom models & behaviours
      run existing regression tests (eg. “ant test-repository” or continuous)
      develop and package as an AMP (Alfresco Module Package)
    • 50. Past, present and future
      43
      Modelling
      integrity checks do not apply to version store
      data model has been split off (eg. for future SOLR integration)
      now only possible to create model elements whose namespace is also defined by the containing model
      composite content (anticipated for Project “Swift”)
      major model enhancement
      will also impact various foundation services
      see wiki for more details (early draft - subject to change)
      Behaviours
      more than one handler can be registered for a policy
      policies do not fire for archive store & version store
      policies are now triggered through the type hierarchy
      maybe some consolidation & rationalisation
      also potentially new policies (to hook into)
    • 51. References & examples
      44
      Alfresco wiki / forums
      Books
      Professional Alfresco (Wrox)
      Alfresco Developer Guide (Packt Publishing)
      Alfresco Training courses
      Intensive Developers Course (5 day)
      Fundamentals (2 day) – new
      Advanced Content Modelling – TBC
      and obviously the source code itself 
      including modules, such as RM (DOD 5015)
    • 52. Feedback … Q & A
      45
    • 53. Learn More
      46
      wiki.alfresco.com
      forums.alfresco.com
      twitter: @AlfrescoECM
    • 54. Another Code Sample (Screenshot)
      47
    • 55. 48
      Shape & Color Pallette
      Normal Text
      Normal Text
      Normal Text
    • 56. 49
    • 57. Content Model ex1 – model, import, namespace
      50
      <?xml version="1.0" encoding="UTF-8"?>
      <model name="cm:contentmodel"
      xmlns="http://www.alfresco.org/model/dictionary/1.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <description>Alfresco Content Domain Model</description>
      <author>Alfresco</author>
      <published>2009-06-04</published>
      <version>1.1</version>
      <imports>
      <import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
      <import uri="http://www.alfresco.org/model/system/1.0" prefix="sys"/>
      </imports>
      <namespaces>
      <namespace uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
      <namespace uri="http://www.alfresco.org/model/rendition/1.0" prefix="rn"/>
      <namespace uri="http://www.alfresco.org/model/exif/1.0" prefix="exif"/>
      </namespaces>
    • 58. Content Model ex2 - type, property, constraint
      51
      <type name="cm:cmobject">
      <title>Object</title>
      <parent>sys:base</parent>
      <properties>
      <property name="cm:name">
      <title>Name</title>
      <type>d:text</type>
      <mandatory enforced="true">true</mandatory>
      <index enabled="true">
      <atomic>true</atomic>
      <stored>false</stored>
      <tokenised>both</tokenised>
      </index>
      <constraints>
      <constraint ref="cm:filename" />
      </constraints>
      </property>
      </properties>
      <mandatory-aspects>
      <aspect>cm:auditable</aspect>
      </mandatory-aspects>
      </type>
    • 59. Content Model ex3 – child assoc …
      52
      <type name="cm:folder">
      <title>Folder</title>
      <parent>cm:cmobject</parent>
      <archive>true</archive>
      <associations>
      <child-association name="cm:contains">
      <source>
      <mandatory>false</mandatory>
      <many>true</many>
      </source>
      <target>
      <class>sys:base</class>
      <mandatory>false</mandatory>
      <many>true</many>
      </target>
      <duplicate>false</duplicate>
      <propagateTimestamps>true</propagateTimestamps>
      </child-association>
      </associations>
      </type>

    ×