mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Dictionary/Constraint improvements (required by MOB-1276)
- get constraints (for model) - add optional title and/or description git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@15913 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -35,10 +35,10 @@ import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.ConstraintDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryException;
|
||||
import org.alfresco.service.cmr.dictionary.ModelDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||
import org.alfresco.service.namespace.DynamicNamespacePrefixResolver;
|
||||
import org.alfresco.service.namespace.NamespaceException;
|
||||
@@ -414,6 +414,14 @@ import org.apache.commons.logging.LogFactory;
|
||||
return associations.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the compiled constraints
|
||||
*/
|
||||
public Collection<ConstraintDefinition> getConstraints()
|
||||
{
|
||||
return constraints.values();
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.dictionary.impl.ModelQuery#getConstraint(QName)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -33,6 +33,7 @@ import org.alfresco.repo.tenant.TenantDeployer;
|
||||
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.ConstraintDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.ModelDefinition;
|
||||
@@ -396,6 +397,11 @@ public class DictionaryComponent implements DictionaryService, TenantDeployer
|
||||
}
|
||||
return props;
|
||||
}
|
||||
|
||||
public Collection<ConstraintDefinition> getConstraints(QName model)
|
||||
{
|
||||
return dictionaryDAO.getConstraints(model);
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
|
@@ -1,186 +1,193 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.dictionary;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.ModelDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.NamespaceDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* Dictionary Data Access
|
||||
*
|
||||
* @author David Caruana
|
||||
*/
|
||||
public interface DictionaryDAO extends ModelQuery
|
||||
{
|
||||
|
||||
/**
|
||||
* @return the models known by the dictionary
|
||||
*/
|
||||
public Collection<QName> getModels();
|
||||
|
||||
/**
|
||||
* @param name the model to retrieve
|
||||
* @return the named model definition
|
||||
*/
|
||||
public ModelDefinition getModel(QName name);
|
||||
|
||||
/**
|
||||
* @param model the model to retrieve property types for
|
||||
* @return the property types of the model
|
||||
*/
|
||||
public Collection<DataTypeDefinition> getDataTypes(QName model);
|
||||
|
||||
/**
|
||||
* @param model the model to retrieve types for
|
||||
* @return the types of the model
|
||||
*/
|
||||
public Collection<TypeDefinition> getTypes(QName model);
|
||||
|
||||
/**
|
||||
* @param superType
|
||||
* @param follow true => follow up the super-class hierarchy, false => immediate sub types only
|
||||
* @return
|
||||
*/
|
||||
public Collection<QName> getSubTypes(QName superType, boolean follow);
|
||||
|
||||
/**
|
||||
* @param model the model to retrieve aspects for
|
||||
* @return the aspects of the model
|
||||
*/
|
||||
public Collection<AspectDefinition> getAspects(QName model);
|
||||
|
||||
|
||||
/**
|
||||
* @param model the model to retrieve associations for
|
||||
* @return the associations of the model
|
||||
*/
|
||||
public Collection<AssociationDefinition> getAssociations(QName model);
|
||||
|
||||
/**
|
||||
* @param superAspect
|
||||
* @param follow true => follow up the super-class hierarchy, false => immediate sub aspects only
|
||||
* @return
|
||||
*/
|
||||
public Collection<QName> getSubAspects(QName superAspect, boolean follow);
|
||||
|
||||
/**
|
||||
* @param model the model for which to get properties for
|
||||
* @return the properties of the model
|
||||
*/
|
||||
public Collection<PropertyDefinition> getProperties(QName model);
|
||||
|
||||
/**
|
||||
* Construct an anonymous type that combines a primary type definition and
|
||||
* and one or more aspects
|
||||
*
|
||||
* @param type the primary type
|
||||
* @param aspects the aspects to combine
|
||||
* @return the anonymous type definition
|
||||
*/
|
||||
public TypeDefinition getAnonymousType(QName type, Collection<QName> aspects);
|
||||
|
||||
/**
|
||||
* Adds a model to the dictionary. The model is compiled and validated.
|
||||
*
|
||||
* @param model the model to add
|
||||
* @return QName name of model
|
||||
*/
|
||||
public QName putModel(M2Model model);
|
||||
|
||||
/**
|
||||
* Removes a model from the dictionary. The types and aspect in the model will no longer be
|
||||
* available.
|
||||
*
|
||||
* @param model the qname of the model to remove
|
||||
*/
|
||||
public void removeModel(QName model);
|
||||
|
||||
/**
|
||||
* Get all properties for the model and that are of the given data type.
|
||||
* If dataType is null then the all properties will be returned.
|
||||
*
|
||||
* @param modelName
|
||||
* @param dataType
|
||||
* @return
|
||||
*/
|
||||
public Collection<PropertyDefinition> getProperties(QName modelName, QName dataType);
|
||||
|
||||
/**
|
||||
* @param model the model to retrieve namespaces for
|
||||
* @return the namespaces of the model
|
||||
*/
|
||||
public Collection<NamespaceDefinition> getNamespaces(QName modelName);
|
||||
|
||||
/**
|
||||
* validate against dictionary
|
||||
*
|
||||
* if new model
|
||||
* then nothing to validate
|
||||
*
|
||||
* else if an existing model
|
||||
* then could be updated (or unchanged) so validate to currently only allow incremental updates
|
||||
* - addition of new types, aspects (except default aspects), properties, associations
|
||||
* - no deletion of types, aspects or properties or associations
|
||||
* - no addition, update or deletion of default/mandatory aspects
|
||||
*
|
||||
* @param newOrUpdatedModel
|
||||
*/
|
||||
public void validateModel(M2Model newOrUpdatedModel);
|
||||
|
||||
/**
|
||||
*
|
||||
* Register listener with the Dictionary
|
||||
*
|
||||
* @param dictionaryListener
|
||||
*/
|
||||
public void register(DictionaryListener dictionaryListener);
|
||||
|
||||
/**
|
||||
* Reset the Dictionary - destroy & re-initialise
|
||||
*/
|
||||
public void reset();
|
||||
|
||||
/**
|
||||
* Initialise the Dictionary
|
||||
*/
|
||||
public void init();
|
||||
|
||||
/**
|
||||
* Destroy the Dictionary
|
||||
*/
|
||||
public void destroy();
|
||||
|
||||
// MT-specific
|
||||
public boolean isModelInherited(QName name);
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.dictionary;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.ConstraintDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.ModelDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.NamespaceDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* Dictionary Data Access
|
||||
*
|
||||
* @author David Caruana
|
||||
*/
|
||||
public interface DictionaryDAO extends ModelQuery
|
||||
{
|
||||
|
||||
/**
|
||||
* @return the models known by the dictionary
|
||||
*/
|
||||
public Collection<QName> getModels();
|
||||
|
||||
/**
|
||||
* @param name the model to retrieve
|
||||
* @return the named model definition
|
||||
*/
|
||||
public ModelDefinition getModel(QName name);
|
||||
|
||||
/**
|
||||
* @param model the model to retrieve property types for
|
||||
* @return the property types of the model
|
||||
*/
|
||||
public Collection<DataTypeDefinition> getDataTypes(QName model);
|
||||
|
||||
/**
|
||||
* @param model the model to retrieve types for
|
||||
* @return the types of the model
|
||||
*/
|
||||
public Collection<TypeDefinition> getTypes(QName model);
|
||||
|
||||
/**
|
||||
* @param superType
|
||||
* @param follow true => follow up the super-class hierarchy, false => immediate sub types only
|
||||
* @return
|
||||
*/
|
||||
public Collection<QName> getSubTypes(QName superType, boolean follow);
|
||||
|
||||
/**
|
||||
* @param model the model to retrieve aspects for
|
||||
* @return the aspects of the model
|
||||
*/
|
||||
public Collection<AspectDefinition> getAspects(QName model);
|
||||
|
||||
|
||||
/**
|
||||
* @param model the model to retrieve associations for
|
||||
* @return the associations of the model
|
||||
*/
|
||||
public Collection<AssociationDefinition> getAssociations(QName model);
|
||||
|
||||
/**
|
||||
* @param superAspect
|
||||
* @param follow true => follow up the super-class hierarchy, false => immediate sub aspects only
|
||||
* @return
|
||||
*/
|
||||
public Collection<QName> getSubAspects(QName superAspect, boolean follow);
|
||||
|
||||
/**
|
||||
* @param model the model for which to get properties for
|
||||
* @return the properties of the model
|
||||
*/
|
||||
public Collection<PropertyDefinition> getProperties(QName model);
|
||||
|
||||
/**
|
||||
* Construct an anonymous type that combines a primary type definition and
|
||||
* and one or more aspects
|
||||
*
|
||||
* @param type the primary type
|
||||
* @param aspects the aspects to combine
|
||||
* @return the anonymous type definition
|
||||
*/
|
||||
public TypeDefinition getAnonymousType(QName type, Collection<QName> aspects);
|
||||
|
||||
/**
|
||||
* Adds a model to the dictionary. The model is compiled and validated.
|
||||
*
|
||||
* @param model the model to add
|
||||
* @return QName name of model
|
||||
*/
|
||||
public QName putModel(M2Model model);
|
||||
|
||||
/**
|
||||
* Removes a model from the dictionary. The types and aspect in the model will no longer be
|
||||
* available.
|
||||
*
|
||||
* @param model the qname of the model to remove
|
||||
*/
|
||||
public void removeModel(QName model);
|
||||
|
||||
/**
|
||||
* Get all properties for the model and that are of the given data type.
|
||||
* If dataType is null then the all properties will be returned.
|
||||
*
|
||||
* @param modelName
|
||||
* @param dataType
|
||||
* @return
|
||||
*/
|
||||
public Collection<PropertyDefinition> getProperties(QName modelName, QName dataType);
|
||||
|
||||
/**
|
||||
* @param model the model to retrieve namespaces for
|
||||
* @return the namespaces of the model
|
||||
*/
|
||||
public Collection<NamespaceDefinition> getNamespaces(QName modelName);
|
||||
|
||||
/**
|
||||
* @param model the model to retrieve constraints for
|
||||
* @return the constraints of the model
|
||||
*/
|
||||
public Collection<ConstraintDefinition> getConstraints(QName model);
|
||||
|
||||
/**
|
||||
* validate against dictionary
|
||||
*
|
||||
* if new model
|
||||
* then nothing to validate
|
||||
*
|
||||
* else if an existing model
|
||||
* then could be updated (or unchanged) so validate to currently only allow incremental updates
|
||||
* - addition of new types, aspects (except default aspects), properties, associations
|
||||
* - no deletion of types, aspects or properties or associations
|
||||
* - no addition, update or deletion of default/mandatory aspects
|
||||
*
|
||||
* @param newOrUpdatedModel
|
||||
*/
|
||||
public void validateModel(M2Model newOrUpdatedModel);
|
||||
|
||||
/**
|
||||
*
|
||||
* Register listener with the Dictionary
|
||||
*
|
||||
* @param dictionaryListener
|
||||
*/
|
||||
public void register(DictionaryListener dictionaryListener);
|
||||
|
||||
/**
|
||||
* Reset the Dictionary - destroy & re-initialise
|
||||
*/
|
||||
public void reset();
|
||||
|
||||
/**
|
||||
* Initialise the Dictionary
|
||||
*/
|
||||
public void init();
|
||||
|
||||
/**
|
||||
* Destroy the Dictionary
|
||||
*/
|
||||
public void destroy();
|
||||
|
||||
// MT-specific
|
||||
public boolean isModelInherited(QName name);
|
||||
}
|
||||
|
@@ -932,6 +932,15 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
||||
return namespaces;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.dictionary.DictionaryDAO#getConstraints(org.alfresco.service.namespace.QName)
|
||||
*/
|
||||
public Collection<ConstraintDefinition> getConstraints(QName modelName)
|
||||
{
|
||||
CompiledModel model = getCompiledModel(modelName);
|
||||
return model.getConstraints();
|
||||
}
|
||||
|
||||
// re-entrant (eg. via reset)
|
||||
private DictionaryRegistry getDictionaryRegistry(String tenantDomain)
|
||||
{
|
||||
|
@@ -29,6 +29,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -172,7 +173,7 @@ public class DictionaryDAOTest extends TestCase
|
||||
bootstrap.setModels(bootstrapModels);
|
||||
bootstrap.setDictionaryDAO(dictionaryDAO);
|
||||
bootstrap.setTenantService(tenantService);
|
||||
bootstrap.bootstrap();
|
||||
bootstrap.bootstrap();
|
||||
}
|
||||
|
||||
|
||||
@@ -203,7 +204,36 @@ public class DictionaryDAOTest extends TestCase
|
||||
// Check that the registered constraints are correct
|
||||
assertNotNull("Constraint reg1 not registered", ConstraintRegistry.getInstance().getConstraint("cm:reg1"));
|
||||
assertNotNull("Constraint reg2 not registered", ConstraintRegistry.getInstance().getConstraint("cm:reg2"));
|
||||
|
||||
|
||||
QName model = QName.createQName(TEST_URL, "dictionarydaotest");
|
||||
Collection<ConstraintDefinition> modelConstraints = service.getConstraints(model);
|
||||
assertEquals(15, modelConstraints.size()); // 8 + 7
|
||||
|
||||
QName conRegExp1QName = QName.createQName(TEST_URL, "regex1");
|
||||
boolean found1 = false;
|
||||
|
||||
QName conStrLen1QName = QName.createQName(TEST_URL, "stringLength1");
|
||||
boolean found2 = false;
|
||||
|
||||
for (ConstraintDefinition constraintDef : modelConstraints)
|
||||
{
|
||||
if (constraintDef.getName().equals(conRegExp1QName))
|
||||
{
|
||||
assertEquals("Regex1 title", constraintDef.getTitle());
|
||||
assertEquals("Regex1 description", constraintDef.getDescription());
|
||||
found1 = true;
|
||||
}
|
||||
|
||||
if (constraintDef.getName().equals(conStrLen1QName))
|
||||
{
|
||||
assertNull(constraintDef.getTitle());
|
||||
assertNull(constraintDef.getDescription());
|
||||
found2 = true;
|
||||
}
|
||||
}
|
||||
assertTrue(found1);
|
||||
assertTrue(found2);
|
||||
|
||||
// get the constraints for a property without constraints
|
||||
QName propNoConstraintsQName = QName.createQName(TEST_URL, "fileprop");
|
||||
PropertyDefinition propNoConstraintsDef = service.getProperty(propNoConstraintsQName);
|
||||
@@ -222,6 +252,17 @@ public class DictionaryDAOTest extends TestCase
|
||||
// check the individual constraints
|
||||
ConstraintDefinition constraintDef = constraints.get(0);
|
||||
assertTrue("Constraint anonymous name incorrect", constraintDef.getName().getLocalName().startsWith("prop1_anon"));
|
||||
|
||||
// inherit title / description for reference constraint
|
||||
assertTrue("Constraint title incorrect", constraintDef.getTitle().equals("Regex1 title"));
|
||||
assertTrue("Constraint description incorrect", constraintDef.getDescription().equals("Regex1 description"));
|
||||
|
||||
constraintDef = constraints.get(1);
|
||||
assertTrue("Constraint anonymous name incorrect", constraintDef.getName().getLocalName().startsWith("prop1_anon"));
|
||||
|
||||
assertTrue("Constraint title incorrect", constraintDef.getTitle().equals("Prop1 Strlen1 title"));
|
||||
assertTrue("Constraint description incorrect", constraintDef.getDescription().equals("Prop1 Strlen1 description"));
|
||||
|
||||
// check that the constraint implementation is valid (it used a reference)
|
||||
Constraint constraint = constraintDef.getConstraint();
|
||||
assertNotNull("Reference constraint has no implementation", constraint);
|
||||
|
@@ -1,82 +1,133 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.dictionary;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract Property Constraint.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class M2Constraint
|
||||
{
|
||||
private String name;
|
||||
private String ref;
|
||||
private String type;
|
||||
private String description;
|
||||
private List<M2NamedValue> parameters = new ArrayList<M2NamedValue>(2);
|
||||
|
||||
/*package*/ M2Constraint()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getRef()
|
||||
{
|
||||
return ref;
|
||||
}
|
||||
|
||||
public String getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public List<M2NamedValue> getParameters()
|
||||
{
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.dictionary;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract Property Constraint.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class M2Constraint
|
||||
{
|
||||
private String name;
|
||||
private String ref;
|
||||
private String type;
|
||||
private String title;
|
||||
private String description;
|
||||
private List<M2NamedValue> parameters = new ArrayList<M2NamedValue>(2);
|
||||
|
||||
/*package*/ M2Constraint()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getRef()
|
||||
{
|
||||
return ref;
|
||||
}
|
||||
|
||||
public String getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getTitle()
|
||||
{
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description)
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public List<M2NamedValue> getParameters()
|
||||
{
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public M2NamedValue createParameter(String name, String simpleValue)
|
||||
{
|
||||
M2NamedValue param = new M2NamedValue();
|
||||
param.setName(name);
|
||||
param.setSimpleValue(simpleValue);
|
||||
parameters.add(param);
|
||||
return param;
|
||||
}
|
||||
|
||||
public M2NamedValue createParameter(String name, List<String> listValue)
|
||||
{
|
||||
M2NamedValue param = new M2NamedValue();
|
||||
param.setName(name);
|
||||
param.setListValue(listValue);
|
||||
parameters.add(param);
|
||||
return param;
|
||||
}
|
||||
|
||||
public void removeParameter(String name)
|
||||
{
|
||||
List<M2NamedValue> params = getParameters();
|
||||
for (M2NamedValue param : params)
|
||||
{
|
||||
if (param.getName().equals(name))
|
||||
{
|
||||
parameters.remove(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,327 +1,375 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.dictionary;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint;
|
||||
import org.alfresco.repo.dictionary.constraint.NumericRangeConstraint;
|
||||
import org.alfresco.repo.dictionary.constraint.RegexConstraint;
|
||||
import org.alfresco.repo.dictionary.constraint.RegisteredConstraint;
|
||||
import org.alfresco.repo.dictionary.constraint.StringLengthConstraint;
|
||||
import org.alfresco.service.cmr.dictionary.Constraint;
|
||||
import org.alfresco.service.cmr.dictionary.ConstraintDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryException;
|
||||
import org.alfresco.service.cmr.dictionary.ModelDefinition;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
import org.springframework.beans.InvalidPropertyException;
|
||||
import org.springframework.beans.PropertyAccessException;
|
||||
|
||||
/**
|
||||
* Compiled Property Constraint
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
/* package */class M2ConstraintDefinition implements ConstraintDefinition
|
||||
{
|
||||
private static final String PROP_SHORT_NAME = "shortName";
|
||||
|
||||
public static final String ERR_CYCLIC_REF = "d_dictionary.constraint.err.cyclic_ref";
|
||||
public static final String ERR_TYPE_AND_REF = "d_dictionary.constraint.err.type_and_ref";
|
||||
public static final String ERR_TYPE_OR_REF = "d_dictionary.constraint.err.type_or_ref";
|
||||
public static final String ERR_REF_NOT_FOUND = "d_dictionary.constraint.err.ref_not_found";
|
||||
public static final String ERR_ANON_NEEDS_PROPERTY = "d_dictionary.constraint.err.anon_needs_property";
|
||||
public static final String ERR_INVALID_TYPE = "d_dictionary.constraint.err.invalid_type";
|
||||
public static final String ERR_SIMPLE_AND_LIST = "d_dictionary.constraint.err.property_simple_and_list";
|
||||
public static final String ERR_CONSTRUCT_FAILURE = "d_dictionary.constraint.err.construct_failure";
|
||||
public static final String ERR_PROPERTY_MISMATCH = "d_dictionary.constraint.err.property_mismatch";
|
||||
public static final String ERR_RESERVED_PROPERTY = "d_dictionary.constraint.err.reserved_property";
|
||||
|
||||
private static int anonPropCount = 0;
|
||||
|
||||
private ModelDefinition model;
|
||||
private NamespacePrefixResolver prefixResolver;
|
||||
private M2Constraint m2Constraint;
|
||||
private QName name;
|
||||
private Constraint constraint;
|
||||
private boolean resolving;
|
||||
|
||||
/* package */M2ConstraintDefinition(M2PropertyDefinition m2PropertyDef, M2Constraint m2Constraint,
|
||||
NamespacePrefixResolver prefixResolver)
|
||||
{
|
||||
this(m2PropertyDef.getModel(), m2PropertyDef, m2Constraint, prefixResolver);
|
||||
}
|
||||
|
||||
/* package */M2ConstraintDefinition(ModelDefinition modelDefinition, M2PropertyDefinition m2PropertyDef,
|
||||
M2Constraint m2Constraint, NamespacePrefixResolver prefixResolver)
|
||||
{
|
||||
this.model = modelDefinition;
|
||||
this.m2Constraint = m2Constraint;
|
||||
this.prefixResolver = prefixResolver;
|
||||
|
||||
String constraintName = m2Constraint.getName();
|
||||
if (constraintName == null)
|
||||
{
|
||||
// the constraint is anonymous, so it has to be defined within the context of a property
|
||||
if (m2PropertyDef == null)
|
||||
{
|
||||
throw new DictionaryException(ERR_ANON_NEEDS_PROPERTY);
|
||||
}
|
||||
// pick the name up from the property and some anonymous value
|
||||
String localName = m2PropertyDef.getName().getLocalName() + "_anon_" + (++anonPropCount);
|
||||
this.name = QName.createQName(m2PropertyDef.getName().getNamespaceURI(), localName);
|
||||
m2Constraint.setName(this.name.getPrefixedQName(prefixResolver).toPrefixString());
|
||||
}
|
||||
else
|
||||
{
|
||||
this.name = QName.createQName(m2Constraint.getName(), prefixResolver);
|
||||
}
|
||||
}
|
||||
|
||||
/* package */synchronized void resolveDependencies(ModelQuery query)
|
||||
{
|
||||
if (resolving)
|
||||
{
|
||||
throw new DictionaryException(ERR_CYCLIC_REF, name.toPrefixString());
|
||||
}
|
||||
// prevent circular references
|
||||
try
|
||||
{
|
||||
resolving = true;
|
||||
resolveInternal(query);
|
||||
}
|
||||
finally
|
||||
{
|
||||
resolving = false;
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void resolveInternal(ModelQuery query)
|
||||
{
|
||||
if (constraint != null)
|
||||
{
|
||||
// already been resolved
|
||||
return;
|
||||
}
|
||||
String shortName = name.toPrefixString();
|
||||
String ref = m2Constraint.getRef();
|
||||
String type = m2Constraint.getType();
|
||||
if (ref != null && type != null)
|
||||
{
|
||||
throw new DictionaryException(ERR_TYPE_AND_REF, shortName);
|
||||
}
|
||||
else if (ref == null && type == null)
|
||||
{
|
||||
throw new DictionaryException(ERR_TYPE_OR_REF, shortName);
|
||||
}
|
||||
else if (ref != null)
|
||||
{
|
||||
// resolve the reference name
|
||||
QName qnameRef = QName.createQName(ref, prefixResolver);
|
||||
// ensure that the reference exists in the model
|
||||
M2ConstraintDefinition constraintDef = (M2ConstraintDefinition) query.getConstraint(qnameRef);
|
||||
if (constraintDef == null)
|
||||
{
|
||||
throw new DictionaryException(ERR_REF_NOT_FOUND, ref, shortName);
|
||||
}
|
||||
// make sure that the constraint definition has itself been resolved
|
||||
constraintDef.resolveDependencies(query);
|
||||
// just use the constraint provided by the referenced definition
|
||||
this.constraint = constraintDef.getConstraint();
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have to build the constraint from the type
|
||||
try
|
||||
{
|
||||
ConstraintType constraintType = ConstraintType.valueOf(type);
|
||||
constraint = constraintType.newInstance();
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
// try to establish it as a class
|
||||
try
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
Class clazz = Class.forName(type);
|
||||
constraint = (Constraint) clazz.newInstance();
|
||||
}
|
||||
catch (ClassNotFoundException ee)
|
||||
{
|
||||
throw new DictionaryException(ERR_INVALID_TYPE, type, shortName);
|
||||
}
|
||||
catch (ClassCastException ee)
|
||||
{
|
||||
throw new DictionaryException(ERR_INVALID_TYPE, type, shortName);
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
throw new DictionaryException(ERR_CONSTRUCT_FAILURE, type, shortName);
|
||||
}
|
||||
}
|
||||
// property setters
|
||||
BeanWrapper beanWrapper = new BeanWrapperImpl(constraint);
|
||||
List<M2NamedValue> constraintNamedValues = m2Constraint.getParameters();
|
||||
|
||||
if (constraintNamedValues != null)
|
||||
{
|
||||
for (M2NamedValue namedValue : constraintNamedValues)
|
||||
{
|
||||
String namedValueName = namedValue.getName();
|
||||
// Check for reserved properties
|
||||
if (namedValueName.equals(PROP_SHORT_NAME))
|
||||
{
|
||||
throw new DictionaryException(ERR_RESERVED_PROPERTY, PROP_SHORT_NAME, namedValueName);
|
||||
}
|
||||
|
||||
Object value = null;
|
||||
if (namedValue.getSimpleValue() != null && namedValue.getListValue() != null)
|
||||
{
|
||||
throw new DictionaryException(ERR_SIMPLE_AND_LIST, shortName, namedValue.getName());
|
||||
}
|
||||
else if (namedValue.getSimpleValue() != null)
|
||||
{
|
||||
value = namedValue.getSimpleValue();
|
||||
}
|
||||
else if (namedValue.getListValue() != null)
|
||||
{
|
||||
value = namedValue.getListValue();
|
||||
}
|
||||
try
|
||||
{
|
||||
beanWrapper.setPropertyValue(namedValueName, value);
|
||||
}
|
||||
catch (PropertyAccessException e)
|
||||
{
|
||||
throw new DictionaryException(ERR_PROPERTY_MISMATCH, e, namedValueName, shortName);
|
||||
}
|
||||
catch (InvalidPropertyException e)
|
||||
{
|
||||
throw new DictionaryException(ERR_PROPERTY_MISMATCH, e, namedValueName, shortName);
|
||||
}
|
||||
}
|
||||
|
||||
// Pass in the short name as a special property, if it is available
|
||||
if (beanWrapper.isWritableProperty(PROP_SHORT_NAME))
|
||||
{
|
||||
try
|
||||
{
|
||||
beanWrapper.setPropertyValue(PROP_SHORT_NAME, shortName);
|
||||
}
|
||||
catch (PropertyAccessException e)
|
||||
{
|
||||
throw new DictionaryException(ERR_PROPERTY_MISMATCH, e, shortName, shortName);
|
||||
}
|
||||
catch (InvalidPropertyException e)
|
||||
{
|
||||
throw new DictionaryException(ERR_PROPERTY_MISMATCH, e, shortName, shortName);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// now initialize
|
||||
constraint.initialize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getName()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getName().toString();
|
||||
}
|
||||
|
||||
public ModelDefinition getModel()
|
||||
{
|
||||
return model;
|
||||
}
|
||||
|
||||
public QName getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public Constraint getConstraint()
|
||||
{
|
||||
return constraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Well-known constraint types
|
||||
*/
|
||||
public static enum ConstraintType
|
||||
{
|
||||
REGISTERED
|
||||
{
|
||||
@Override
|
||||
protected Constraint newInstance()
|
||||
{
|
||||
return new RegisteredConstraint();
|
||||
}
|
||||
},
|
||||
REGEX
|
||||
{
|
||||
@Override
|
||||
protected Constraint newInstance()
|
||||
{
|
||||
return new RegexConstraint();
|
||||
}
|
||||
},
|
||||
MINMAX
|
||||
{
|
||||
@Override
|
||||
protected Constraint newInstance()
|
||||
{
|
||||
return new NumericRangeConstraint();
|
||||
}
|
||||
},
|
||||
LENGTH
|
||||
{
|
||||
@Override
|
||||
protected Constraint newInstance()
|
||||
{
|
||||
return new StringLengthConstraint();
|
||||
}
|
||||
},
|
||||
LIST
|
||||
{
|
||||
@Override
|
||||
protected Constraint newInstance()
|
||||
{
|
||||
return new ListOfValuesConstraint();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return Returns the constraint implementation
|
||||
*/
|
||||
protected abstract Constraint newInstance();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.dictionary;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint;
|
||||
import org.alfresco.repo.dictionary.constraint.NumericRangeConstraint;
|
||||
import org.alfresco.repo.dictionary.constraint.RegexConstraint;
|
||||
import org.alfresco.repo.dictionary.constraint.RegisteredConstraint;
|
||||
import org.alfresco.repo.dictionary.constraint.StringLengthConstraint;
|
||||
import org.alfresco.service.cmr.dictionary.Constraint;
|
||||
import org.alfresco.service.cmr.dictionary.ConstraintDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryException;
|
||||
import org.alfresco.service.cmr.dictionary.ModelDefinition;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
import org.springframework.beans.InvalidPropertyException;
|
||||
import org.springframework.beans.PropertyAccessException;
|
||||
|
||||
/**
|
||||
* Compiled Property Constraint
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
/* package */class M2ConstraintDefinition implements ConstraintDefinition
|
||||
{
|
||||
private static final String PROP_SHORT_NAME = "shortName";
|
||||
private static final String PROP_TITLE = "title";
|
||||
private static final String PROP_DESCRIPTION = "description";
|
||||
|
||||
public static final String ERR_CYCLIC_REF = "d_dictionary.constraint.err.cyclic_ref";
|
||||
public static final String ERR_TYPE_AND_REF = "d_dictionary.constraint.err.type_and_ref";
|
||||
public static final String ERR_TYPE_OR_REF = "d_dictionary.constraint.err.type_or_ref";
|
||||
public static final String ERR_REF_NOT_FOUND = "d_dictionary.constraint.err.ref_not_found";
|
||||
public static final String ERR_ANON_NEEDS_PROPERTY = "d_dictionary.constraint.err.anon_needs_property";
|
||||
public static final String ERR_INVALID_TYPE = "d_dictionary.constraint.err.invalid_type";
|
||||
public static final String ERR_SIMPLE_AND_LIST = "d_dictionary.constraint.err.property_simple_and_list";
|
||||
public static final String ERR_CONSTRUCT_FAILURE = "d_dictionary.constraint.err.construct_failure";
|
||||
public static final String ERR_PROPERTY_MISMATCH = "d_dictionary.constraint.err.property_mismatch";
|
||||
public static final String ERR_RESERVED_PROPERTY = "d_dictionary.constraint.err.reserved_property";
|
||||
|
||||
private static int anonPropCount = 0;
|
||||
|
||||
private ModelDefinition model;
|
||||
private NamespacePrefixResolver prefixResolver;
|
||||
private M2Constraint m2Constraint;
|
||||
private QName name;
|
||||
private Constraint constraint;
|
||||
private boolean resolving;
|
||||
|
||||
/* package */M2ConstraintDefinition(M2PropertyDefinition m2PropertyDef, M2Constraint m2Constraint,
|
||||
NamespacePrefixResolver prefixResolver)
|
||||
{
|
||||
this(m2PropertyDef.getModel(), m2PropertyDef, m2Constraint, prefixResolver);
|
||||
}
|
||||
|
||||
/* package */M2ConstraintDefinition(ModelDefinition modelDefinition, M2PropertyDefinition m2PropertyDef,
|
||||
M2Constraint m2Constraint, NamespacePrefixResolver prefixResolver)
|
||||
{
|
||||
this.model = modelDefinition;
|
||||
this.m2Constraint = m2Constraint;
|
||||
this.prefixResolver = prefixResolver;
|
||||
|
||||
String constraintName = m2Constraint.getName();
|
||||
if (constraintName == null)
|
||||
{
|
||||
// the constraint is anonymous, so it has to be defined within the context of a property
|
||||
if (m2PropertyDef == null)
|
||||
{
|
||||
throw new DictionaryException(ERR_ANON_NEEDS_PROPERTY);
|
||||
}
|
||||
// pick the name up from the property and some anonymous value
|
||||
String localName = m2PropertyDef.getName().getLocalName() + "_anon_" + (++anonPropCount);
|
||||
this.name = QName.createQName(m2PropertyDef.getName().getNamespaceURI(), localName);
|
||||
m2Constraint.setName(this.name.getPrefixedQName(prefixResolver).toPrefixString());
|
||||
}
|
||||
else
|
||||
{
|
||||
this.name = QName.createQName(m2Constraint.getName(), prefixResolver);
|
||||
}
|
||||
}
|
||||
|
||||
/* package */synchronized void resolveDependencies(ModelQuery query)
|
||||
{
|
||||
if (resolving)
|
||||
{
|
||||
throw new DictionaryException(ERR_CYCLIC_REF, name.toPrefixString());
|
||||
}
|
||||
// prevent circular references
|
||||
try
|
||||
{
|
||||
resolving = true;
|
||||
resolveInternal(query);
|
||||
}
|
||||
finally
|
||||
{
|
||||
resolving = false;
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void resolveInternal(ModelQuery query)
|
||||
{
|
||||
if (constraint != null)
|
||||
{
|
||||
// already been resolved
|
||||
return;
|
||||
}
|
||||
|
||||
String shortName = name.toPrefixString();
|
||||
String ref = m2Constraint.getRef();
|
||||
String type = m2Constraint.getType();
|
||||
|
||||
String title = m2Constraint.getTitle();
|
||||
String description = m2Constraint.getDescription();
|
||||
|
||||
if (ref != null && type != null)
|
||||
{
|
||||
throw new DictionaryException(ERR_TYPE_AND_REF, shortName);
|
||||
}
|
||||
else if (ref == null && type == null)
|
||||
{
|
||||
throw new DictionaryException(ERR_TYPE_OR_REF, shortName);
|
||||
}
|
||||
else if (ref != null)
|
||||
{
|
||||
// resolve the reference name
|
||||
QName qnameRef = QName.createQName(ref, prefixResolver);
|
||||
// ensure that the reference exists in the model
|
||||
M2ConstraintDefinition constraintDef = (M2ConstraintDefinition) query.getConstraint(qnameRef);
|
||||
if (constraintDef == null)
|
||||
{
|
||||
throw new DictionaryException(ERR_REF_NOT_FOUND, ref, shortName);
|
||||
}
|
||||
// make sure that the constraint definition has itself been resolved
|
||||
constraintDef.resolveDependencies(query);
|
||||
// just use the constraint provided by the referenced definition
|
||||
this.constraint = constraintDef.getConstraint();
|
||||
|
||||
if (m2Constraint.getTitle() == null)
|
||||
{
|
||||
m2Constraint.setTitle(constraintDef.getTitle());
|
||||
}
|
||||
|
||||
if (m2Constraint.getDescription() == null)
|
||||
{
|
||||
m2Constraint.setDescription(constraintDef.getDescription());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have to build the constraint from the type
|
||||
try
|
||||
{
|
||||
ConstraintType constraintType = ConstraintType.valueOf(type);
|
||||
constraint = constraintType.newInstance();
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
// try to establish it as a class
|
||||
try
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
Class clazz = Class.forName(type);
|
||||
constraint = (Constraint) clazz.newInstance();
|
||||
}
|
||||
catch (ClassNotFoundException ee)
|
||||
{
|
||||
throw new DictionaryException(ERR_INVALID_TYPE, type, shortName);
|
||||
}
|
||||
catch (ClassCastException ee)
|
||||
{
|
||||
throw new DictionaryException(ERR_INVALID_TYPE, type, shortName);
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
throw new DictionaryException(ERR_CONSTRUCT_FAILURE, type, shortName);
|
||||
}
|
||||
}
|
||||
|
||||
// property setters
|
||||
BeanWrapper beanWrapper = new BeanWrapperImpl(constraint);
|
||||
List<M2NamedValue> constraintNamedValues = m2Constraint.getParameters();
|
||||
|
||||
if (constraintNamedValues != null)
|
||||
{
|
||||
for (M2NamedValue namedValue : constraintNamedValues)
|
||||
{
|
||||
String namedValueName = namedValue.getName();
|
||||
// Check for reserved properties
|
||||
if (namedValueName.equals(PROP_SHORT_NAME))
|
||||
{
|
||||
throw new DictionaryException(ERR_RESERVED_PROPERTY, PROP_SHORT_NAME, namedValueName);
|
||||
}
|
||||
|
||||
Object value = null;
|
||||
if (namedValue.getSimpleValue() != null && namedValue.getListValue() != null)
|
||||
{
|
||||
throw new DictionaryException(ERR_SIMPLE_AND_LIST, shortName, namedValue.getName());
|
||||
}
|
||||
else if (namedValue.getSimpleValue() != null)
|
||||
{
|
||||
value = namedValue.getSimpleValue();
|
||||
}
|
||||
else if (namedValue.getListValue() != null)
|
||||
{
|
||||
value = namedValue.getListValue();
|
||||
}
|
||||
try
|
||||
{
|
||||
beanWrapper.setPropertyValue(namedValueName, value);
|
||||
}
|
||||
catch (PropertyAccessException e)
|
||||
{
|
||||
throw new DictionaryException(ERR_PROPERTY_MISMATCH, e, namedValueName, shortName);
|
||||
}
|
||||
catch (InvalidPropertyException e)
|
||||
{
|
||||
throw new DictionaryException(ERR_PROPERTY_MISMATCH, e, namedValueName, shortName);
|
||||
}
|
||||
}
|
||||
|
||||
// Pass in the short name as a special property, if it is available
|
||||
if (beanWrapper.isWritableProperty(PROP_SHORT_NAME))
|
||||
{
|
||||
try
|
||||
{
|
||||
beanWrapper.setPropertyValue(PROP_SHORT_NAME, shortName);
|
||||
}
|
||||
catch (PropertyAccessException e)
|
||||
{
|
||||
throw new DictionaryException(ERR_PROPERTY_MISMATCH, e, shortName, shortName);
|
||||
}
|
||||
catch (InvalidPropertyException e)
|
||||
{
|
||||
throw new DictionaryException(ERR_PROPERTY_MISMATCH, e, shortName, shortName);
|
||||
}
|
||||
}
|
||||
|
||||
if ((title != null) && (beanWrapper.isWritableProperty(PROP_TITLE)))
|
||||
{
|
||||
beanWrapper.setPropertyValue(PROP_TITLE, title);
|
||||
}
|
||||
|
||||
if ((title != null) && (beanWrapper.isWritableProperty(PROP_DESCRIPTION)))
|
||||
{
|
||||
beanWrapper.setPropertyValue(PROP_DESCRIPTION, description);
|
||||
}
|
||||
}
|
||||
|
||||
// now initialize
|
||||
constraint.initialize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getName()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getName().toString();
|
||||
}
|
||||
|
||||
public ModelDefinition getModel()
|
||||
{
|
||||
return model;
|
||||
}
|
||||
|
||||
public QName getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getTitle()
|
||||
{
|
||||
String value = M2Label.getLabel(model, "constraint", name, "title");
|
||||
if (value == null)
|
||||
{
|
||||
value = m2Constraint.getTitle();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
String value = M2Label.getLabel(model, "constraint", name, "description");
|
||||
if (value == null)
|
||||
{
|
||||
value = m2Constraint.getDescription();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public Constraint getConstraint()
|
||||
{
|
||||
return constraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Well-known constraint types
|
||||
*/
|
||||
public static enum ConstraintType
|
||||
{
|
||||
REGISTERED
|
||||
{
|
||||
@Override
|
||||
protected Constraint newInstance()
|
||||
{
|
||||
return new RegisteredConstraint();
|
||||
}
|
||||
},
|
||||
REGEX
|
||||
{
|
||||
@Override
|
||||
protected Constraint newInstance()
|
||||
{
|
||||
return new RegexConstraint();
|
||||
}
|
||||
},
|
||||
MINMAX
|
||||
{
|
||||
@Override
|
||||
protected Constraint newInstance()
|
||||
{
|
||||
return new NumericRangeConstraint();
|
||||
}
|
||||
},
|
||||
LENGTH
|
||||
{
|
||||
@Override
|
||||
protected Constraint newInstance()
|
||||
{
|
||||
return new StringLengthConstraint();
|
||||
}
|
||||
},
|
||||
LIST
|
||||
{
|
||||
@Override
|
||||
protected Constraint newInstance()
|
||||
{
|
||||
return new ListOfValuesConstraint();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return Returns the constraint implementation
|
||||
*/
|
||||
protected abstract Constraint newInstance();
|
||||
}
|
||||
}
|
||||
|
@@ -1,402 +1,432 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.dictionary;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryException;
|
||||
import org.jibx.runtime.BindingDirectory;
|
||||
import org.jibx.runtime.IBindingFactory;
|
||||
import org.jibx.runtime.IMarshallingContext;
|
||||
import org.jibx.runtime.IUnmarshallingContext;
|
||||
import org.jibx.runtime.JiBXException;
|
||||
|
||||
|
||||
/**
|
||||
* Model Definition.
|
||||
*
|
||||
* @author David Caruana
|
||||
*
|
||||
*/
|
||||
public class M2Model
|
||||
{
|
||||
private String name = null;
|
||||
private String description = null;
|
||||
private String author = null;
|
||||
private Date published = null;
|
||||
private String version;
|
||||
|
||||
private List<M2Namespace> namespaces = new ArrayList<M2Namespace>();
|
||||
private List<M2Namespace> imports = new ArrayList<M2Namespace>();
|
||||
private List<M2DataType> dataTypes = new ArrayList<M2DataType>();
|
||||
private List<M2Type> types = new ArrayList<M2Type>();
|
||||
private List<M2Aspect> aspects = new ArrayList<M2Aspect>();
|
||||
private List<M2Constraint> constraints = new ArrayList<M2Constraint>();
|
||||
|
||||
private M2Model()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct an empty model
|
||||
*
|
||||
* @param name the name of the model
|
||||
* @return the model
|
||||
*/
|
||||
public static M2Model createModel(String name)
|
||||
{
|
||||
M2Model model = new M2Model();
|
||||
model.name = name;
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct a model from a dictionary xml specification
|
||||
*
|
||||
* @param xml the dictionary xml
|
||||
* @return the model representation of the xml
|
||||
*/
|
||||
public static M2Model createModel(InputStream xml)
|
||||
{
|
||||
try
|
||||
{
|
||||
IBindingFactory factory = BindingDirectory.getFactory(M2Model.class);
|
||||
IUnmarshallingContext context = factory.createUnmarshallingContext();
|
||||
Object obj = context.unmarshalDocument(xml, null);
|
||||
return (M2Model)obj;
|
||||
}
|
||||
catch(JiBXException e)
|
||||
{
|
||||
throw new DictionaryException("Failed to parse model", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render the model to dictionary XML
|
||||
*
|
||||
* @param xml the dictionary xml representation of the model
|
||||
*/
|
||||
public void toXML(OutputStream xml)
|
||||
{
|
||||
try
|
||||
{
|
||||
IBindingFactory factory = BindingDirectory.getFactory(M2Model.class);
|
||||
IMarshallingContext context = factory.createMarshallingContext();
|
||||
context.setIndent(4);
|
||||
context.marshalDocument(this, "UTF-8", null, xml);
|
||||
}
|
||||
catch(JiBXException e)
|
||||
{
|
||||
throw new DictionaryException("Failed to create M2 Model", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a compiled form of this model
|
||||
*
|
||||
* @param dictionaryDAO dictionary DAO
|
||||
* @param namespaceDAO namespace DAO
|
||||
* @return the compiled form of the model
|
||||
*/
|
||||
/*package*/ CompiledModel compile(DictionaryDAO dictionaryDAO, NamespaceDAO namespaceDAO)
|
||||
{
|
||||
CompiledModel compiledModel = new CompiledModel(this, dictionaryDAO, namespaceDAO);
|
||||
return compiledModel;
|
||||
}
|
||||
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
public void setDescription(String description)
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
public String getAuthor()
|
||||
{
|
||||
return author;
|
||||
}
|
||||
|
||||
|
||||
public void setAuthor(String author)
|
||||
{
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
|
||||
public Date getPublishedDate()
|
||||
{
|
||||
return published;
|
||||
}
|
||||
|
||||
|
||||
public void setPublishedDate(Date published)
|
||||
{
|
||||
this.published = published;
|
||||
}
|
||||
|
||||
|
||||
public String getVersion()
|
||||
{
|
||||
return version;
|
||||
}
|
||||
|
||||
|
||||
public void setVersion(String version)
|
||||
{
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
|
||||
public M2Type createType(String name)
|
||||
{
|
||||
M2Type type = new M2Type();
|
||||
type.setName(name);
|
||||
types.add(type);
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
public void removeType(String name)
|
||||
{
|
||||
M2Type type = getType(name);
|
||||
if (type != null)
|
||||
{
|
||||
types.remove(type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<M2Type> getTypes()
|
||||
{
|
||||
return Collections.unmodifiableList(types);
|
||||
}
|
||||
|
||||
|
||||
public M2Type getType(String name)
|
||||
{
|
||||
for (M2Type candidate : types)
|
||||
{
|
||||
if (candidate.getName().equals(name))
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public M2Aspect createAspect(String name)
|
||||
{
|
||||
M2Aspect aspect = new M2Aspect();
|
||||
aspect.setName(name);
|
||||
aspects.add(aspect);
|
||||
return aspect;
|
||||
}
|
||||
|
||||
|
||||
public void removeAspect(String name)
|
||||
{
|
||||
M2Aspect aspect = getAspect(name);
|
||||
if (aspect != null)
|
||||
{
|
||||
aspects.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<M2Aspect> getAspects()
|
||||
{
|
||||
return Collections.unmodifiableList(aspects);
|
||||
}
|
||||
|
||||
|
||||
public M2Aspect getAspect(String name)
|
||||
{
|
||||
for (M2Aspect candidate : aspects)
|
||||
{
|
||||
if (candidate.getName().equals(name))
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public M2DataType createPropertyType(String name)
|
||||
{
|
||||
M2DataType type = new M2DataType();
|
||||
type .setName(name);
|
||||
dataTypes.add(type);
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
public void removePropertyType(String name)
|
||||
{
|
||||
M2DataType type = getPropertyType(name);
|
||||
if (type != null)
|
||||
{
|
||||
dataTypes.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<M2DataType> getPropertyTypes()
|
||||
{
|
||||
return Collections.unmodifiableList(dataTypes);
|
||||
}
|
||||
|
||||
|
||||
public M2DataType getPropertyType(String name)
|
||||
{
|
||||
for (M2DataType candidate : dataTypes)
|
||||
{
|
||||
if (candidate.getName().equals(name))
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public M2Namespace createNamespace(String uri, String prefix)
|
||||
{
|
||||
M2Namespace namespace = new M2Namespace();
|
||||
namespace.setUri(uri);
|
||||
namespace.setPrefix(prefix);
|
||||
namespaces.add(namespace);
|
||||
return namespace;
|
||||
}
|
||||
|
||||
|
||||
public void removeNamespace(String uri)
|
||||
{
|
||||
M2Namespace namespace = getNamespace(uri);
|
||||
if (namespace != null)
|
||||
{
|
||||
namespaces.remove(namespace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<M2Namespace> getNamespaces()
|
||||
{
|
||||
return Collections.unmodifiableList(namespaces);
|
||||
}
|
||||
|
||||
|
||||
public M2Namespace getNamespace(String uri)
|
||||
{
|
||||
for (M2Namespace candidate : namespaces)
|
||||
{
|
||||
if (candidate.getUri().equals(uri))
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public M2Namespace createImport(String uri, String prefix)
|
||||
{
|
||||
M2Namespace namespace = new M2Namespace();
|
||||
namespace.setUri(uri);
|
||||
namespace.setPrefix(prefix);
|
||||
imports.add(namespace);
|
||||
return namespace;
|
||||
}
|
||||
|
||||
|
||||
public void removeImport(String uri)
|
||||
{
|
||||
M2Namespace namespace = getImport(uri);
|
||||
if (namespace != null)
|
||||
{
|
||||
imports.remove(namespace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<M2Namespace> getImports()
|
||||
{
|
||||
return Collections.unmodifiableList(imports);
|
||||
}
|
||||
|
||||
|
||||
public M2Namespace getImport(String uri)
|
||||
{
|
||||
for (M2Namespace candidate : imports)
|
||||
{
|
||||
if (candidate.getUri().equals(uri))
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<M2Constraint> getConstraints()
|
||||
{
|
||||
return Collections.unmodifiableList(constraints);
|
||||
}
|
||||
|
||||
// Do not delete: referenced by m2binding.xml
|
||||
@SuppressWarnings("unused")
|
||||
private static List createList()
|
||||
{
|
||||
return new ArrayList();
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.dictionary;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryException;
|
||||
import org.jibx.runtime.BindingDirectory;
|
||||
import org.jibx.runtime.IBindingFactory;
|
||||
import org.jibx.runtime.IMarshallingContext;
|
||||
import org.jibx.runtime.IUnmarshallingContext;
|
||||
import org.jibx.runtime.JiBXException;
|
||||
|
||||
|
||||
/**
|
||||
* Model Definition.
|
||||
*
|
||||
* @author David Caruana
|
||||
*
|
||||
*/
|
||||
public class M2Model
|
||||
{
|
||||
private String name = null;
|
||||
private String description = null;
|
||||
private String author = null;
|
||||
private Date published = null;
|
||||
private String version;
|
||||
|
||||
private List<M2Namespace> namespaces = new ArrayList<M2Namespace>();
|
||||
private List<M2Namespace> imports = new ArrayList<M2Namespace>();
|
||||
private List<M2DataType> dataTypes = new ArrayList<M2DataType>();
|
||||
private List<M2Type> types = new ArrayList<M2Type>();
|
||||
private List<M2Aspect> aspects = new ArrayList<M2Aspect>();
|
||||
private List<M2Constraint> constraints = new ArrayList<M2Constraint>();
|
||||
|
||||
private M2Model()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct an empty model
|
||||
*
|
||||
* @param name the name of the model
|
||||
* @return the model
|
||||
*/
|
||||
public static M2Model createModel(String name)
|
||||
{
|
||||
M2Model model = new M2Model();
|
||||
model.name = name;
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct a model from a dictionary xml specification
|
||||
*
|
||||
* @param xml the dictionary xml
|
||||
* @return the model representation of the xml
|
||||
*/
|
||||
public static M2Model createModel(InputStream xml)
|
||||
{
|
||||
try
|
||||
{
|
||||
IBindingFactory factory = BindingDirectory.getFactory(M2Model.class);
|
||||
IUnmarshallingContext context = factory.createUnmarshallingContext();
|
||||
Object obj = context.unmarshalDocument(xml, null);
|
||||
return (M2Model)obj;
|
||||
}
|
||||
catch(JiBXException e)
|
||||
{
|
||||
throw new DictionaryException("Failed to parse model", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render the model to dictionary XML
|
||||
*
|
||||
* @param xml the dictionary xml representation of the model
|
||||
*/
|
||||
public void toXML(OutputStream xml)
|
||||
{
|
||||
try
|
||||
{
|
||||
IBindingFactory factory = BindingDirectory.getFactory(M2Model.class);
|
||||
IMarshallingContext context = factory.createMarshallingContext();
|
||||
context.setIndent(4);
|
||||
context.marshalDocument(this, "UTF-8", null, xml);
|
||||
}
|
||||
catch(JiBXException e)
|
||||
{
|
||||
throw new DictionaryException("Failed to create M2 Model", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a compiled form of this model
|
||||
*
|
||||
* @param dictionaryDAO dictionary DAO
|
||||
* @param namespaceDAO namespace DAO
|
||||
* @return the compiled form of the model
|
||||
*/
|
||||
/*package*/ CompiledModel compile(DictionaryDAO dictionaryDAO, NamespaceDAO namespaceDAO)
|
||||
{
|
||||
CompiledModel compiledModel = new CompiledModel(this, dictionaryDAO, namespaceDAO);
|
||||
return compiledModel;
|
||||
}
|
||||
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
public void setDescription(String description)
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
public String getAuthor()
|
||||
{
|
||||
return author;
|
||||
}
|
||||
|
||||
|
||||
public void setAuthor(String author)
|
||||
{
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
|
||||
public Date getPublishedDate()
|
||||
{
|
||||
return published;
|
||||
}
|
||||
|
||||
|
||||
public void setPublishedDate(Date published)
|
||||
{
|
||||
this.published = published;
|
||||
}
|
||||
|
||||
|
||||
public String getVersion()
|
||||
{
|
||||
return version;
|
||||
}
|
||||
|
||||
|
||||
public void setVersion(String version)
|
||||
{
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
|
||||
public M2Type createType(String name)
|
||||
{
|
||||
M2Type type = new M2Type();
|
||||
type.setName(name);
|
||||
types.add(type);
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
public void removeType(String name)
|
||||
{
|
||||
M2Type type = getType(name);
|
||||
if (type != null)
|
||||
{
|
||||
types.remove(type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<M2Type> getTypes()
|
||||
{
|
||||
return Collections.unmodifiableList(types);
|
||||
}
|
||||
|
||||
|
||||
public M2Type getType(String name)
|
||||
{
|
||||
for (M2Type candidate : types)
|
||||
{
|
||||
if (candidate.getName().equals(name))
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public M2Aspect createAspect(String name)
|
||||
{
|
||||
M2Aspect aspect = new M2Aspect();
|
||||
aspect.setName(name);
|
||||
aspects.add(aspect);
|
||||
return aspect;
|
||||
}
|
||||
|
||||
|
||||
public void removeAspect(String name)
|
||||
{
|
||||
M2Aspect aspect = getAspect(name);
|
||||
if (aspect != null)
|
||||
{
|
||||
aspects.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<M2Aspect> getAspects()
|
||||
{
|
||||
return Collections.unmodifiableList(aspects);
|
||||
}
|
||||
|
||||
|
||||
public M2Aspect getAspect(String name)
|
||||
{
|
||||
for (M2Aspect candidate : aspects)
|
||||
{
|
||||
if (candidate.getName().equals(name))
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public M2DataType createPropertyType(String name)
|
||||
{
|
||||
M2DataType type = new M2DataType();
|
||||
type.setName(name);
|
||||
dataTypes.add(type);
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
public void removePropertyType(String name)
|
||||
{
|
||||
M2DataType type = getPropertyType(name);
|
||||
if (type != null)
|
||||
{
|
||||
dataTypes.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<M2DataType> getPropertyTypes()
|
||||
{
|
||||
return Collections.unmodifiableList(dataTypes);
|
||||
}
|
||||
|
||||
|
||||
public M2DataType getPropertyType(String name)
|
||||
{
|
||||
for (M2DataType candidate : dataTypes)
|
||||
{
|
||||
if (candidate.getName().equals(name))
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public M2Namespace createNamespace(String uri, String prefix)
|
||||
{
|
||||
M2Namespace namespace = new M2Namespace();
|
||||
namespace.setUri(uri);
|
||||
namespace.setPrefix(prefix);
|
||||
namespaces.add(namespace);
|
||||
return namespace;
|
||||
}
|
||||
|
||||
|
||||
public void removeNamespace(String uri)
|
||||
{
|
||||
M2Namespace namespace = getNamespace(uri);
|
||||
if (namespace != null)
|
||||
{
|
||||
namespaces.remove(namespace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<M2Namespace> getNamespaces()
|
||||
{
|
||||
return Collections.unmodifiableList(namespaces);
|
||||
}
|
||||
|
||||
|
||||
public M2Namespace getNamespace(String uri)
|
||||
{
|
||||
for (M2Namespace candidate : namespaces)
|
||||
{
|
||||
if (candidate.getUri().equals(uri))
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public M2Namespace createImport(String uri, String prefix)
|
||||
{
|
||||
M2Namespace namespace = new M2Namespace();
|
||||
namespace.setUri(uri);
|
||||
namespace.setPrefix(prefix);
|
||||
imports.add(namespace);
|
||||
return namespace;
|
||||
}
|
||||
|
||||
|
||||
public void removeImport(String uri)
|
||||
{
|
||||
M2Namespace namespace = getImport(uri);
|
||||
if (namespace != null)
|
||||
{
|
||||
imports.remove(namespace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<M2Namespace> getImports()
|
||||
{
|
||||
return Collections.unmodifiableList(imports);
|
||||
}
|
||||
|
||||
|
||||
public M2Namespace getImport(String uri)
|
||||
{
|
||||
for (M2Namespace candidate : imports)
|
||||
{
|
||||
if (candidate.getUri().equals(uri))
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<M2Constraint> getConstraints()
|
||||
{
|
||||
return Collections.unmodifiableList(constraints);
|
||||
}
|
||||
|
||||
public M2Constraint getConstraint(String name)
|
||||
{
|
||||
for (M2Constraint candidate : constraints)
|
||||
{
|
||||
if (candidate.getName().equals(name))
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public M2Constraint createConstraint(String name, String type)
|
||||
{
|
||||
M2Constraint constraint = new M2Constraint();
|
||||
constraint.setName(name);
|
||||
constraint.setType(type);
|
||||
constraints.add(constraint);
|
||||
return constraint;
|
||||
}
|
||||
|
||||
public void removeConstraint(String name)
|
||||
{
|
||||
M2Constraint constraint = getConstraint(name);
|
||||
if (constraint != null)
|
||||
{
|
||||
constraints.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
// Do not delete: referenced by m2binding.xml
|
||||
@SuppressWarnings("unused")
|
||||
private static List createList()
|
||||
{
|
||||
return new ArrayList();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,71 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.dictionary;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Definition of a named value that can be used for property injection.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class M2NamedValue
|
||||
{
|
||||
private String name;
|
||||
private String simpleValue = null;
|
||||
private List<String> listValue = null;
|
||||
|
||||
/*package*/ M2NamedValue()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return (name + "=" + (simpleValue == null ? listValue : simpleValue));
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the raw, unconverted value
|
||||
*/
|
||||
public String getSimpleValue()
|
||||
{
|
||||
return simpleValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the list of raw, unconverted values
|
||||
*/
|
||||
public List<String> getListValue()
|
||||
{
|
||||
return listValue;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.dictionary;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Definition of a named value that can be used for property injection.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class M2NamedValue
|
||||
{
|
||||
private String name;
|
||||
private String simpleValue = null;
|
||||
private List<String> listValue = null;
|
||||
|
||||
/*package*/ M2NamedValue()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return (name + "=" + (simpleValue == null ? listValue : simpleValue));
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the raw, unconverted value
|
||||
*/
|
||||
public String getSimpleValue()
|
||||
{
|
||||
return simpleValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the list of raw, unconverted values
|
||||
*/
|
||||
public List<String> getListValue()
|
||||
{
|
||||
return listValue;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setSimpleValue(String simpleValue)
|
||||
{
|
||||
this.simpleValue = simpleValue;
|
||||
}
|
||||
|
||||
public void setListValue(List<String> listValue)
|
||||
{
|
||||
this.listValue = listValue;
|
||||
}
|
||||
|
||||
public boolean hasSimpleValue()
|
||||
{
|
||||
return (this.simpleValue != null);
|
||||
}
|
||||
|
||||
public boolean hasListValue()
|
||||
{
|
||||
return (this.listValue != null);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,197 +1,209 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.dictionary.constraint;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.Constraint;
|
||||
import org.alfresco.service.cmr.dictionary.ConstraintException;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryException;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
|
||||
/**
|
||||
* Base services for constraints.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public abstract class AbstractConstraint implements Constraint
|
||||
{
|
||||
public static final String ERR_PROP_NOT_SET = "d_dictionary.constraint.err.property_not_set";
|
||||
public static final String ERR_EVALUATE_EXCEPTION = "d_dictionary.constraint.err.evaluate_exception";
|
||||
|
||||
|
||||
/** The constraint name. May be useful in error messages */
|
||||
private String shortName;
|
||||
private ConstraintRegistry registry;
|
||||
|
||||
/**
|
||||
* Sets the constraint name. Automatically called after construction. Please excuse the strange method name as we
|
||||
* want the property name to begin with an underscore to avoid property name clashes.
|
||||
*
|
||||
* @param shortName
|
||||
* @deprecated
|
||||
*/
|
||||
public void set_shortName(String shortName)
|
||||
{
|
||||
setShortName(shortName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the constraint name
|
||||
* @param name
|
||||
*/
|
||||
public void setShortName(String name)
|
||||
{
|
||||
this.shortName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the constraint name.
|
||||
*
|
||||
* @return the constraint name.
|
||||
*/
|
||||
public String getShortName()
|
||||
{
|
||||
return this.shortName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally specify the registry that will be used to register the constraint.
|
||||
* This is used when instantiating constraints outside the dictionary.
|
||||
*
|
||||
* @param registry the constraint registry
|
||||
*/
|
||||
public void setRegistry(ConstraintRegistry registry)
|
||||
{
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
public String getType()
|
||||
{
|
||||
return this.getClass().getName();
|
||||
}
|
||||
|
||||
public Map<String, Object> getParameters()
|
||||
{
|
||||
return new HashMap<String, Object>(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
* Registers the constraint with the registry, if present. Call this method if
|
||||
* you want the constraint to be auto-registered.
|
||||
*/
|
||||
public void initialize()
|
||||
{
|
||||
if (registry != null)
|
||||
{
|
||||
registry.register(shortName, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the given value is not <tt>null</tt>.
|
||||
*
|
||||
* @param name the name of the property
|
||||
* @param value the value to check for <tt>null</tt>
|
||||
*
|
||||
* @throws DictionaryException if the the property is null
|
||||
*/
|
||||
protected void checkPropertyNotNull(String name, Object value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new DictionaryException(AbstractConstraint.ERR_PROP_NOT_SET, name, getShortName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #evaluateSingleValue(Object)
|
||||
* @see #evaluateCollection(Collection)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public final void evaluate(Object value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
// null values are never evaluated
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
// ensure that we can handle collections
|
||||
if (DefaultTypeConverter.INSTANCE.isMultiValued(value))
|
||||
{
|
||||
Collection collection = DefaultTypeConverter.INSTANCE.getCollection(Object.class, value);
|
||||
evaluateCollection(collection);
|
||||
}
|
||||
else
|
||||
{
|
||||
evaluateSingleValue(value);
|
||||
}
|
||||
}
|
||||
catch (ConstraintException e)
|
||||
{
|
||||
// this can go
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
throw new DictionaryException(AbstractConstraint.ERR_EVALUATE_EXCEPTION, this, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only override if there is some specific evaluation that needs to be performed on the
|
||||
* collection as a whole.
|
||||
*
|
||||
* @param collection the collection of values to evaluate
|
||||
*
|
||||
* @see #evaluateSingleValue(Object)
|
||||
*/
|
||||
protected void evaluateCollection(Collection<Object> collection)
|
||||
{
|
||||
for (Object value : collection)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
// contract states that it will always pass
|
||||
continue;
|
||||
}
|
||||
evaluateSingleValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Support for evaluation of properties. The value passed in will never be a
|
||||
* <tt>Collection</tt> and will never be <tt>null</tt>.
|
||||
*
|
||||
* @throws ConstraintException throw this when the evaluation fails
|
||||
*/
|
||||
protected abstract void evaluateSingleValue(Object value);
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.dictionary.constraint;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.Constraint;
|
||||
import org.alfresco.service.cmr.dictionary.ConstraintException;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryException;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
|
||||
/**
|
||||
* Base services for constraints.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public abstract class AbstractConstraint implements Constraint
|
||||
{
|
||||
public static final String ERR_PROP_NOT_SET = "d_dictionary.constraint.err.property_not_set";
|
||||
public static final String ERR_EVALUATE_EXCEPTION = "d_dictionary.constraint.err.evaluate_exception";
|
||||
|
||||
|
||||
/** The constraint name. May be useful in error messages */
|
||||
private String shortName;
|
||||
private String title;
|
||||
|
||||
private ConstraintRegistry registry;
|
||||
|
||||
/**
|
||||
* Sets the constraint name. Automatically called after construction. Please excuse the strange method name as we
|
||||
* want the property name to begin with an underscore to avoid property name clashes.
|
||||
*
|
||||
* @param shortName
|
||||
* @deprecated
|
||||
*/
|
||||
public void set_shortName(String shortName)
|
||||
{
|
||||
setShortName(shortName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the constraint name
|
||||
* @param name
|
||||
*/
|
||||
public void setShortName(String name)
|
||||
{
|
||||
this.shortName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the constraint name.
|
||||
*
|
||||
* @return the constraint name.
|
||||
*/
|
||||
public String getShortName()
|
||||
{
|
||||
return this.shortName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally specify the registry that will be used to register the constraint.
|
||||
* This is used when instantiating constraints outside the dictionary.
|
||||
*
|
||||
* @param registry the constraint registry
|
||||
*/
|
||||
public void setRegistry(ConstraintRegistry registry)
|
||||
{
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
public String getType()
|
||||
{
|
||||
return this.getClass().getName();
|
||||
}
|
||||
|
||||
public void setTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getTitle()
|
||||
{
|
||||
return title;
|
||||
}
|
||||
|
||||
public Map<String, Object> getParameters()
|
||||
{
|
||||
return new HashMap<String, Object>(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
* Registers the constraint with the registry, if present. Call this method if
|
||||
* you want the constraint to be auto-registered.
|
||||
*/
|
||||
public void initialize()
|
||||
{
|
||||
if (registry != null)
|
||||
{
|
||||
registry.register(shortName, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the given value is not <tt>null</tt>.
|
||||
*
|
||||
* @param name the name of the property
|
||||
* @param value the value to check for <tt>null</tt>
|
||||
*
|
||||
* @throws DictionaryException if the the property is null
|
||||
*/
|
||||
protected void checkPropertyNotNull(String name, Object value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new DictionaryException(AbstractConstraint.ERR_PROP_NOT_SET, name, getShortName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #evaluateSingleValue(Object)
|
||||
* @see #evaluateCollection(Collection)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public final void evaluate(Object value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
// null values are never evaluated
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
// ensure that we can handle collections
|
||||
if (DefaultTypeConverter.INSTANCE.isMultiValued(value))
|
||||
{
|
||||
Collection collection = DefaultTypeConverter.INSTANCE.getCollection(Object.class, value);
|
||||
evaluateCollection(collection);
|
||||
}
|
||||
else
|
||||
{
|
||||
evaluateSingleValue(value);
|
||||
}
|
||||
}
|
||||
catch (ConstraintException e)
|
||||
{
|
||||
// this can go
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
throw new DictionaryException(AbstractConstraint.ERR_EVALUATE_EXCEPTION, this, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only override if there is some specific evaluation that needs to be performed on the
|
||||
* collection as a whole.
|
||||
*
|
||||
* @param collection the collection of values to evaluate
|
||||
*
|
||||
* @see #evaluateSingleValue(Object)
|
||||
*/
|
||||
protected void evaluateCollection(Collection<Object> collection)
|
||||
{
|
||||
for (Object value : collection)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
// contract states that it will always pass
|
||||
continue;
|
||||
}
|
||||
evaluateSingleValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Support for evaluation of properties. The value passed in will never be a
|
||||
* <tt>Collection</tt> and will never be <tt>null</tt>.
|
||||
*
|
||||
* @throws ConstraintException throw this when the evaluation fails
|
||||
*/
|
||||
protected abstract void evaluateSingleValue(Object value);
|
||||
}
|
||||
|
@@ -109,6 +109,14 @@ public final class RegisteredConstraint implements Constraint
|
||||
return getConstraint().getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defers to the registered constraint
|
||||
*/
|
||||
public String getTitle()
|
||||
{
|
||||
return getConstraint().getTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defers to the registered constraint
|
||||
*/
|
||||
|
@@ -30,6 +30,8 @@
|
||||
<parameter name="registeredName"><value>cm:reg2</value></parameter>
|
||||
</constraint>
|
||||
<constraint name="test:regex1" type="REGEX">
|
||||
<title>Regex1 title</title>
|
||||
<description>Regex1 description</description>
|
||||
<parameter name="expression"><value>[A-Z]*</value></parameter>
|
||||
<parameter name="requiresMatch"><value>false</value></parameter>
|
||||
</constraint>
|
||||
@@ -74,7 +76,10 @@
|
||||
<default></default>
|
||||
<constraints>
|
||||
<constraint ref="test:regex1"/>
|
||||
<constraint ref="test:stringLength1"/>
|
||||
<constraint ref="test:stringLength1">
|
||||
<title>Prop1 Strlen1 title</title>
|
||||
<description>Prop1 Strlen1 description</description>
|
||||
</constraint>
|
||||
<constraint ref="test:registered1"/>
|
||||
</constraints>
|
||||
</property>
|
||||
|
@@ -122,8 +122,8 @@
|
||||
|
||||
<mapping abstract="true" class="org.alfresco.repo.dictionary.M2NamedValue">
|
||||
<value style="attribute" name="name" field="name" />
|
||||
<value name="value" field="simpleValue" usage="optional" />
|
||||
<structure name="list" usage="optional">
|
||||
<value name="value" field="simpleValue" test-method="hasSimpleValue" usage="optional"/>
|
||||
<structure name="list" test-method="hasListValue" usage="optional">
|
||||
<collection field="listValue" factory="org.alfresco.repo.dictionary.M2Model.createList" usage="optional">
|
||||
<value name="value" style="element" usage="optional" type="java.lang.String"/>
|
||||
</collection>
|
||||
@@ -134,6 +134,7 @@
|
||||
<value style="attribute" name="name" field="name" usage="optional"/>
|
||||
<value style="attribute" name="type" field="type" usage="optional"/>
|
||||
<value style="attribute" name="ref" field="ref" usage="optional"/>
|
||||
<value name="title" field="title" usage="optional"/>
|
||||
<value name="description" field="description" usage="optional"/>
|
||||
<collection field="parameters" factory="org.alfresco.repo.dictionary.M2Model.createList" usage="optional">
|
||||
<structure name="parameter" type="org.alfresco.repo.dictionary.M2NamedValue" />
|
||||
|
@@ -1,81 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.service.cmr.dictionary;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* The interface for classes that implement constraints on property values.
|
||||
* <p>
|
||||
* Implementations of the actual constraint code should must not synchronize
|
||||
* or in any other way block threads. Concurrent access of the evaluation
|
||||
* method is expected, but will always occur after initialization has completed.
|
||||
* <p>
|
||||
* Attention to performance is <u>crucial</u> for all implementations as
|
||||
* instances of this class are heavily used.
|
||||
* <p>
|
||||
* The constraint implementations can provide standard setter methods that will
|
||||
* be populated by bean setter injection. Once all the available properties have
|
||||
* been set, the contraint will be initialized.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public interface Constraint
|
||||
{
|
||||
/**
|
||||
* Returns the 'type' of the constraint, this is the identifier given to
|
||||
* constraint in the configuration.
|
||||
*
|
||||
* @return The type
|
||||
*/
|
||||
public String getType();
|
||||
|
||||
/**
|
||||
* Returns the parameters passed to the instance of the constraint.
|
||||
*
|
||||
* @return Map of parameters or an empty <tt>Map</tt> if none exist
|
||||
*/
|
||||
public Map<String, Object> getParameters();
|
||||
|
||||
/**
|
||||
* Initializes the constraint with appropriate values, which will depend
|
||||
* on the implementation itself. This method can be implemented as a
|
||||
* once-off, i.e. reinitialization does not have to be supported.
|
||||
*
|
||||
* @param parameters constraint parameters
|
||||
*/
|
||||
public void initialize();
|
||||
|
||||
/**
|
||||
* Evaluates a property value according to the implementation and initialization
|
||||
* parameters provided.
|
||||
*
|
||||
* @param value the property value to check
|
||||
*
|
||||
* @throws ConstraintException if the value doesn't pass all constraints
|
||||
*/
|
||||
public void evaluate(Object value);
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.service.cmr.dictionary;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* The interface for classes that implement constraints on property values.
|
||||
* <p>
|
||||
* Implementations of the actual constraint code should must not synchronize
|
||||
* or in any other way block threads. Concurrent access of the evaluation
|
||||
* method is expected, but will always occur after initialization has completed.
|
||||
* <p>
|
||||
* Attention to performance is <u>crucial</u> for all implementations as
|
||||
* instances of this class are heavily used.
|
||||
* <p>
|
||||
* The constraint implementations can provide standard setter methods that will
|
||||
* be populated by bean setter injection. Once all the available properties have
|
||||
* been set, the contraint will be initialized.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public interface Constraint
|
||||
{
|
||||
/**
|
||||
* Returns the 'type' of the constraint, this is the identifier given to
|
||||
* constraint in the configuration.
|
||||
*
|
||||
* @return The type
|
||||
*/
|
||||
public String getType();
|
||||
|
||||
/**
|
||||
* @return the human-readable constraint title (optional)
|
||||
*/
|
||||
public String getTitle();
|
||||
|
||||
/**
|
||||
* Returns the parameters passed to the instance of the constraint.
|
||||
*
|
||||
* @return Map of parameters or an empty <tt>Map</tt> if none exist
|
||||
*/
|
||||
public Map<String, Object> getParameters();
|
||||
|
||||
/**
|
||||
* Initializes the constraint with appropriate values, which will depend
|
||||
* on the implementation itself. This method can be implemented as a
|
||||
* once-off, i.e. reinitialization does not have to be supported.
|
||||
*
|
||||
* @param parameters constraint parameters
|
||||
*/
|
||||
public void initialize();
|
||||
|
||||
/**
|
||||
* Evaluates a property value according to the implementation and initialization
|
||||
* parameters provided.
|
||||
*
|
||||
* @param value the property value to check
|
||||
*
|
||||
* @throws ConstraintException if the value doesn't pass all constraints
|
||||
*/
|
||||
public void evaluate(Object value);
|
||||
}
|
||||
|
@@ -1,50 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.service.cmr.dictionary;
|
||||
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Property constraint definition
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public interface ConstraintDefinition
|
||||
{
|
||||
/**
|
||||
* @return defining model
|
||||
*/
|
||||
public ModelDefinition getModel();
|
||||
|
||||
/**
|
||||
* @return Returns the qualified name of the constraint
|
||||
*/
|
||||
public QName getName();
|
||||
|
||||
/**
|
||||
* @return Returns the constraint implementation
|
||||
*/
|
||||
public Constraint getConstraint();
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.service.cmr.dictionary;
|
||||
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Property constraint definition
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public interface ConstraintDefinition
|
||||
{
|
||||
/**
|
||||
* @return defining model
|
||||
*/
|
||||
public ModelDefinition getModel();
|
||||
|
||||
/**
|
||||
* @return Returns the qualified name of the constraint
|
||||
*/
|
||||
public QName getName();
|
||||
|
||||
/**
|
||||
* @return the human-readable class title
|
||||
*/
|
||||
public String getTitle();
|
||||
|
||||
/**
|
||||
* @return the human-readable class description
|
||||
*/
|
||||
public String getDescription();
|
||||
|
||||
/**
|
||||
* @return Returns the constraint implementation
|
||||
*/
|
||||
public Constraint getConstraint();
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -25,6 +25,7 @@
|
||||
package org.alfresco.service.cmr.dictionary;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.NotAuditable;
|
||||
@@ -262,6 +263,14 @@ public interface DictionaryService
|
||||
@NotAuditable
|
||||
Collection<QName> getAllAssociations();
|
||||
|
||||
/**
|
||||
* Get constraints for the specified model
|
||||
*
|
||||
* @param model
|
||||
* @return
|
||||
*/
|
||||
public Collection<ConstraintDefinition> getConstraints(QName model);
|
||||
|
||||
// TODO: Behaviour definitions
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user