cancel
Showing results for 
Search instead for 
Did you mean: 

Custom type , using aspects with mandatory fields

ranjeetsi
Star Contributor
Star Contributor

Hi ,

Have a question: 

For the custom types having a mandatory aspect applied. 

a) How can a propery of an aspect be made mandatory for one custom type but can be optional for another custom type.

For eg: an approvable aspect has a property "needsApproval".

Both custom type "employee" and "Director" has mandatory aspect approvable,

a) Can "employee" has "needsApproval" as mandatory but "Director" has "needsApproval" as optional property?

b) If there is any other way - like making optional at aspect but mandatory at custom type ? by some means?

Please suggest. Appreciate any help!

Alfresco Content Services Certified Engineer (ACSCE)
3 ACCEPTED ANSWERS

abhinavmishra14
World-Class Innovator
World-Class Innovator

The way content model aspects are designed to work, i don't think it is possible to have a property on an aspect (meant to have a property that can be re-used) as mandatory for one type and same property as optional for other type from content model standpoint. 

Aspects “cross-cut” the content model with properties and associations by attaching them to content types (or even specific instances of content) when and where they are needed.

However here are some workarounds which may work for your use case if these are options for you:

1- Keep the property in the aspect as optional by default (don't set mandatory element value to true and don't enforce) at content model level and set the aspect as mandatory aspect on both types (employee and director), and make use of behaviors as you get better control over node.

      a - Create a java behavior on NodeServicePolicies.OnCreateNodePolicy.

      b- Bind the behavior on employee and director types.

      c- onCreateNode event allow the creation of node of employee type only when "needsApproval" property has a value (property is set) and abort the node creation if value is not set. For director type of node pass on the node creation without the mandatory check since you want to have the property as optional.

2- Use folder rules and run a script from rules that will check the type of node and also check whether the required property is set, if its allowed then pass on else throw error. This approach also requires to keep the property in the aspect as optional by default at content model level and set the aspect as mandatory aspect on both types (employee and director)

3- Don't use the property via aspect and instead create a property on one type (e.g. employee type) with mandatory attributes set and create a different property for other type (e.g. director) where you want to keep it optional.

~Abhinav
(ACSCE, AWS SAA, Azure Admin)

View answer in original post


@ranjeetsi wrote:

Thanks Eddie,

Hi @abhinavmishra14 

Thanks for your solutions/options: I have a followup question though:  (Link below) where the overrides can also resolve this?

https://docs.alfresco.com/6.2/concepts/metadata-model-inheritance.html

https://docs.alfresco.com/6.2/concepts/metadata-model-aspects.html

(mandatory: A subtype can enforce a property to become mandatory but it cannot relax an existing parent mandatory constraint.)

Also - if this can be done via aspect . Can have the parent aspect with some non-mandatory property and child aspect can have the same as mandatory? will it work?


@ranjeetsi Indeed, i missed this part. I am glad you opened up this topic.

I think the way 'overriding' of properties works you may be able to achieve your use case. You can only override the default value, mandatory parameter, and constraints definitions for a property. So looks like you have another option to try. 

Note that, if you have configured to create document types from share create menu (i.e. on model-type), you would  have to provide the property on the form and show mandatory indicator via share config.

Here is an example to try for you:

<aspects>
<aspect name="demo:approvable">
	<title>Approvable</title>
	<description>Approvable</description>
	<properties>
		<property name="demo:needsApproval">
			<title>Needs Approval</title>
			<description>Needs Approval</description>
			<type>d:text</type>
			<mandatory enforced="false">false</mandatory>
		</property>
	</properties>
</aspect>

<aspect name="demo:approvableDirectorLevel">
	<title>Approvable DirectorLevel</title>
	<description>Approvable DirectorLevel</description>
	<parent>demo:approvable</parent>
	<overrides>
		<property name="demo:needsApproval">
			<mandatory enforced="false">true</mandatory>
		</property>
	</overrides>
</aspect>

<aspect name="demo:approvableEmployeeLevel">
	<title>Approvable EmployeeLevel</title>
	<description>Approvable EmployeeLevel</description>
	<parent>demo:approvable</parent>
	<overrides>
		<property name="demo:needsApproval">
			<mandatory enforced="true">true</mandatory>
		</property>
	</overrides>
</aspect>
</aspects>

<types>
	<type name="demo:directorDoc">
		<title>Director level document</title>
		<description>Director level document</description>
		<parent>cm:content</parent>
		<mandatory-aspects>
			<aspect>demo:approvableDirectorLevel</aspect>
		</mandatory-aspects>
	</type>
	<type name="demo:employeeDoc">
		<title>Employee level document</title>
		<description>Employee level document</description>
		<parent>cm:content</parent>
		<mandatory-aspects>
			<aspect>demo:approvableEmployeeLevel</aspect>
		</mandatory-aspects>
	</type>
