//The MIT License
//
// Copyright (c) 2004 Mindswap Research Group, University of Maryland, College Park
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
package org.mindswap.swoop.utils.owlapi;
import java.io.Serializable;
import java.net.URI;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.semanticweb.owl.io.ShortFormProvider;
import org.semanticweb.owl.io.vocabulary.OWLVocabularyAdapter;
import org.semanticweb.owl.io.vocabulary.RDFSVocabularyAdapter;
import org.semanticweb.owl.io.vocabulary.RDFVocabularyAdapter;
import org.semanticweb.owl.io.vocabulary.XMLSchemaSimpleDatatypeVocabulary;
public class QNameShortFormProvider implements ShortFormProvider, Serializable {
// A pattern to match a reversed URL
// Roughly corresponds to .*<name>?.*<name>
private static Pattern splitPattern = Pattern.compile("^([\\w[-.]]*[A-Za-z_])((?:[^A-Za-z_][^A-Za-z_]*?([\\w[-.]]*[A-Za-z_]).*)|(?:[^A-Za-z_]*))?$");//([\\w[-.]]*[A-Za-z_]).*)$");
private static int BASE_GROUP = 2;
private static int PREFIX_GROUP = 3;
private static int NAME_GROUP = 1;
private static String OWL = OWLVocabularyAdapter.OWL;
private static String RDFS = RDFSVocabularyAdapter.RDFS;
private static String RDF = RDFVocabularyAdapter.RDF;
private static String XSD = XMLSchemaSimpleDatatypeVocabulary.XS;
private static String DC = "http://purl.org/dc/elements/1.1/";
// stores a map of uri -> prefix
Map uriToPrefix;
Map prefixToUri;
public Map touchedPrefixes;
/**
*
*/
public QNameShortFormProvider() {
uriToPrefix = new Hashtable();
prefixToUri = new Hashtable();
touchedPrefixes = new Hashtable();
// initialize it with standard stuff
setMapping("owl", OWL);
setMapping("rdf", RDF);
setMapping("rdfs", RDFS);
setMapping("xsd", XSD);
setMapping("dc", DC);
//setMapping("foaf", FOAF);
}
/**
* Reverse a string
* @param string
* @return A reversed copy of the string
*/
protected static String reverse(String string) {
String reversed = null;
if (string != null) {
StringBuffer sb = new StringBuffer(string);
reversed = sb.reverse().toString();
}
return reversed;
}
/**
* Splits a uri into three parts.
*
* @param uri
* @return An array of three strings: 1) The base uri, 2) A prefix from that
* base, 3) the local name
*/
protected static String[] splitURI(URI uri) {
String base, prefix, name;
String[] bpn = new String[3];
Matcher splitMatcher = splitPattern.matcher(reverse(uri.toString()));
if (splitMatcher.matches()) {
base = reverse(splitMatcher.group(BASE_GROUP));
prefix = reverse(splitMatcher.group(PREFIX_GROUP));
name = reverse(splitMatcher.group(NAME_GROUP));
// System.out.println("============");
// System.out.println("URI: " +uri);
// System.out.println("Base: "+base);
// System.out.println("Prefix: "+prefix);
// System.out.println("Name: "+name);
if (base == null) {
base = "";
}
if (prefix == null) {
prefix = "a";
}
prefix = removeExtension(prefix);
bpn[0] = base;
bpn[1] = prefix;
bpn[2] = name;
// System.out.println("============");
// System.out.println("Base: "+base);
// System.out.println("Prefix: "+prefix);
// System.out.println("Name: "+name);
} else {
// System.out.println("No match for "+uri);
bpn = null;
}
return bpn;
}
public String getPrefix(String uri) {
return (String) uriToPrefix.get(uri);
}
/**
* Get the URI associated with a given prefix.
* @param prefix
* @return The uri associated, or null of none can be found.
*/
public String getURI(String prefix) {
return (String) prefixToUri.get(prefix);
}
/**
* Associates a prefix with a URI, if no association has already been made.
* @param prefix
* @param uri
* @return True if successful, or false if the mapping already existed.
*/
public boolean setMapping(String prefix, String uri) {
String currentUri = getURI(prefix);
if (currentUri == null) {
//the (prefix, uri) pair is not stored in the provider, we add it.
prefixToUri.put(prefix, uri);
uriToPrefix.put(uri, prefix);
return true;
} else if (currentUri == uri) {
return true;
} else {
return false;
}
}
/**
* Return all the prefixes known about.
* @return
*/
public Set getPrefixSet() {
return prefixToUri.keySet();
}
public String shortForm(URI uri) {
//System.out.println("Shortform for " + uri);
return shortForm(uri, true);
}
/**
*
* @param uri
* @param default_to_uri
* @return The shortform of the uri. If default_to_uri is set to false, null
* will be returned if a shortform cannot be fabricated.
*/
public String shortForm(URI uri, boolean default_to_uri) {
String[] bpn = splitURI(uri);
String base, possible_prefix, prefix, name;
String qname;
if (uri.toString().indexOf("ClassExpression") >= 0) {
String uriStr = uri.toString();
return uriStr.substring(uriStr.indexOf("#") + 1, uriStr.length());
}
if (bpn == null) {
if (default_to_uri) {
return uri.toString();
} else {
return null;
}
}
base = bpn[0];
possible_prefix = bpn[1];
name = bpn[2];
prefix = getPrefix(base);
if (prefix == null) {
// Check prefix for uniqueness
prefix = possible_prefix;
int mod = 0;
while (!setMapping(prefix, base)) {
prefix = possible_prefix + mod;
mod++;
}
}
touchedPrefixes.put(prefix, base);
qname = prefix + ":" + name;
return qname;
}
/**
* Find the local part of a URI
* @param uri
* @return The local portion, or null if none can be found.
*/
public String findLocal(URI uri) {
String local = null;
String bpn[] = splitURI(uri);
if (bpn != null) {
local = bpn[2];
}
return local;
}
/**
* Find the portion of a uri that is left over after removing the local part.
* @param uri
* @return The results, or null if the uri cannot be split.
*/
public String findPrefixURI(URI uri) {
String prefix = null;
String bpn[] = splitURI(uri);
if (bpn != null) {
prefix = bpn[0];
}
return prefix;
}
/**
* Returns a prefix associated non-localname portion of a uri.
* @param uri
* @return
*/
public String findPrefix(URI uri) {
shortForm(uri);
String prefixURI = findPrefixURI(uri);
return getPrefix(prefixURI);
}
private static String removeExtension(String prefix) {
// remove extension on prefix
if (prefix.indexOf(".") >= 0) {
prefix = prefix.substring(0, prefix.lastIndexOf("."));
} //BJP BUG: sometimes, for, I guess, new prefixes, you can get a .owl or something. Shouldn't be an else.
return prefix;
}
}