package uk.ac.manchester.cs.jfact.datatypes; /* This file is part of the JFact DL reasoner Copyright 2011-2013 by Ignazio Palmisano, Dmitry Tsarkov, University of Manchester This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*/ import java.io.Serializable; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.semanticweb.owlapi.model.IRI; import uk.ac.manchester.cs.jfact.visitors.DLExpressionVisitor; import uk.ac.manchester.cs.jfact.visitors.DLExpressionVisitorEx; /** * @author ignazio * @param <R> * type */ public abstract class ABSTRACT_DATATYPE<R extends Comparable<R>> implements Datatype<R>, Serializable { private static final long serialVersionUID = 11000L; protected final Set<Facet> facets; protected Set<Datatype<?>> ancestors; @SuppressWarnings("rawtypes") protected final Map<Facet, Comparable> knownNumericFacetValues = new HashMap<Facet, Comparable>(); @SuppressWarnings("rawtypes") protected final Map<Facet, Comparable> knownNonNumericFacetValues = new HashMap<Facet, Comparable>(); protected final IRI uri; /** * @param u * u * @param f * facets */ public ABSTRACT_DATATYPE(IRI u, Set<Facet> f) { this.facets = Collections.unmodifiableSet(f); this.uri = u; } @Override public IRI getDatatypeIRI() { return this.uri; } @Override public IRI getName() { return IRI.create(toString()); } @Override public int hashCode() { return this.uri.hashCode(); } @Override public boolean equals(Object obj) { if (super.equals(obj)) { return true; } if (obj instanceof Datatype<?>) { return this.uri.equals(((Datatype<?>) obj).getDatatypeIRI()); } return false; } @Override public Collection<Datatype<?>> getAncestors() { return this.ancestors; } @Override public Set<Facet> getFacets() { return this.facets; } @SuppressWarnings("rawtypes") @Override public Map<Facet, Comparable> getKnownNumericFacetValues() { return this.knownNumericFacetValues; } @SuppressWarnings("rawtypes") @Override public Map<Facet, Comparable> getKnownNonNumericFacetValues() { return this.knownNonNumericFacetValues; } @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public Comparable getFacetValue(Facet f) { if (f.isNumberFacet()) { return this.getNumericFacetValue(f); } return this.knownNonNumericFacetValues.get(f); } @SuppressWarnings("rawtypes") @Override public Comparable getNumericFacetValue(Facet f) { return this.knownNumericFacetValues.get(f); } @Override public boolean isSubType(Datatype<?> type) { return this.ancestors.contains(type) || this.equals(type); } @Override public String toString() { return getDatatypeIRI().getFragment(); } @Override public boolean isCompatible(Datatype<?> type) { if (type.isExpression()) { type = type.asExpression().getHostType(); } return type.equals(this) || type.equals(DatatypeFactory.LITERAL) || type.isSubType(this) || this.isSubType(type); } @Override public boolean isCompatible(Literal<?> l) { if (!this.isCompatible(l.getDatatypeExpression())) { return false; } try { R value = parseValue(l.value()); return this.isInValueSpace(value); } catch (RuntimeException e) { System.err.println(e.getMessage()); // parsing exceptions will be caught here return false; } } @Override public boolean isContradictory(Datatype<?> type) { return !isCompatible(type); } // most common answer; restrictions on value spaces to be tested in // subclasses @Override public boolean isInValueSpace(R l) { return true; } @Override public void accept(DLExpressionVisitor visitor) { visitor.visit(this); } @Override public <O> O accept(DLExpressionVisitorEx<O> visitor) { return visitor.visit(this); } @Override public boolean isExpression() { return false; } @SuppressWarnings("unchecked") @Override public DatatypeExpression<R> asExpression() { if (!this.isExpression()) { throw new UnsupportedOperationException("Type: " + this.getDatatypeIRI() + " is not an expression"); } return (DatatypeExpression<R>) this; } @Override public Literal<R> buildLiteral(String s) { if (this.getNumeric()) { return new NumericLiteralImpl<R>(this.asNumericDatatype(), s); } return new LiteralImpl<R>(this, s); } @Override public Collection<Literal<R>> listValues() { return Collections.emptyList(); } @Override public boolean getBounded() { return false; } @Override public boolean getNumeric() { return false; } @Override public ordered getOrdered() { return ordered.FALSE; } @Override public cardinality getCardinality() { return cardinality.COUNTABLYINFINITE; } protected <T extends Comparable<T>> boolean overlapping( OrderedDatatype<T> first, OrderedDatatype<T> second) { T max = first.getMax(); T min = second.getMin(); if (first.hasMaxInclusive() && second.hasMinInclusive()) { return max.compareTo(min) >= 0; } if (first.hasMaxExclusive() && second.hasMinInclusive()) { return max.compareTo(min) > 0; } // if we get here, first has no max, hence it's unbounded upwards return false; } @Override public boolean isNumericDatatype() { return false; } @Override public NumericDatatype<R> asNumericDatatype() { return null; } @Override public boolean isOrderedDatatype() { return false; } @Override public OrderedDatatype<R> asOrderedDatatype() { return null; } @Override public boolean emptyValueSpace() { return false; } }