</types>
~Abhinav
(ACSCE, AWS SAA, Azure Admin)

View answer in original post

Great that solution worked for you.

If you read the documentation carefully it clearly says you can't modify existing constraint. You can add additional constraints. This rule applies to type and aspects both.

However you can do this with overriding, you can't have one list constraint in parent and override with other in child:

<aspect name="demo:approvable">
	<title>Approvable</title>
	<description>Approvable</description>
	<properties>
		<property name="demo:needsApproval">
			<title>Needs Approval</title>
			<description>Needs Approval</description>
			<type>d:text</type>
			<mandatory enforced="false">false</mandatory>
		</property>
	</properties>
</aspect>

<aspect name="demo:approvableDirectorLevel">
	<title>Approvable DirectorLevel</title>
	<description>Approvable DirectorLevel</description>
	<parent>demo:approvable</parent>
	<overrides>
		<property name="demo:needsApproval">
			<mandatory enforced="false">true</mandatory>
			<constraints>
				<constraint name="demo:categoryList"
				            type="LIST">
					<parameter name="allowedValues">
						<list>
							<value>Y</value>
							<value>N</value>
						</list>
					</parameter>
				</constraint>
			</constraints>
		</property>
		
	</overrides>
</aspect>

<aspect name="demo:approvableEmployeeLevel">
	<title>Approvable EmployeeLevel</title>
	<description>Approvable EmployeeLevel</description>
	<parent>demo:approvable</parent>
	<overrides>
		<property name="demo:needsApproval">
			<mandatory enforced="true">true</mandatory>
			<constraints>
				<constraint name="demo:categoryList"
				            type="LIST">
					<parameter name="allowedValues">
						<list>
							<value>Required</value>
							<value>Not required</value>
						</list>
					</parameter>
				</constraint>
			</constraints>
		</property>
	</overrides>
</aspect>

If you want to have different constraint lists in child (types/aspects) then parent must not have a constraint list already defined, else you would get error possibly 'Integrity violation error'.

Another example of overriding property with constraints:

<aspect name="demo:approvable">
	<title>Approvable</title>
	<description>Approvable</description>
	<properties>
		<property name="demo:needsApproval">
			<title>Needs Approval</title>
			<description>Needs Approval</description>
			<type>d:text</type>
			<mandatory enforced="false">false</mandatory>
			<constraints>
				<constraint name="demo:lengthConstraint" type="LENGTH">
					<parameter name="minLength"><value>0</value></parameter>
					<parameter name="maxLength"><value>12</value></parameter>
				</constraint>
			</constraints>
		</property>
	</properties>
</aspect>

<aspect name="demo:approvableDirectorLevel">
	<title>Approvable DirectorLevel</title>
	<description>Approvable DirectorLevel</description>
	<parent>demo:approvable</parent>
	<overrides>
		<property name="demo:needsApproval">
			<mandatory enforced="false">true</mandatory>
			<constraints>
				<constraint name="demo:categoryList"
				            type="LIST">
					<parameter name="allowedValues">
						<list>
							<value>Y</value>
							<value>N</value>
						</list>
					</parameter>
				</constraint>
			</constraints>
		</property>
		
	</overrides>
</aspect>

<aspect name="demo:approvableEmployeeLevel">
	<title>Approvable EmployeeLevel</title>
	<description>Approvable EmployeeLevel</description>
	<parent>demo:approvable</parent>
	<overrides>
		<property name="demo:needsApproval">
			<mandatory enforced="true">true</mandatory>
			<constraints>
				<constraint name="demo:categoryList"
				            type="LIST">
					<parameter name="allowedValues">
						<list>
							<value>Required</value>
							<value>Not required</value>
						</list>
					</parameter>
				</constraint>
			</constraints>
		</property>
	</overrides>
</aspect>
~Abhinav
(ACSCE, AWS SAA, Azure Admin)

View answer in original post

7 REPLIES 7

abhinavmishra14
World-Class Innovator
World-Class Innovator

The way content model aspects are designed to work, i don't think it is possible to have a property on an aspect (meant to have a property that can be re-used) as mandatory for one type and same property as optional for other type from content model standpoint. 

Aspects “cross-cut” the content model with properties and associations by attaching them to content types (or even specific instances of content) when and where they are needed.

However here are some workarounds which may work for your use case if these are options for you:

