/*
* Copyright (c) 2012 Data Harmonisation Panel
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution. If not, see <http://www.gnu.org/licenses/>.
*
* Contributors:
* HUMBOLDT EU Integrated Project #030962
* Data Harmonisation Panel <http://www.dhpanel.eu>
*/
package eu.esdihumboldt.hale.ui.service.entity.internal.tester;
import java.util.List;
import org.eclipse.core.expressions.IPropertyTester;
import org.eclipse.core.expressions.PropertyTester;
import org.eclipse.ui.PlatformUI;
import eu.esdihumboldt.hale.common.align.model.AlignmentUtil;
import eu.esdihumboldt.hale.common.align.model.ChildContext;
import eu.esdihumboldt.hale.common.align.model.EntityDefinition;
import eu.esdihumboldt.hale.common.schema.SchemaSpaceID;
import eu.esdihumboldt.hale.common.schema.model.ChildDefinition;
import eu.esdihumboldt.hale.common.schema.model.DefinitionUtil;
import eu.esdihumboldt.hale.common.schema.model.constraint.property.Cardinality;
import eu.esdihumboldt.hale.ui.service.align.AlignmentService;
/**
* Tester for properties related to instance contexts
*
* @author Simon Templer
* @since 2.5
*/
public class InstanceContextTester extends PropertyTester {
/**
* The property namespace for this tester.
*/
public static final String NAMESPACE = "eu.esdihumboldt.hale.ui.service.entity";
/**
* The property that specifies if adding a new named instance context is
* allowed.
*/
public static final String PROPERTY_ALLOW_ADD_NAMED = "allow_add_named";
/**
* The property that specifies if adding a new instance context index is
* allowed.
*/
public static final String PROPERTY_ALLOW_ADD_INDEX = "allow_add_index";
/**
* The property that specifies if adding a new condition context index is
* allowed.
*/
public static final String PROPERTY_ALLOW_ADD_CONDITION = "allow_add_condition";
/**
* The property that specifies if editing a condition context index is
* allowed.
*/
public static final String PROPERTY_ALLOW_EDIT_CONDITION = "allow_edit_condition";
/**
* The property that specifies if removing the instance context is allowed.
*/
public static final String PROPERTY_ALLOW_REMOVE = "allow_remove";
/**
* The property that specifies if an entity definition has a named context
* other than the default context.
*/
public static final String PROPERTY_NAMED_CONTEXT = "has_named_context";
/**
* The property that specifies if an entity definition has a context index.
*/
public static final String PROPERTY_INDEX_CONTEXT = "has_index_context";
/**
* The property that specifies if an entity definition has a condition
* context.
*/
public static final String PROPERTY_CONDITION_CONTEXT = "has_condition_context";
/**
* @see IPropertyTester#test(Object, String, Object[], Object)
*/
@Override
public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
if (receiver == null) {
return false;
}
if (property.equals(PROPERTY_ALLOW_ADD_NAMED) && receiver instanceof EntityDefinition) {
return testAllowAddNamed((EntityDefinition) receiver);
}
if (property.equals(PROPERTY_ALLOW_ADD_INDEX) && receiver instanceof EntityDefinition) {
return testAllowAddIndex((EntityDefinition) receiver);
}
if (property.equals(PROPERTY_ALLOW_ADD_CONDITION) && receiver instanceof EntityDefinition) {
return testAllowAddCondition((EntityDefinition) receiver);
}
if (property.equals(PROPERTY_ALLOW_EDIT_CONDITION)
&& receiver instanceof EntityDefinition) {
return testAllowEditCondition((EntityDefinition) receiver);
}
if (property.equals(PROPERTY_NAMED_CONTEXT) && receiver instanceof EntityDefinition) {
return testHasNamedContext((EntityDefinition) receiver);
}
if (property.equals(PROPERTY_INDEX_CONTEXT) && receiver instanceof EntityDefinition) {
return testHasIndexContext((EntityDefinition) receiver);
}
if (property.equals(PROPERTY_CONDITION_CONTEXT) && receiver instanceof EntityDefinition) {
return testHasConditionContext((EntityDefinition) receiver);
}
if (property.equals(PROPERTY_ALLOW_REMOVE) && receiver instanceof EntityDefinition) {
return testAllowRemove((EntityDefinition) receiver);
}
return false;
}
/**
* Test if for the given entity removing the instance context is allowed.
*
* @param entityDef the entity definition
* @return if removing the instance context is allowed
*/
private boolean testAllowRemove(EntityDefinition entityDef) {
if (!testHasNamedContext(entityDef) && !testHasIndexContext(entityDef)
&& !testHasConditionContext(entityDef)) {
return false;
}
// check if there are any alignment cells related to that context
AlignmentService as = PlatformUI.getWorkbench().getService(AlignmentService.class);
if (AlignmentUtil.entityOrChildMapped(entityDef, as.getAlignment())) {
return false;
}
return true;
}
/**
* Tests if for the given entity definition a new instance context may be
* created.
*
* @param entityDef the entity definition
* @return if adding an instance context is allowed
*/
private boolean testAllowAddNamed(EntityDefinition entityDef) {
if (entityDef.getSchemaSpace().equals(SchemaSpaceID.SOURCE)) {
// only allowed on target properties
return false;
}
// XXX for now only a simple test based on type and cardinality
List<ChildContext> path = entityDef.getPropertyPath();
if (path != null && !path.isEmpty()) {
ChildContext lastContext = path.get(path.size() - 1);
ChildDefinition<?> lastDef = lastContext.getChild();
// test type & cardinality
Cardinality cardinality;
try {
cardinality = DefinitionUtil.getCardinality(lastDef);
} catch (Exception e) {
return false;
}
if (cardinality.getMaxOccurs() == Cardinality.UNBOUNDED) {
return true;
}
return cardinality.getMaxOccurs() > 1;
}
// FIXME do a test through the entity definition service instead
return false;
}
/**
* Tests if for the given entity definition a new index context may be
* created.
*
* @param entityDef the entity definition
* @return if adding an index context is allowed
*/
private boolean testAllowAddIndex(EntityDefinition entityDef) {
if (entityDef.getSchemaSpace().equals(SchemaSpaceID.TARGET)) {
// only allowed on source properties
return false;
}
// XXX for now only a simple test based on type and cardinality
List<ChildContext> path = entityDef.getPropertyPath();
if (path != null && !path.isEmpty()) {
ChildContext lastContext = path.get(path.size() - 1);
ChildDefinition<?> lastDef = lastContext.getChild();
// test type & cardinality
Cardinality cardinality;
try {
cardinality = DefinitionUtil.getCardinality(lastDef);
} catch (Exception e) {
return false;
}
if (cardinality.getMaxOccurs() == Cardinality.UNBOUNDED) {
return true;
}
return cardinality.getMaxOccurs() > 1;
}
// FIXME do a test through the entity definition service instead
return false;
}
/**
* Tests if for the given entity definition a new condition context may be
* created.
*
* @param entityDef the entity definition
* @return if adding a condition context is allowed
*/
private boolean testAllowAddCondition(EntityDefinition entityDef) {
if (entityDef.getSchemaSpace().equals(SchemaSpaceID.TARGET)
&& entityDef.getPropertyPath().isEmpty()) {
// not allowed on target types
return false;
}
// FIXME for now adding conditions for target properties disabled
if (entityDef.getSchemaSpace().equals(SchemaSpaceID.TARGET)
&& !entityDef.getPropertyPath().isEmpty()) {
return false;
}
List<ChildContext> propertyPath = entityDef.getPropertyPath();
if (!propertyPath.isEmpty()
&& propertyPath.get(propertyPath.size() - 1).getChild().asProperty() == null) {
return false;
}
// FIXME do a test through the entity definition service instead
return true;
}
/**
* Tests if the condition context of the given entity definition may be
* edited.
*
* @param entityDef the entity definition
* @return if adding a condition context is allowed
*/
private boolean testAllowEditCondition(EntityDefinition entityDef) {
return testAllowAddCondition(entityDef)
&& AlignmentUtil.getContextCondition(entityDef) != null;
}
/**
* Tests if the given entity definition has a named instance context for the
* last path element that is not the default context.
*
* @param entityDef the entity definition
* @return if the entity definition has a named instance context for the
* last path element
*/
private boolean testHasNamedContext(EntityDefinition entityDef) {
return AlignmentUtil.getContextName(entityDef) != null;
}
/**
* Tests if the given entity definition has an index context for the last
* path element that is not the default context.
*
* @param entityDef the entity definition
* @return if the entity definition has an index context for the last path
* element
*/
private boolean testHasIndexContext(EntityDefinition entityDef) {
return AlignmentUtil.getContextIndex(entityDef) != null;
}
/**
* Tests if the given entity definition has a condition context for the last
* path element that is not the default context.
*
* @param entityDef the entity definition
* @return if the entity definition has a condition context for the last
* path element
*/
private boolean testHasConditionContext(EntityDefinition entityDef) {
return AlignmentUtil.getContextCondition(entityDef) != null;
}
}