/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * */ package org.apache.stanbol.ontologymanager.registry.impl.cache; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.net.URI; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.semanticweb.owlapi.apibinding.OWLManager; import org.semanticweb.owlapi.io.FileDocumentSource; import org.semanticweb.owlapi.io.OWLOntologyDocumentSource; import org.semanticweb.owlapi.io.RDFXMLOntologyFormat; import org.semanticweb.owlapi.model.IRI; import org.semanticweb.owlapi.model.MissingImportEvent; import org.semanticweb.owlapi.model.MissingImportListener; import org.semanticweb.owlapi.model.OWLOntology; import org.semanticweb.owlapi.model.OWLOntologyAlreadyExistsException; import org.semanticweb.owlapi.model.OWLOntologyCreationException; import org.semanticweb.owlapi.model.OWLOntologyLoaderListener; import org.semanticweb.owlapi.model.OWLOntologyManager; import org.semanticweb.owlapi.model.OWLOntologyStorageException; import org.semanticweb.owlapi.model.UnknownOWLOntologyException; import org.slf4j.LoggerFactory; /** * @author Enrico Daga * */ public final class ODPRegistryCacheManager { /** * Restrict instantiation */ private ODPRegistryCacheManager() {} /** * */ private static final long serialVersionUID = 1L; /* * TODO bundle path or something */ public static final String WORKSPACE_PATH = ""/* * ResourcesPlugin.getWorkspace() * .getRoot().getLocationURI(). toString() */; public static final String TEMPORARY_DIR_NAME = ".xd"; public static final String TEMPORARY_FILE_PREFIX = "uri"; public static final String TEMPORARY_FILE_EXTENSION = ".res"; public static final String TEMPORARY_URI_REGISTRY = ".registry"; private static final String SEPARATOR = System.getProperty("file.separator"); private static final String URI_SEPARATOR = "/"; private static Map<URI,File> uris = new HashMap<URI,File>(); private static Map<URI,IRI> oiri = new HashMap<URI,IRI>(); private static Set<URI> unresolvedURIs = new HashSet<URI>(); private static OWLOntologyManager manager = OWLManager.createOWLOntologyManager(); public static OWLOntologyManager getManager() { return manager; } public static void addResource(OWLOntology ontology, URI virtualPhysicalURI) throws ODPRegistryCacheException { File file = newFile(); try { cacheOntology(virtualPhysicalURI, file, ontology); // manager.saveOntology(ontology, new RDFXMLOntologyFormat(), file // .toURI()); } catch (UnknownOWLOntologyException e) { throw new ODPRegistryCacheException(e); } catch (OWLOntologyStorageException e) { throw new ODPRegistryCacheException(e); } // uris.put(virtualPhysicalURI, file); } /** * uri is the physical uri * * @param uri * @return * @throws ODPRegistryCacheException * @throws URIUnresolvableException */ public static synchronized OWLOntology getOntology(URI uri) throws ODPRegistryCacheException, URIUnresolvableException { if (getUnresolvedURIs().contains(uri)) throw new URIUnresolvableException(); try { if (uris.containsKey(uri)) return retrieveLocalResource(uri); else return retrieveRemoteResource(uri); } catch (UnknownOWLOntologyException e) { throw new ODPRegistryCacheException(e); } catch (OWLOntologyCreationException e) { throw new ODPRegistryCacheException(e); } catch (OWLOntologyStorageException e) { throw new ODPRegistryCacheException(e); } } public static synchronized OWLOntologyDocumentSource getOntologyInputSource(URI uri) throws ODPRegistryCacheException, URIUnresolvableException { if (getUnresolvedURIs().contains(uri)) throw new URIUnresolvableException(); if (uris.containsKey(uri)) { File f = uris.get(uri); FileDocumentSource fds = new FileDocumentSource(f); return fds; } else { try { retrieveRemoteResource(uri); return getOntologyInputSource(uri); } catch (UnknownOWLOntologyException e) { throw new ODPRegistryCacheException(e); } catch (OWLOntologyCreationException e) { throw new ODPRegistryCacheException(e); } catch (OWLOntologyStorageException e) { throw new ODPRegistryCacheException(e); } } } public static URI getRegistryURI() { return URI.create(WORKSPACE_PATH + URI_SEPARATOR + TEMPORARY_DIR_NAME + URI_SEPARATOR + TEMPORARY_URI_REGISTRY); } public static boolean registryContains(URI ontologyURI) { return uris.containsKey(ontologyURI); } public static URI getTemporaryFolder() { return URI.create(WORKSPACE_PATH + URI_SEPARATOR + TEMPORARY_DIR_NAME); } /** * @return the unresolvedURIs */ public static Set<URI> getUnresolvedURIs() { return unresolvedURIs; } public static File newFile() { File file = new File(URI.create(getTemporaryFolder().toString() + URI_SEPARATOR + TEMPORARY_FILE_PREFIX + System.currentTimeMillis() + TEMPORARY_FILE_EXTENSION)); return file; } private static synchronized OWLOntology retrieveLocalResource(URI uri) throws OWLOntologyCreationException, ODPRegistryCacheException, URIUnresolvableException { File file = uris.get(uri); if (!file.exists()) { uris.remove(uri); return getOntology(uri); } manager.setSilentMissingImportsHandling(true); manager.addMissingImportListener(new MissingImportListener() { public void importMissing(MissingImportEvent arg0) { if (!getUnresolvedURIs().contains(arg0.getImportedOntologyURI())) getUnresolvedURIs().add( arg0.getImportedOntologyURI().toURI()); } }); IRI oi = oiri.get(uri); OWLOntology ontology = null; ontology = manager.getOntology(oi); if (ontology == null) try { ontology = manager.loadOntologyFromOntologyDocument(IRI.create(file)); } catch (OWLOntologyAlreadyExistsException e) { ontology = manager.getOntology(e.getOntologyID()); } return ontology; } /** * Gets the remote ontology and saves it locally * * @param uri * @return * @throws OWLOntologyCreationException * @throws UnknownOWLOntologyException * @throws OWLOntologyStorageException */ private static synchronized OWLOntology retrieveRemoteResource(URI uri) throws OWLOntologyCreationException, UnknownOWLOntologyException, OWLOntologyStorageException { manager.setSilentMissingImportsHandling(true); manager.addMissingImportListener(new MissingImportListener() { public void importMissing(MissingImportEvent arg0) { if (!getUnresolvedURIs().contains(arg0.getImportedOntologyURI())) getUnresolvedURIs().add( arg0.getImportedOntologyURI().toURI()); } }); manager.addOntologyLoaderListener(new OWLOntologyLoaderListener() { @Override public void startedLoadingOntology(LoadingStartedEvent event) { // Nothing to do } @Override public void finishedLoadingOntology(LoadingFinishedEvent event) { URI onturi = event.getDocumentIRI().toURI(); if (event.getException() != null) { getUnresolvedURIs().add(onturi); LoggerFactory.getLogger(ODPRegistryCacheManager.class).warn( "Failed to resolve ontology at " + onturi + " . Skipping.", event.getException()); return; } try { if (!uris.containsKey(onturi)) { cacheOntology(onturi, newFile(), manager.getOntology(event.getOntologyID())); } } catch (UnknownOWLOntologyException e) { LoggerFactory.getLogger(ODPRegistryCacheManager.class).warn( "Failed to cache ontology at " + onturi + " . Skipping.", e); getUnresolvedURIs().add(onturi); } catch (OWLOntologyStorageException e) { LoggerFactory.getLogger(ODPRegistryCacheManager.class).warn( "Failed to cache ontology at " + onturi + " . Skipping.", e); getUnresolvedURIs().add(onturi); } } }); OWLOntology ont; try { ont = manager.loadOntologyFromOntologyDocument(IRI.create(uri)); } catch (OWLOntologyAlreadyExistsException e) { ont = manager.getOntology(e.getOntologyID().getOntologyIRI()); } File file = newFile(); cacheOntology(uri, file, ont); return ont; } private static synchronized void cacheOntology(URI physicalRemoteUri, File file, OWLOntology ont) throws UnknownOWLOntologyException, OWLOntologyStorageException { uris.put(physicalRemoteUri, file); oiri.put(physicalRemoteUri, ont.getOntologyID().getOntologyIRI()); manager.setOntologyDocumentIRI(ont, IRI.create(file)); manager.saveOntology(ont, new RDFXMLOntologyFormat(), IRI.create(file)); } public static synchronized boolean save() { File registry = new File(ODPRegistryCacheManager.getRegistryURI()); if (registry.exists()) registry.delete(); try { registry.createNewFile(); BufferedWriter writer = new BufferedWriter(new FileWriter(registry)); for (URI u : uris.keySet()) { writer.write(u.toString() + "|" + uris.get(u).toString()); writer.newLine(); } writer.close(); } catch (IOException e) { return false; } return true; } public static synchronized boolean load() { File registry = new File(ODPRegistryCacheManager.getRegistryURI()); if (!registry.exists()) return false; Map<URI,File> newUris = new HashMap<URI,File>(); try { BufferedReader reader = new BufferedReader(new FileReader(registry)); String line = null; while ((line = reader.readLine()) != null) { if (line.indexOf('|') < 0) continue; String[] splitted = line.split("\\|"); newUris.put(URI.create(splitted[0]), new File(splitted[1])); } reader.close(); } catch (FileNotFoundException e) { LoggerFactory.getLogger(ODPRegistryCacheManager.class).error( "Failed to load registry " + getRegistryURI() + " File not found.", e); } catch (IOException e) { LoggerFactory.getLogger(ODPRegistryCacheManager.class).error( "Failed to load registry " + getRegistryURI(), e); } uris.clear(); uris = newUris; return true; } public static synchronized boolean clean() { // FileUriHelper fu = new FileUriHelper(); try { // fu // .deleteDir(new File(ODPRegistryCacheManager // .getTemporaryFolder())); uris.clear(); manager = null; manager = OWLManager.createOWLOntologyManager(); } catch (Exception e) { LoggerFactory.getLogger(ODPRegistryCacheManager.class).error( "OWL cache manager cleanup failed. ", e); return false; } return true; } }