1- Keep the property in the aspect as optional by default (don't set mandatory element value to true and don't enforce) at content model level and set the aspect as mandatory aspect on both types (employee and director), and make use of behaviors as you get better control over node.

      a - Create a java behavior on NodeServicePolicies.OnCreateNodePolicy.

      b- Bind the behavior on employee and director types.

      c- onCreateNode event allow the creation of node of employee type only when "needsApproval" property has a value (property is set) and abort the node creation if value is not set. For director type of node pass on the node creation without the mandatory check since you want to have the property as optional.

2- Use folder rules and run a script from rules that will check the type of node and also check whether the required property is set, if its allowed then pass on else throw error. This approach also requires to keep the property in the aspect as optional by default at content model level and set the aspect as mandatory aspect on both types (employee and director)

3- Don't use the property via aspect and instead create a property on one type (e.g. employee type) with mandatory attributes set and create a different property for other type (e.g. director) where you want to keep it optional.

~Abhinav
(ACSCE, AWS SAA, Azure Admin)

Thanks Eddie,

Hi @abhinavmishra14 

Thanks for your solutions/options: I have a followup question though:  (Link below) where the overrides can also resolve this?

https://docs.alfresco.com/6.2/concepts/metadata-model-inheritance.html

https://docs.alfresco.com/6.2/concepts/metadata-model-aspects.html

(mandatory: A subtype can enforce a property to become mandatory but it cannot relax an existing parent mandatory constraint.)

Also - if this can be done via aspect . Can have the parent aspect with some non-mandatory property and child aspect can have the same as mandatory? will it work?

Alfresco Content Services Certified Engineer (ACSCE)


@ranjeetsi wrote:

Thanks Eddie,

Hi @abhinavmishra14 

Thanks for your solutions/options: I have a followup question though:  (Link below) where the overrides can also resolve this?

https://docs.alfresco.com/6.2/concepts/metadata-model-inheritance.html

https://docs.alfresco.com/6.2/concepts/metadata-model-aspects.html

(mandatory: A subtype can enforce a property to become mandatory but it cannot relax an existing parent mandatory constraint.)

Also - if this can be done via aspect . Can have the parent aspect with some non-mandatory property and child aspect can have the same as mandatory? will it work?


@ranjeetsi Indeed, i missed this part. I am glad you opened up this topic.

I think the way 'overriding' of properties works you may be able to achieve your use case. You can only override the default value, mandatory parameter, and constraints definitions for a property. So looks like you have another option to try. 

Note that, if you have configured to create document types from share create menu (i.e. on model-type), you would  have to provide the property on the form and show mandatory indicator via share config.

Here is an example to try for you:

<aspects>
<aspect name="demo:approvable">
	<title>Approvable</title>
	<description>Approvable</description>
	<properties>
		<property name="demo:needsApproval">
			<title>Needs Approval</title>
			<description>Needs Approval</description>
			<type>d:text</type>
			<mandatory enforced="false">false</mandatory>
		</property>
	</properties>
</aspect>

<aspect name="demo:approvableDirectorLevel">
	<title>Approvable DirectorLevel</title>
	<description>Approvable DirectorLevel</description>
	<parent>demo:approvable</parent>
	<overrides>
		<property name="demo:needsApproval">
			<mandatory enforced="false">true</mandatory>
		</property>
	</overrides>
</aspect>

<aspect name="demo:approvableEmployeeLevel">
	<title>Approvable EmployeeLevel</title>
	<description>Approvable EmployeeLevel</description>
	<parent>demo:approvable</parent>
	<overrides>
		<property name="demo:needsApproval">
			<mandatory enforced="true">true</mandatory>
		</property>
	</overrides>
</aspect>
</aspects>

<types>
	<type name="demo:directorDoc">
		<title>Director level document</title>
		<description>Director level document</description>
		<parent>cm:content</parent>
		<mandatory-aspects>
			<aspect>demo:approvableDirectorLevel</aspect>
		</mandatory-aspects>
	</type>
	<type name="demo:employeeDoc">
		<title>Employee level document</title>
		<description>Employee level document</description>
		<parent>cm:content</parent>
		<mandatory-aspects>
			<aspect>demo:approvableEmployeeLevel</aspect>
		</mandatory-aspects>
	</type>
</types>
~Abhinav
(ACSCE, AWS SAA, Azure Admin)

Thanks @abhinavmishra14 ,

Sure , i just had used the approach and it works for my use case.

One more question may be last on this topic:

I need the constraints to be overriden as well and the lists swapped for the child custom types . How can i do that - trying to find some link of trhe code.

For eg 

Parent Type impdoc has a property sub docs which refers to get value from constraints 

a) Child Custom type timedoc will have some differenmt constraints

