net.sansa_stack.owl.common.parsing.FunctionalSyntaxParsing.scala Maven / Gradle / Ivy
The newest version!
package net.sansa_stack.owl.common.parsing
import com.typesafe.scalalogging.Logger
import org.semanticweb.owlapi.apibinding.OWLManager
import org.semanticweb.owlapi.functional.parser.OWLFunctionalSyntaxOWLParserFactory
import org.semanticweb.owlapi.io.{OWLParserException, StringDocumentSource}
import org.semanticweb.owlapi.model.OWLAxiom
/**
* Object containing several constants used by the FunctionalSyntaxParsing
* trait and the FunctionalSyntaxExpressionBuilder
*/
object FunctionalSyntaxParsing {
/** marker used to store the prefix for the default namespace */
val _empty = "_EMPTY_"
// TODO: refine
val prefixPattern = "Prefix\\(([a-zA-Z]*)\\:=<(.*)>\\)".r
val ontologyPattern = "Ontology\\(<(.*)>".r
}
/**
* Trait to support the parsing of input OWL files in functional syntax. This
* trait mainly defines how to make axioms from input functional syntax
* expressions.
*/
trait FunctionalSyntaxParsing {
private val logger = Logger(classOf[FunctionalSyntaxParsing])
private def parser = new OWLFunctionalSyntaxOWLParserFactory().createParser()
private def man = OWLManager.createOWLOntologyManager()
private def ontConf = man.getOntologyLoaderConfiguration
/**
* Builds a snippet conforming to the OWL functional syntax which then can
* be parsed by the OWLAPI functional syntax parser. A single expression,
* e.g.
*
* Declaration(Class(bar:Cls2))
*
* has thus to be wrapped into an ontology declaration as follows
*
* Ontology(
* Declaration(Class(bar:Cls2))
* )
*
* @param expression A String containing an expression in OWL functional
* syntax, e.g. Declaration(Class(bar:Cls2))
* @return The parsed axiom or null in case something went wrong during parsing
*/
@throws(classOf[OWLParserException])
def makeAxiom(expression: String): OWLAxiom = {
val ontStr = "Ontology(\n"
val axStr = ontStr + expression + "\n)"
val ont = man.createOntology()
parser.parse(new StringDocumentSource(axStr), ont, ontConf)
val it = ont.axioms().iterator()
if (it.hasNext) {
it.next()
} else {
logger.warn("No axiom was created for expression " + expression)
null
}
}
}
/**
* Trait to support the parsing of prefixes from expressions given in
* functional syntax.
*/
trait FunctionalSyntaxPrefixParsing {
/**
* Parses the prefix declaration of a namespace URI and returns the
* pair (prefix, namespace URI)
*
* @param prefixLine Sth like
* Prefix(:=) or
* Prefix(dc:= )
*/
def parsePrefix(prefixLine: String) = {
var prefix, uri: String = null
prefixLine.trim match {
case FunctionalSyntaxParsing.prefixPattern(p, u) => {
prefix = p
uri = u
}
}
if (prefix.isEmpty) prefix = FunctionalSyntaxParsing._empty
(prefix, uri)
}
def isPrefixDeclaration(expression: String): Boolean = {
FunctionalSyntaxParsing.prefixPattern.pattern.matcher(expression).matches()
}
}
/**
* The main purpose of this class is to provide an object which is initialized
* with
*
* - all prefix declarations
*
* and, fed with an expression in functional syntax, returns expressions in
* functional syntax, with
*
* - all prefix URIs being extended
* - all comments removed
* - all non-axiom expressions (e.g. Ontology(...), Prefix(...)) removed
*
* 'Removed' here means that a null value is returned discarding the input
* string.
*
* @param prefixes Map containing all read prefixes; required to expand
* namespace shortcuts in the cleaned (functional syntax)
* axiom string
*/
class FunctionalSyntaxExpressionBuilder(val prefixes: Map[String, String]) extends Serializable {
def clean(expression: String): String = {
var trimmedExpr = expression.trim
/* Throw away expressions that are of no use for further processing:
* 1) empty lines
* 2) comments
* 3) the last, outermost closing parenthesis
* 4) prefix declaration
* 5) ontology declaration
* 6) URL being part of the ontology declaration, e.g.
*
* being part of Ontology(...)
*/
val discardExpression: Boolean =
trimmedExpr.isEmpty || // 1)
trimmedExpr.startsWith("#") || // 2)
trimmedExpr.startsWith(")") || // 3)
trimmedExpr.startsWith("Prefix(") || // 4)
trimmedExpr.startsWith("Ontology(") || // 5)
trimmedExpr.startsWith(" http://foo.com/somePath#Bar
for (prefix <- prefixes.keys) {
val p = prefix + ":"
if (trimmedExpr.contains(p)) {
val v: String = "<" + prefixes.get(prefix).get
// TODO: refine regex
val pattern = (p + "([a-zA-Z][0-9a-zA-Z_-]*)").r
pattern.findAllIn(trimmedExpr).foreach(hit => {
if (!trimmedExpr.contains(hit + ">")) {
trimmedExpr = trimmedExpr.replace(hit, hit + ">")
}
})
trimmedExpr = trimmedExpr.replace(p.toCharArray, v.toCharArray)
}
}
// handle default prefix e.g. :Bar --> http://foo.com/defaultPath#Bar
// TODO: refine regex
val pattern = ":[^/][a-zA-Z][0-9a-zA-Z_-]*".r
val v: String = "<" + prefixes.get(FunctionalSyntaxParsing._empty).get
if (prefixes.contains(FunctionalSyntaxParsing._empty)) {
pattern.findAllIn(trimmedExpr).foreach(hit => {
val full = hit.replace(":".toCharArray, v.toCharArray)
trimmedExpr = trimmedExpr.replace(hit, full + ">")
})
}
trimmedExpr
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy