diff --git a/source/java/org/alfresco/repo/dictionary/CompiledModel.java b/source/java/org/alfresco/repo/dictionary/CompiledModel.java index c665de6596..382affaeb0 100644 --- a/source/java/org/alfresco/repo/dictionary/CompiledModel.java +++ b/source/java/org/alfresco/repo/dictionary/CompiledModel.java @@ -90,7 +90,14 @@ import org.apache.commons.logging.LogFactory; resolveDependencies(query, namespaceDAO); // Phase 3: Resolve inheritance of values within class hierachy - resolveInheritance(query); + NamespacePrefixResolver localPrefixes = createLocalPrefixResolver(model, namespaceDAO); + resolveInheritance(query, localPrefixes, constraints); + + // Phase 4: Resolve constraint dependencies + for (ConstraintDefinition def : constraints.values()) + { + ((M2ConstraintDefinition)def).resolveDependencies(query); + } } catch(Exception e) { @@ -220,10 +227,6 @@ import org.apache.commons.logging.LogFactory; { ((M2ClassDefinition)def).resolveDependencies(query, prefixResolver, constraints); } - for (ConstraintDefinition def : constraints.values()) - { - ((M2ConstraintDefinition)def).resolveDependencies(query); - } } @@ -232,7 +235,10 @@ import org.apache.commons.logging.LogFactory; * * @param query support for querying other items in model */ - private void resolveInheritance(ModelQuery query) + private void resolveInheritance( + ModelQuery query, + NamespacePrefixResolver prefixResolver, + Map modelConstraints) { // Calculate order of class processing (root to leaf) Map> order = new TreeMap>(); @@ -270,7 +276,7 @@ import org.apache.commons.logging.LogFactory; { for (ClassDefinition def : order.get(depth)) { - ((M2ClassDefinition)def).resolveInheritance(query); + ((M2ClassDefinition)def).resolveInheritance(query, prefixResolver, modelConstraints); } } } diff --git a/source/java/org/alfresco/repo/dictionary/DictionaryDAOTest.java b/source/java/org/alfresco/repo/dictionary/DictionaryDAOTest.java index 169c932c70..bae285a5ea 100644 --- a/source/java/org/alfresco/repo/dictionary/DictionaryDAOTest.java +++ b/source/java/org/alfresco/repo/dictionary/DictionaryDAOTest.java @@ -24,6 +24,7 @@ import junit.framework.TestCase; import org.alfresco.i18n.I18NUtil; import org.alfresco.repo.dictionary.constraint.RegexConstraint; +import org.alfresco.repo.dictionary.constraint.StringLengthConstraint; import org.alfresco.service.cmr.dictionary.AssociationDefinition; import org.alfresco.service.cmr.dictionary.ClassDefinition; import org.alfresco.service.cmr.dictionary.Constraint; @@ -35,6 +36,7 @@ import org.alfresco.service.cmr.dictionary.ModelDefinition; import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.dictionary.TypeDefinition; import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.RegexQNamePattern; public class DictionaryDAOTest extends TestCase @@ -145,6 +147,38 @@ public class DictionaryDAOTest extends TestCase // make sure it is the correct type of constraint assertTrue("Expected type REGEX constraint", constraint instanceof RegexConstraint); } + + public void testConstraintsOverrideInheritance() + { + QName baseQName = QName.createQName(TEST_URL, "base"); + QName fileQName = QName.createQName(TEST_URL, "file"); + QName folderQName = QName.createQName(TEST_URL, "folder"); + QName prop1QName = QName.createQName(TEST_URL, "prop1"); + + // get the base property + PropertyDefinition prop1Def = service.getProperty(baseQName, prop1QName); + assertNotNull(prop1Def); + List prop1Constraints = prop1Def.getConstraints(); + assertEquals("Incorrect number of constraints", 2, prop1Constraints.size()); + assertTrue("Constraint instance incorrect", prop1Constraints.get(0).getConstraint() instanceof RegexConstraint); + assertTrue("Constraint instance incorrect", prop1Constraints.get(1).getConstraint() instanceof StringLengthConstraint); + + // check the inherited property on folder (must be same as above) + prop1Def = service.getProperty(folderQName, prop1QName); + assertNotNull(prop1Def); + prop1Constraints = prop1Def.getConstraints(); + assertEquals("Incorrect number of constraints", 2, prop1Constraints.size()); + assertTrue("Constraint instance incorrect", prop1Constraints.get(0).getConstraint() instanceof RegexConstraint); + assertTrue("Constraint instance incorrect", prop1Constraints.get(1).getConstraint() instanceof StringLengthConstraint); + + // check the overridden property on file (must be reverse of above) + prop1Def = service.getProperty(fileQName, prop1QName); + assertNotNull(prop1Def); + prop1Constraints = prop1Def.getConstraints(); + assertEquals("Incorrect number of constraints", 2, prop1Constraints.size()); + assertTrue("Constraint instance incorrect", prop1Constraints.get(0).getConstraint() instanceof StringLengthConstraint); + assertTrue("Constraint instance incorrect", prop1Constraints.get(1).getConstraint() instanceof RegexConstraint); + } public void testArchive() { diff --git a/source/java/org/alfresco/repo/dictionary/M2ClassDefinition.java b/source/java/org/alfresco/repo/dictionary/M2ClassDefinition.java index 8601167e70..7b759472de 100644 --- a/source/java/org/alfresco/repo/dictionary/M2ClassDefinition.java +++ b/source/java/org/alfresco/repo/dictionary/M2ClassDefinition.java @@ -204,7 +204,10 @@ import org.alfresco.service.namespace.QName; } - /*package*/ void resolveInheritance(ModelQuery query) + /*package*/ void resolveInheritance( + ModelQuery query, + NamespacePrefixResolver prefixResolver, + Map modelConstraints) { // Retrieve parent class ClassDefinition parentClass = (parentName == null) ? null : query.getClass(parentName); @@ -221,7 +224,9 @@ import org.alfresco.service.namespace.QName; } else { - inheritedProperties.put(def.getName(), new M2PropertyDefinition(this, def, override)); + inheritedProperties.put( + def.getName(), + new M2PropertyDefinition(this, def, override, prefixResolver, modelConstraints)); } } } diff --git a/source/java/org/alfresco/repo/dictionary/M2Property.java b/source/java/org/alfresco/repo/dictionary/M2Property.java index 3082a726a9..8eebf3e675 100644 --- a/source/java/org/alfresco/repo/dictionary/M2Property.java +++ b/source/java/org/alfresco/repo/dictionary/M2Property.java @@ -19,6 +19,8 @@ package org.alfresco.repo.dictionary; import java.util.Collections; import java.util.List; +import org.alfresco.service.cmr.dictionary.ConstraintDefinition; + /** * Property Definition diff --git a/source/java/org/alfresco/repo/dictionary/M2PropertyDefinition.java b/source/java/org/alfresco/repo/dictionary/M2PropertyDefinition.java index a9507dca28..fc62e47213 100644 --- a/source/java/org/alfresco/repo/dictionary/M2PropertyDefinition.java +++ b/source/java/org/alfresco/repo/dictionary/M2PropertyDefinition.java @@ -44,8 +44,7 @@ import org.alfresco.service.namespace.QName; private QName name; private QName propertyTypeName; private DataTypeDefinition dataType; - private List constraints = new ArrayList(5); - private Map constraintsByQName = new HashMap(7); + private List constraintDefs = Collections.emptyList(); /*package*/ M2PropertyDefinition( ClassDefinition classDef, @@ -64,10 +63,12 @@ import org.alfresco.service.namespace.QName; /*package*/ M2PropertyDefinition( ClassDefinition classDef, PropertyDefinition propertyDef, - M2PropertyOverride override) + M2PropertyOverride override, + NamespacePrefixResolver prefixResolver, + Map modelConstraints) { this.classDef = classDef; - this.m2Property = createOverriddenProperty(propertyDef, override); + this.m2Property = createOverriddenProperty(propertyDef, override, prefixResolver, modelConstraints); this.name = propertyDef.getName(); this.dataType = propertyDef.getDataType(); this.propertyTypeName = this.dataType.getName(); @@ -100,15 +101,30 @@ import org.alfresco.service.namespace.QName; } // Construct constraints - for (M2Constraint constraint : m2Property.getConstraints()) + constraintDefs = buildConstraints( + m2Property.getConstraints(), + this, + prefixResolver, + modelConstraints); + } + + private static List buildConstraints( + List m2constraints, + M2PropertyDefinition m2PropertyDef, + NamespacePrefixResolver prefixResolver, + Map modelConstraints) + { + List constraints = new ArrayList(5); + Map constraintsByQName = new HashMap(7); + for (M2Constraint constraint : m2constraints) { - ConstraintDefinition def = new M2ConstraintDefinition(this, constraint, prefixResolver); + ConstraintDefinition def = new M2ConstraintDefinition(m2PropertyDef, constraint, prefixResolver); QName qname = def.getName(); if (constraintsByQName.containsKey(qname)) { throw new DictionaryException( "d_dictionary.property.err.duplicate_constraint_on_property", - def.getName().toPrefixString(), name.toPrefixString()); + def.getName().toPrefixString(), m2PropertyDef.name.toPrefixString()); } else if (modelConstraints.containsKey(qname)) { @@ -120,9 +136,10 @@ import org.alfresco.service.namespace.QName; constraints.add(def); modelConstraints.put(qname, def); } + // done + return constraints; } - /** * Create a property definition whose values are overridden * @@ -130,7 +147,11 @@ import org.alfresco.service.namespace.QName; * @param override the overridden values * @return the property definition */ - private M2Property createOverriddenProperty(PropertyDefinition propertyDef, M2PropertyOverride override) + private M2Property createOverriddenProperty( + PropertyDefinition propertyDef, + M2PropertyOverride override, + NamespacePrefixResolver prefixResolver, + Map modelConstraints) { M2Property property = new M2Property(); @@ -161,6 +182,21 @@ import org.alfresco.service.namespace.QName; property.setMandatory(isOverrideMandatory == null ? propertyDef.isMandatory() : isOverrideMandatory); property.setMandatoryEnforced(isOverrideMandatoryEnforced); + // inherit or override constraints + List overrideConstraints = override.getConstraints(); + if (overrideConstraints != null) + { + constraintDefs = buildConstraints( + overrideConstraints, + (M2PropertyDefinition) propertyDef, + prefixResolver, + modelConstraints); + } + else + { + this.constraintDefs = propertyDef.getConstraints(); + } + // Copy all other properties as they are property.setDescription(propertyDef.getDescription()); property.setIndexed(propertyDef.isIndexed()); @@ -323,6 +359,6 @@ import org.alfresco.service.namespace.QName; public List getConstraints() { - return Collections.unmodifiableList(constraints); + return constraintDefs; } } diff --git a/source/java/org/alfresco/repo/dictionary/M2PropertyOverride.java b/source/java/org/alfresco/repo/dictionary/M2PropertyOverride.java index b709796018..80e1a13502 100644 --- a/source/java/org/alfresco/repo/dictionary/M2PropertyOverride.java +++ b/source/java/org/alfresco/repo/dictionary/M2PropertyOverride.java @@ -16,6 +16,8 @@ */ package org.alfresco.repo.dictionary; +import java.util.List; + /** * Property override definition @@ -29,7 +31,7 @@ public class M2PropertyOverride private Boolean isMandatory; private boolean isMandatoryEnforced = false; private String defaultValue; - + private List constraints; /*package*/ M2PropertyOverride() { @@ -74,5 +76,9 @@ public class M2PropertyOverride { this.defaultValue = defaultValue; } - + + public List getConstraints() + { + return constraints; + } } diff --git a/source/java/org/alfresco/repo/dictionary/dictionarydaotest_model.xml b/source/java/org/alfresco/repo/dictionary/dictionarydaotest_model.xml index a9a74f0592..32e074b425 100644 --- a/source/java/org/alfresco/repo/dictionary/dictionarydaotest_model.xml +++ b/source/java/org/alfresco/repo/dictionary/dictionarydaotest_model.xml @@ -27,10 +27,18 @@ [A-Z]* false + + [a-z]* + false + 0 256 + + 0 + 128 + 0 256 @@ -132,8 +140,12 @@ - + an overriden default value + + + + diff --git a/source/java/org/alfresco/repo/dictionary/m2binding.xml b/source/java/org/alfresco/repo/dictionary/m2binding.xml index df04117d7e..0c9669abf8 100644 --- a/source/java/org/alfresco/repo/dictionary/m2binding.xml +++ b/source/java/org/alfresco/repo/dictionary/m2binding.xml @@ -77,6 +77,9 @@ + + +