b)Child custom type speeddoc will have different constraint. 

How can use/implement this

extract from the link - https://docs.alfresco.com/6.2/concepts/metadata-model-inheritance.html

constraints: Additional constraints can be applied to a parent property, but existing constraints cannot be modified.

Alfresco Content Services Certified Engineer (ACSCE)

Great that solution worked for you.

If you read the documentation carefully it clearly says you can't modify existing constraint. You can add additional constraints. This rule applies to type and aspects both.

However you can do this with overriding, you can't have one list constraint in parent and override with other in child:

<aspect name="demo:approvable">
	<title>Approvable</title>
	<description>Approvable</description>
	<properties>
		<property name="demo:needsApproval">
			<title>Needs Approval</title>
			<description>Needs Approval</description>
			<type>d:text</type>
			<mandatory enforced="false">false</mandatory>
		</property>
	</properties>
</aspect>

<aspect name="demo:approvableDirectorLevel">
	<title>Approvable DirectorLevel</title>
	<description>Approvable DirectorLevel</description>
	<parent>demo:approvable</parent>
	<overrides>
		<property name="demo:needsApproval">
			<mandatory enforced="false">true</mandatory>
			<constraints>
				<constraint name="demo:categoryList"
				            type="LIST">
					<parameter name="allowedValues">
						<list>
							<value>Y</value>
							<value>N</value>
						</list>
					</parameter>
				</constraint>
			</constraints>
		</property>
		
	</overrides>
</aspect>

<aspect name="demo:approvableEmployeeLevel">
	<title>Approvable EmployeeLevel</title>
	<description>Approvable EmployeeLevel</description>
	<parent>demo:approvable</parent>
	<overrides>
		<property name="demo:needsApproval">
			<mandatory enforced="true">true</mandatory>
			<constraints>
				<constraint name="demo:categoryList"
				            type="LIST">
					<parameter name="allowedValues">
						<list>
							<value>Required</value>
							<value>Not required</value>
						</list>
					</parameter>
				</constraint>
			</constraints>
		</property>
	</overrides>
</aspect>

If you want to have different constraint lists in child (types/aspects) then parent must not have a constraint list already defined, else you would get error possibly 'Integrity violation error'.

Another example of overriding property with constraints:

<aspect name="demo:approvable">
	<title>Approvable</title>
	<description>Approvable</description>
	<properties>
		<property name="demo:needsApproval">
			<title>Needs Approval</title>
			<description>Needs Approval</description>
			<type>d:text</type>
			<mandatory enforced="false">false</mandatory>
			<constraints>
				<constraint name="demo:lengthConstraint" type="LENGTH">
					<parameter name="minLength"><value>0</value></parameter>
					<parameter name="maxLength"><value>12</value></parameter>
				</constraint>
			</constraints>
		</property>
	</properties>
</aspect>

<aspect name="demo:approvableDirectorLevel">
	<title>Approvable DirectorLevel</title>
	<description>Approvable DirectorLevel</description>
	<parent>demo:approvable</parent>
	<overrides>
		<property name="demo:needsApproval">
			<mandatory enforced="false">true</mandatory>
			<constraints>
				<constraint name="demo:categoryList"
				            type="LIST">
					<parameter name="allowedValues">
						<list>
							<value>Y</value>
							<value>N</value>
						</list>
					</parameter>
				</constraint>
			</constraints>
		</property>
		
	</overrides>
</aspect>

<aspect name="demo:approvableEmployeeLevel">
	<title>Approvable EmployeeLevel</title>
	<description>Approvable EmployeeLevel</description>
	<parent>demo:approvable</parent>
	<overrides>
		<property name="demo:needsApproval">
			<mandatory enforced="true">true</mandatory>
			<constraints>
				<constraint name="demo:categoryList"
				            type="LIST">
					<parameter name="allowedValues">
						<list>
							<value>Required</value>
							<value>Not required</value>
						</list>
					</parameter>
				</constraint>
			</constraints>
		</property>
	</overrides>
</aspect>
~Abhinav
(ACSCE, AWS SAA, Azure Admin)

Part2-

You can also create dynamic list for the property at run time to handle your use case with constraints.

Have a look at this solution: https://hub.alfresco.com/t5/alfresco-content-services-forum/can-we-give-dropdown-constraints-only-fo...

~Abhinav
(ACSCE, AWS SAA, Azure Admin)

EddieMay
World-Class Innovator
World-Class Innovator

Hi @ranjeetsi 

Thanks for accepting the solution - really helpful to other users.

Cheers,

Digital Community Manager, Alfresco Software.
Problem solved? Click Accept as Solution!