package org.openflexo.foundation.viewpoint.binding;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
import java.util.logging.Logger;
import org.openflexo.antar.binding.AbstractBinding.BindingEvaluationContext;
import org.openflexo.antar.binding.Bindable;
import org.openflexo.antar.binding.BindingPathElement;
import org.openflexo.antar.binding.BindingVariable;
import org.openflexo.antar.binding.SimpleBindingPathElementImpl;
import org.openflexo.antar.binding.SimplePathElement;
import org.openflexo.antar.binding.TypeUtils;
import org.openflexo.foundation.ontology.FlexoOntology;
import org.openflexo.foundation.ontology.IndividualOfClass;
import org.openflexo.foundation.ontology.OntologyClass;
import org.openflexo.foundation.ontology.OntologyDataProperty;
import org.openflexo.foundation.ontology.OntologyIndividual;
import org.openflexo.foundation.ontology.OntologyObject;
import org.openflexo.foundation.ontology.OntologyObjectProperty;
import org.openflexo.foundation.ontology.OntologyProperty;
import org.openflexo.foundation.ontology.SubClassOfClass;
import org.openflexo.foundation.ontology.dm.URIChanged;
import org.openflexo.foundation.ontology.dm.URINameChanged;
import org.openflexo.foundation.ontology.owl.OWL2URIDefinitions;
import org.openflexo.localization.FlexoLocalization;
public class OntologyObjectPathElement<T extends OntologyObject> implements SimplePathElement<T>, BindingVariable<T> {
private static final Logger logger = Logger.getLogger(OntologyObjectPathElement.class.getPackage().getName());
private String name;
private BindingPathElement parentElement;
private SimpleBindingPathElementImpl uriNameProperty;
private SimpleBindingPathElementImpl uriProperty;
protected List<BindingPathElement> allProperties;
private Vector<StatementPathElement> accessibleStatements;
private FlexoOntology viewpointOntology;
public static final int MAX_LEVELS = 3;
public OntologyObjectPathElement(String name, BindingPathElement aParentElement, FlexoOntology viewpointOntology) {
super();
this.name = name;
parentElement = aParentElement;
this.viewpointOntology = viewpointOntology;
allProperties = new Vector<BindingPathElement>();
accessibleStatements = new Vector<StatementPathElement>();
uriNameProperty = new SimpleBindingPathElementImpl<String>(URINameChanged.URI_NAME_KEY, TypeUtils.getBaseClass(getType()),
String.class, true, "uri_name_as_supplied_in_ontology") {
@Override
public String getBindingValue(Object target, BindingEvaluationContext context) {
return ((OntologyObject) target).getName();
}
@Override
public void setBindingValue(String value, Object target, BindingEvaluationContext context) {
if (target instanceof OntologyObject) {
try {
logger.info("Rename URI of object " + target + " with " + value);
((OntologyObject) target).setName(value);
} catch (Exception e) {
logger.warning("Unhandled exception: " + e);
e.printStackTrace();
}
} else {
logger.warning("Unexpected " + target);
}
}
};
allProperties.add(uriNameProperty);
uriProperty = new SimpleBindingPathElementImpl<String>(URIChanged.URI_KEY, TypeUtils.getBaseClass(getType()), String.class, false,
"uri_as_supplied_in_ontology") {
@Override
public String getBindingValue(Object target, BindingEvaluationContext context) {
return ((OntologyObject) target).getURI();
}
@Override
public void setBindingValue(String value, Object target, BindingEvaluationContext context) {
// not relevant because not settable
}
};
allProperties.add(uriProperty);
}
public List<BindingPathElement> getAllProperties() {
if (!propertiesFound) {
searchProperties(getOntologicType());
}
return allProperties;
}
boolean propertiesFound = false;
private void searchProperties(OntologyObject ontologicType) {
if (ontologicType != null) {
// System.out.println("Properties = "
// + ((IndividualPatternRole) getPatternRole()).getOntologicType().getPropertiesTakingMySelfAsDomain());
OntologyProperty[] array = ontologicType.getPropertiesTakingMySelfAsDomain().toArray(
new OntologyProperty[ontologicType.getPropertiesTakingMySelfAsDomain().size()]);
// Big trick here
// A property may shadow another one relatively from its name
// We try to detect such shadowing, and we put the most specialized property first
// TODO: This should be properly rewritten in OWLObject
List<Integer> i1 = new Vector<Integer>();
List<Integer> i2 = new Vector<Integer>();
for (int i = 0; i < array.length; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i].getName().equals(array[j].getName())) {
// Detected name based shadowing between array[i] and array[j]
// System.out.println("Detected name based shadowing between " + array[i] + " and " + array[j]);
if (array[i].getFlexoOntology().getAllImportedOntologies().contains(array[j].getFlexoOntology())) {
// array[i] appears to be the most specialized, don't do anything
} else if (array[j].getFlexoOntology().getAllImportedOntologies().contains(array[i].getFlexoOntology())) {
// array[j] appears to be the most specialized, we need to swap
i1.add(i);
i2.add(j);
}
}
}
}
for (int i = 0; i < i1.size(); i++) {
OntologyProperty p1 = array[i1.get(i)];
OntologyProperty p2 = array[i2.get(i)];
array[i1.get(i)] = p2;
array[i2.get(i)] = p1;
// Swapping p1 and p2
}
for (final OntologyProperty property : array) {
StatementPathElement<?> propertyPathElement = null;
if (property instanceof OntologyObjectProperty) {
propertyPathElement = ObjectPropertyStatementPathElement.makeObjectPropertyStatementPathElement(this,
(OntologyObjectProperty) property, true, OntologyObjectPathElement.MAX_LEVELS);
} else if (property instanceof OntologyDataProperty) {
propertyPathElement = new DataPropertyStatementPathElement(this, (OntologyDataProperty) property);
}
if (propertyPathElement != null) {
// System.out.println("add " + propertyPathElement);
accessibleStatements.add(propertyPathElement);
allProperties.add(propertyPathElement);
}
}
Collections.sort(allProperties, BindingPathElement.COMPARATOR);
propertiesFound = true;
}
}
public OntologyClass getOntologicType() {
if (getViewpointOntology() != null) {
return getViewpointOntology().getThingConcept();
}
return null;
}
@Override
public Class<? extends Bindable> getDeclaringClass() {
if (parentElement != null) {
return TypeUtils.getBaseClass(parentElement.getType());
}
return Bindable.class;
}
@Override
public String getSerializationRepresentation() {
return getLabel();
}
@Override
public boolean isBindingValid() {
return true;
}
@Override
public Type getType() {
return OntologyObject.class;
}
@Override
public String getLabel() {
return name;
}
@Override
public String getTooltipText(Type resultingType) {
return FlexoLocalization.localizedForKey("view_object");
}
@Override
public boolean isSettable() {
return false;
}
@Override
public T getBindingValue(Object target, BindingEvaluationContext context) {
logger.warning("Que dois-je renvoyer pour " + target);
return null;
}
@Override
public void setBindingValue(T value, Object target, BindingEvaluationContext context) {
// TODO Auto-generated method stub
}
@Override
public Bindable getContainer() {
return null;
}
@Override
public String getVariableName() {
return getLabel();
}
public FlexoOntology getViewpointOntology() {
return viewpointOntology;
}
public static class OntologyClassPathElement extends OntologyObjectPathElement<OntologyClass> {
private OntologyClass ontologyType;
public OntologyClassPathElement(String name, BindingPathElement aParentElement, FlexoOntology viewpointOntology) {
this(name, viewpointOntology.getThingConcept(), aParentElement, viewpointOntology);
}
public OntologyClassPathElement(String name, OntologyClass ontologyType, BindingPathElement aParentElement,
FlexoOntology viewpointOntology) {
super(name, aParentElement, viewpointOntology);
this.ontologyType = ontologyType;
/*accessibleStatements = new Vector<StatementPathElement>();
if (ontologyType != null) {
for (final OntologyProperty property : ontologyType.getPropertiesTakingMySelfAsDomain()) {
StatementPathElement propertyPathElement = null;
if (property instanceof OntologyObjectProperty) {
propertyPathElement = ObjectPropertyStatementPathElement.makeObjectPropertyStatementPathElement(this,
(OntologyObjectProperty) property, true, MAX_LEVELS);
} else if (property instanceof OntologyDataProperty) {
propertyPathElement = new DataPropertyStatementPathElement(this, (OntologyDataProperty) property);
}
if (propertyPathElement != null) {
accessibleStatements.add(propertyPathElement);
allProperties.add(propertyPathElement);
}
}
}*/
}
/*@Override
public Type getType() {
if (ontologyType != null) {
return SubClassOfClass.getSubClassOfClass(ontologyType);
}
return OntologyClass.class;
}*/
@Override
public Type getType() {
return SubClassOfClass.getSubClassOfClass(getOntologicType());
}
@Override
public OntologyClass getOntologicType() {
if (ontologyType != null) {
return ontologyType;
}
if (getViewpointOntology() != null) {
return getViewpointOntology().getThingConcept();
}
return null;
}
}
public static class OntologyIndividualPathElement extends OntologyObjectPathElement<OntologyIndividual> {
private OntologyClass ontologyType;
public OntologyIndividualPathElement(String name, BindingPathElement aParentElement, FlexoOntology viewpointOntology) {
this(name, null, aParentElement, viewpointOntology);
}
public OntologyIndividualPathElement(String name, OntologyClass ontologyType, BindingPathElement aParentElement,
FlexoOntology viewpointOntology) {
super(name, aParentElement, viewpointOntology);
this.ontologyType = ontologyType;
/*accessibleStatements = new Vector<StatementPathElement>();
if (ontologyType != null) {
for (final OntologyProperty property : ontologyType.getPropertiesTakingMySelfAsDomain()) {
StatementPathElement propertyPathElement = null;
if (property instanceof OntologyObjectProperty) {
propertyPathElement = ObjectPropertyStatementPathElement.makeObjectPropertyStatementPathElement(this,
(OntologyObjectProperty) property, true, MAX_LEVELS);
} else if (property instanceof OntologyDataProperty) {
propertyPathElement = new DataPropertyStatementPathElement(this, (OntologyDataProperty) property);
}
if (propertyPathElement != null) {
accessibleStatements.add(propertyPathElement);
allProperties.add(propertyPathElement);
}
}
}*/
}
@Override
public Type getType() {
return IndividualOfClass.getIndividualOfClass(getOntologicType());
}
@Override
public OntologyClass getOntologicType() {
if (ontologyType != null) {
return ontologyType;
}
if (getViewpointOntology() != null) {
return getViewpointOntology().getThingConcept();
}
return null;
}
}
public static abstract class OntologyPropertyPathElement<T extends OntologyProperty> extends OntologyObjectPathElement<T> {
public OntologyPropertyPathElement(String name, BindingPathElement aParentElement, FlexoOntology viewpointOntology) {
super(name, aParentElement, viewpointOntology);
}
@Override
public Type getType() {
return OntologyProperty.class;
}
}
public static class OntologyDataPropertyPathElement extends OntologyPropertyPathElement<OntologyDataProperty> {
public OntologyDataPropertyPathElement(String name, BindingPathElement aParentElement, FlexoOntology viewpointOntology) {
super(name, aParentElement, viewpointOntology);
}
@Override
public Type getType() {
return OntologyDataProperty.class;
}
@Override
public OntologyClass getOntologicType() {
if (getViewpointOntology() != null) {
return getViewpointOntology().getClass(OWL2URIDefinitions.OWL_DATA_PROPERTY_URI);
}
return null;
}
}
public static class OntologyObjectPropertyPathElement extends OntologyPropertyPathElement<OntologyObjectProperty> {
public OntologyObjectPropertyPathElement(String name, BindingPathElement aParentElement, FlexoOntology viewpointOntology) {
super(name, aParentElement, viewpointOntology);
}
@Override
public Type getType() {
return OntologyObjectProperty.class;
}
@Override
public OntologyClass getOntologicType() {
if (getViewpointOntology() != null) {
return getViewpointOntology().getClass(OWL2URIDefinitions.OWL_OBJECT_PROPERTY_URI);
}
return null;
}
}
}