cancel
Showing results for 
Search instead for 
Did you mean: 
resplin
Elite Collaborator
Elite Collaborator

Obsolete Pages{{Obsolete}}

The official documentation is at: http://docs.alfresco.com



Content Modeling


Constraints


Defining Constraints in the Model


The following comes from the dictionary test model, dictionarydaotest_model.xml, and shows the built-in constraints currently implemented.

<model name='test:dictionarydaotest' xmlns='http://www.alfresco.org/model/dictionary/1.0'>
...
  <imports>
...
  </imports>
  <namespaces>
...
  </namespaces>
  <data-types>
...
  </data-types>
  <constraints>
     <constraint name='test:regex1' type='REGEX'>
        <parameter name='expression'><value>[A-Z]*</value></parameter>
        <parameter name='requiresMatch'><value>false</value></parameter>
     </constraint>
     <constraint name='test:regex2' type='REGEX'>
        <parameter name='expression'><value>[a-z]*</value></parameter>
        <parameter name='requiresMatch'><value>false</value></parameter>
     </constraint>
     <constraint name='test:stringLength1' type='LENGTH'>
        <parameter name='minLength'><value>0</value></parameter>
        <parameter name='maxLength'><value>256</value></parameter>
     </constraint>
     <constraint name='test:stringLength2' type='LENGTH'>
        <parameter name='minLength'><value>0</value></parameter>
        <parameter name='maxLength'><value>128</value></parameter>
     </constraint>
     <constraint name='test:minMax1' type='MINMAX'>
        <parameter name='minValue'><value>0</value></parameter>
        <parameter name='maxValue'><value>256</value></parameter>
     </constraint>
     <constraint name='test:list1' type='LIST'>
        <parameter name='allowedValues'>
            <list>
                <value>ABC</value>
                <value>DEF</value>
            </list>
        </parameter>
        <parameter name='caseSensitive'><value>true</value></parameter>
     </constraint>
  </constraints>
...

These constraints can be referenced in the property definitions:

...
           <property name='test:prop1'>
              <type>d:text</type>
              <protected>true</protected>
              <default></default>
              <constraints>
                 <constraint ref='test:regex1'/>
                 <constraint ref='test:stringLength1'/>
              </constraints>
           </property>
...

Further constraints can be defined inline as well, but are not reusable:

...
           <property name='test:prop1'>
              <type>d:text</type>
              <protected>true</protected>
              <default></default>
              <constraints>
                 <constraint ref='test:regex1'/>
                 <constraint type='LENGTH'>
                    <parameter name='minLength'><value>0</value></parameter>
                    <parameter name='maxLength'><value>128</value></parameter>
                 </constraint>
              </constraints>
           </property>
...

The built-in constraints are present in the package org.alfresco.repo.dictionary.constraint and are:


  • REGEX    org.alfresco.repo.dictionary.constraint.RegexConstraint
  • LENGTH   org.alfresco.repo.dictionary.constraint.StringLengthConstraint
  • MINMAX   org.alfresco.repo.dictionary.constraint.NumericRangeConstraint
  • LIST     org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint

The <parameter> definitions correspond directly to setter methods on the classes.

When defining a derived type and overriding a property, the constraints for the property can also be overridden.


Writing Further Constraints


Apart from the built-in constraints that are recognised by the dictionary model parser, further constraints can be added.  Implementations need only implement the org.alfresco.service.cmr.dictionary.Constraint interface.  Typically, constraints will extend org.alfresco.repo.dictionary.constraint.AbstractConstraint.  See the test class org.alfresco.repo.dictionary.constraint.ConstraintsTest for examples of how the constraints can be tested.  Note: your custom constraint needs to have a default constructor, as it's used to instantiate it.

To define the constraint in the model, put the fully qualified class name in the type attribute.  For example, assume a constraint that only allows multiples of a given number:

...
     <constraint name='my:FactorsOf' type='com.company.alfresco.constraints.MultiplesOfConstraint'>
        <parameter name='multipleOf'><value>10</value></parameter>
     </constraint>
...

In your class, you define the parameters you need using the method getParameters:

   private Integer multipleOf;

   @Override
   public Map<String, Object> getParameters()
   {
       Map<String, Object> params = new HashMap<String, Object>(2);
      
       params.put('multipleOf', this.multipleOf);
      
       return params;
   }



If you do not want to use any parameters, you still have to define this method to return an empty map

   @Override
   public Map<String, Object> getParameters()
   {
       return new HashMap<String, Object>();
   }

and then obviously define your constraint in your model accordingly:

...
     <constraint name='my:validPostCode' type='com.company.alfresco.constraints.ValidPostCodeConstraint' />
...

Constraint Execution


Constraint checks are applied during integrity checks, typically at the end of a transaction within the server.  All clients are therefore forced to ensure that the constraints are met.  How the constraints are enforced varies from client to client.  When setting a constraint against a property, it is worth considering how the various repository clients will enforce the constraints.

In the default model, for example, the cm:name property is over-constrained by the REGEX constraint for certain clients - but has to ensure conformance across WebDAV, CIFS, FTP and the Alfresco Web Client.  If some of these clients are not being used, then the constraints can be relaxed accordingly.

The Alfresco Web Application UI has built-in javascript translation to enforce constraints on the browser clients for the built-in types.  See org.alfresco.web.bean.generator.BaseComponentGenerator for more examples.