All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openrdf.repository.object.compiler.OWLCompiler Maven / Gradle / Ivy

Go to download

The Object Composition library merges multiple Java objects into a single multi-subject object.

The newest version!
/*
 * Copyright (c) 2007-2009, James Leigh All rights reserved.
 * Copyright (c) 2011 Talis Inc., Some rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * - Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution. 
 * - Neither the name of the openrdf.org nor the names of its contributors may
 *   be used to endorse or promote products derived from this software without
 *   specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * 
 */
package org.openrdf.repository.object.compiler;

import info.aduna.io.FileUtil;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.ConnectException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import org.openrdf.annotations.Iri;
import org.openrdf.model.Model;
import org.openrdf.model.Namespace;
import org.openrdf.model.Resource;
import org.openrdf.model.URI;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.model.vocabulary.OWL;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.object.compiler.model.RDFClass;
import org.openrdf.repository.object.compiler.model.RDFOntology;
import org.openrdf.repository.object.compiler.model.RDFProperty;
import org.openrdf.repository.object.compiler.source.ClassPathBuilder;
import org.openrdf.repository.object.compiler.source.JavaCompiler;
import org.openrdf.repository.object.exceptions.ObjectStoreConfigException;
import org.openrdf.repository.object.managers.LiteralManager;
import org.openrdf.repository.object.managers.RoleMapper;
import org.openrdf.repository.object.managers.helpers.RoleClassLoader;
import org.openrdf.repository.object.vocabulary.MSG;
import org.openrdf.rio.RDFFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Converts OWL ontologies into Java source code.
 * 
 * @author James Leigh
 * 
 */
public class OWLCompiler {
	private static final String META_INF_ANNOTATIONS = "META-INF/org.openrdf.annotations";
	private static final String META_INF_BEHAVIOURS = "META-INF/org.openrdf.behaviours";
	private static final String META_INF_CONCEPTS = "META-INF/org.openrdf.concepts";
	private static final String META_INF_DATATYPES = "META-INF/org.openrdf.datatypes";
	private static final String META_INF_ONTOLOGIES = "META-INF/org.openrdf.ontologies";

	private class AnnotationBuilder implements Runnable {
		private final RDFProperty bean;
		private final List content;
		private final File target;

		AnnotationBuilder(File target, List content,
				RDFProperty bean) {
			this.target = target;
			this.content = content;
			this.bean = bean;
		}

		public void run() {
			try {
				bean.generateAnnotationCode(target, resolver);
				URI uri = bean.getURI();
				String pkg = resolver.getPackageName(uri);
				String className = resolver.getSimpleName(uri);
				if (pkg != null) {
					className = pkg + '.' + className;
				}
				synchronized (content) {
					logger.debug("Saving {}", className);
					content.add(className);
					annotations.add(className);
				}
			} catch (Exception exc) {
				logger.error("Error processing {}", bean);
				if (exception == null) {
					exception = exc;
				}
			}
		}
	}

	private class ConceptBuilder implements Runnable {
		private final RDFClass bean;
		private final List content;
		private final File target;

		ConceptBuilder(File target, List content, RDFClass bean) {
			this.target = target;
			this.content = content;
			this.bean = bean;
		}

		public void run() {
			try {
				bean.generateSourceCode(target, resolver);
				URI uri = bean.getURI();
				String pkg = resolver.getPackageName(uri);
				String className = resolver.getSimpleName(uri);
				if (pkg != null) {
					className = pkg + '.' + className;
				}
				boolean anon = resolver.isAnonymous(uri)
						&& bean.isEmpty(resolver);
				synchronized (content) {
					logger.debug("Saving {}", className);
					content.add(className);
					if (!anon) {
						concepts.add(className);
					}
				}
			} catch (Exception exc) {
				logger.error("Error processing {}", bean);
				if (exception == null) {
					exception = exc;
				}
			}
		}
	}

	private final class DatatypeBuilder implements Runnable {
		private final RDFClass bean;
		private final List content;
		private final File target;

		DatatypeBuilder(List content, RDFClass bean, File target) {
			this.content = content;
			this.bean = bean;
			this.target = target;
		}

		public void run() {
			try {
				for (RDFClass equivalentRdfClass : bean.getRDFClasses(OWL.EQUIVALENTCLASS)) {
					Class equivalentJavaClass = literals.findClass(equivalentRdfClass.getURI());
					if (equivalentJavaClass != null) {
						String equivalentJavaClassname = equivalentJavaClass.getName();
						List uris = datatypes.get(equivalentJavaClassname);
						if (uris == null) {
							uris = new ArrayList();
							uris.add(equivalentRdfClass.getURI());
							datatypes.put(equivalentJavaClassname, uris);
						}
						uris.add(bean.getURI());
						literals.addDatatype(equivalentJavaClass, bean.getURI());
						return;
					}
				}
				bean.generateSourceCode(target, resolver);
				String pkg = resolver.getPackageName(bean.getURI());
				String className = resolver.getSimpleName(bean.getURI());
				if (pkg != null) {
					className = pkg + '.' + className;
				}
				synchronized (content) {
					logger.debug("Saving {}", className);
					content.add(className);
					datatypes.put(className, null);
				}
			} catch (Exception exc) {
				logger.error("Error processing {}", bean);
				if (exception == null) {
					exception = exc;
				}
			}
		}
	}

	private static final String JAVA_NS = "java:";

	private static ClassLoader findClassLoader() {
		ClassLoader ccl = Thread.currentThread().getContextClassLoader();
		if (ccl == null)
			return OWLCompiler.class.getClassLoader();
		return ccl;
	}

	Runnable helper = new Runnable() {
		public void run() {
			try {
				for (Runnable r = queue.take(); r != helper; r = queue.take()) {
					r.run();
				}
			} catch (InterruptedException e) {
				logger.error(e.toString(), e);
			}
		}
	};
	final Logger logger = LoggerFactory.getLogger(OWLCompiler.class);
	BlockingQueue queue = new LinkedBlockingQueue();
	private String[] baseClasses = new String[0];
	Set annotations = new TreeSet();
	Set concepts = new TreeSet();
	Map> datatypes = new HashMap>();
	Exception exception;
	LiteralManager literals;
	private RoleMapper mapper;
	private String memPrefix;
	private Model model;
	/** context -> prefix -> namespace */
	private Collection> ns = Collections.emptySet();
	private String pkgPrefix = "";
	JavaNameResolver resolver;
	private Map ontologies;
	private JavaCompiler compiler = new JavaCompiler();
	private final ClassLoader cl;
	private OwlNormalizer normalizer;
	private boolean pluralForms = false;
	private boolean resolvingPrefix = false;

	/**
	 * Constructs a new compiler instance using the
	 * existing Java classes referenced in the classpath.
	 * 
	 */
	public OWLCompiler() throws ObjectStoreConfigException {
		this(findClassLoader());
	}

	/**
	 * Constructs a new compiler instance using the
	 * existing Java classes referenced in the classpath.
	 * 
	 */
	public OWLCompiler(ClassLoader cl) throws ObjectStoreConfigException {
		assert cl != null;
		this.cl = cl;
		this.mapper = new RoleMapper();
		new RoleClassLoader(mapper).loadRoles(cl);
		this.literals = new LiteralManager(cl);
	}

	/**
	 * Constructs a new compiler instance using the
	 * existing Java classes referenced in the {@link RoleMapper} and
	 * {@link LiteralManager}.
	 * 
	 */
	public OWLCompiler(RoleMapper mapper, LiteralManager literals, ClassLoader cl) {
		assert mapper != null && literals != null && cl != null;
		this.cl = cl;
		this.mapper = mapper;
		this.literals = literals;
	}

	/**
	 * If an attempt is made to convert Set property names to their plural form.
	 */
	public boolean isPluralForms() {
		return pluralForms;
	}

	public void setPluralForms(boolean enabled) {
		this.pluralForms = enabled;
	}

	/**
	 * If prefixes for unknown namespaces should be looked up using a Web service.
	 */
	public boolean isResolvingPrefix() {
		return resolvingPrefix;
	}

	public void setResolvingPrefix(boolean resolvingPrefix) {
		this.resolvingPrefix = resolvingPrefix;
	}

	/**
	 * Assigns the schema that will be compiled.
	 * 
	 * @param model contains all relevant triples
	 */
	public void setModel(Model model) {
		assert model != null;
		this.model = model;
		normalizer = new OwlNormalizer(new RDFDataSource(model));
		normalizer.normalize();
	}

	/**
	 * All Java classes created will use prepend this to their package name.
	 */
	public void setPackagePrefix(String prefix) {
		if (prefix == null) {
			this.pkgPrefix = "";
		} else {
			this.pkgPrefix = prefix;
		}
	}

	/**
	 * Override all the prefixes used in the model namespaces to this one.
	 */
	public void setMemberPrefix(String prefix) {
		this.memPrefix = prefix;
	}

	/**
	 * Sets the prefixes for namespaces used in each graph of the model
	 */
	public void setPrefixNamespaces(Map> namespaces) {
		this.ns = namespaces.values();
	}

	/**
	 * Sets the prefixes for namespaces used in each graph of the model
	 */
	public void setPrefixNamespaces(Collection> namespaces) {
		this.ns = namespaces;
	}

	/**
	 * Sets the prefixes for namespaces used in each graph of the model
	 */
	public void setNamespaces(Map namespaces) {
		this.ns = Collections.singleton(namespaces);
	}

	/**
	 * All concepts created will extend the give baseClasses.
	 */
	public void setBaseClasses(String[] baseClasses) {
		assert baseClasses != null;
		this.baseClasses = baseClasses;
	}

	/**
	 * The given ontologies will be downloaded and included in the concept jar
	 * as resources.
	 */
	public void setOntologies(Map ontologies) {
		this.ontologies = ontologies;
	}

	/**
	 * Build concepts and behaviours, compile them and save them to this jar file
	 * 
	 * @throws IllegalArgumentException
	 *             if no concepts found
	 * @return a ClassLoader with in jar included
	 * @throws IOException 
	 * @throws ObjectStoreConfigException 
	 */
	public ClassLoader createJar(File jar) throws IOException,
			ObjectStoreConfigException {
		File target = createTempDir(getClass().getSimpleName());
		compile(target);
		JarPacker packer = new JarPacker(target);
		packer.packageJar(jar);
		FileUtil.deleteDir(target);
		return new URLClassLoader(new URL[] { jar.toURI().toURL() }, cl);
	}

	/**
	 * Build and compile concepts and behaivours to this directory.
	 * 
	 * @throws IllegalArgumentException
	 *             if no concepts found
	 * @return list of compiled classes
	 * @throws IOException 
	 * @throws ObjectStoreConfigException 
	 */
	public List compile(File dir) throws ObjectStoreConfigException,
			IOException {
		if (resolver == null) {
			resolver = buildJavaNameResolver(pkgPrefix, memPrefix, ns, model,
					normalizer, cl);
		}
		List classes = buildJavaFiles(dir);
		saveConceptResources(dir);
		if (!classes.isEmpty()) {
			ClassPathBuilder cb = new ClassPathBuilder();
			cb.append(getClass().getClassLoader()).append(cl);
			List classpath = cb.toFileList();
			compiler.compile(classes, dir, classpath);
		}
		return classes;
	}

	/**
	 * Build concepts in this directory
	 * 
	 * @throws IllegalArgumentException
	 *             if no concepts found
	 * @return list of concept classes created
	 * @throws IOException 
	 * @throws ObjectStoreConfigException
	 */
	public List buildJavaFiles(File dir)
			throws ObjectStoreConfigException, IOException {
		if (resolver == null) {
			resolver = buildJavaNameResolver(pkgPrefix, memPrefix, ns, model,
					normalizer, cl);
		}
		if (baseClasses.length > 0) {
			Set classes = model.filter(null, RDF.TYPE, OWL.CLASS)
					.subjects();
			for (Resource o : new ArrayList(classes)) {
				RDFClass bean = new RDFClass(model, o);
				if (bean.getURI() == null)
					continue;
				if (bean.isDatatype())
					continue;
				if (mapper.isRecordedConcept(bean.getURI(), cl))
					continue;
				addBaseClass(bean);
			}
		}
		List threads = new ArrayList();
		for (int i = 0; i < 3; i++) {
			threads.add(new Thread(helper));
		}
		for (Thread thread : threads) {
			thread.start();
		}
		Set usedNamespaces = new HashSet();
		List content = new ArrayList();
        for (Resource o : model.filter(null, RDF.TYPE, RDFS.DATATYPE)
				.subjects()) {
			RDFClass bean = new RDFClass(model, o);
			if (bean.getURI() == null)
				continue;
			if (literals.isRecordedeType(bean.getURI()))
				continue;
			String namespace = bean.getURI().getNamespace();
			usedNamespaces.add(namespace);
			new DatatypeBuilder(content, bean, dir).run();
		}
		for (Resource o : model.filter(null, RDF.TYPE, OWL.ANNOTATIONPROPERTY)
				.subjects()) {
			RDFProperty bean = new RDFProperty(model, o);
			if (bean.getURI() == null)
				continue;
			if (mapper.isRecordedAnnotation(bean.getURI()))
				continue;
			String namespace = bean.getURI().getNamespace();
			usedNamespaces.add(namespace);
			queue.add(new AnnotationBuilder(dir, content, bean));
		}
		for (Resource o : model.filter(null, RDF.TYPE, OWL.CLASS).subjects()) {
			if (model.contains(o, RDFS.SUBCLASSOF, MSG.MESSAGE))
				continue;
			RDFClass bean = new RDFClass(model, o);
			if (bean.getURI() == null)
				continue;
			if (bean.isDatatype())
				continue;
			if (mapper.isRecordedConcept(bean.getURI(), cl)) {
				if ("java:".equals(bean.getURI().getNamespace()))
					continue;
				if (isComplete(bean, mapper.findRoles(bean.getURI()), resolver))
					continue;
			}
			String namespace = bean.getURI().getNamespace();
			usedNamespaces.add(namespace);
			queue.add(new ConceptBuilder(dir, content, bean));
		}
		Set methods = new HashSet();
		for (int i = 0, n = threads.size(); i < n; i++) {
			queue.add(helper);
		}
		for (String namespace : usedNamespaces) {
			if (JAVA_NS.equals(namespace))
				continue;
			RDFOntology ont = findOntology(namespace);
			ont.generatePackageInfo(dir, namespace, resolver);
			String pkg = resolver.getBoundPackageName(namespace);
			if (pkg != null) {
				String className = pkg + ".package-info";
				synchronized (content) {
					logger.debug("Saving {}", className);
					content.add(className);
				}
			}
		}
		for (Thread thread1 : threads) {
			try {
				thread1.join();
			} catch (InterruptedException cause) {
				InterruptedIOException e = new InterruptedIOException(cause.getMessage());
				e.initCause(cause);
				throw e;
			}
		}
		if (exception != null)
			try {
				throw exception;
			} catch (ObjectStoreConfigException e) {
				throw new ObjectStoreConfigException(e.getMessage(), e);
			} catch (IOException e) {
				throw new IOException(e.getMessage(), e);
			} catch (Exception e) {
				throw new UndeclaredThrowableException(e);
			}
		if (!methods.isEmpty()) {
			printClasses(methods, dir, META_INF_BEHAVIOURS);
			content.addAll(methods);
		}
		return content;
	}

	/**
	 * Save META-INF resource for concepts in this parent directory. This method
	 * must be called after {@link #buildJavaFiles(File)}.
	 */
	public void saveConceptResources(File dir) throws IOException {
		if (!annotations.isEmpty()) {
			printClasses(annotations, dir, META_INF_ANNOTATIONS);
		}
		if (!concepts.isEmpty()) {
			printClasses(concepts, dir, META_INF_CONCEPTS);
		}
		if (!datatypes.isEmpty()) {
            printDatatypes(datatypes, dir, META_INF_DATATYPES);
        }
		if (ontologies != null) {
			packOntologies(ontologies, dir, META_INF_ONTOLOGIES);
		}
	}

	private void addBaseClass(RDFClass klass) {
		if (klass.getRDFClasses(RDFS.SUBCLASSOF).isEmpty()) {
			for (String b : baseClasses) {
				URI name = new URIImpl(JAVA_NS + b);
				model.add(klass.getURI(), RDFS.SUBCLASSOF, name);
			}
		}
	}

	private boolean isComplete(RDFClass bean, Collection> roles,
			JavaNameResolver resolver) {
		loop: for (RDFProperty prop : bean.getDeclaredProperties()) {
			if (prop.getURI() == null)
				continue;
			String iri = prop.getURI().stringValue();
			for (Class role : roles) {
				for (Method m : role.getMethods()) {
					if (m.isAnnotationPresent(Iri.class)
							&& iri.equals(m.getAnnotation(Iri.class).value()))
						continue loop;
				}
			}
			return false;
		}
		loop: for (RDFClass type : bean.getDeclaredMessages()) {
			if (type.getURI() == null || resolver.isAnonymous(type.getURI()))
				continue;
			String iri = type.getURI().stringValue();
			for (Class role : roles) {
				for (Method m : role.getMethods()) {
					if (m.isAnnotationPresent(Iri.class)
							&& iri.equals(m.getAnnotation(Iri.class).value()))
						continue loop;
				}
			}
			return false;
		}
		loop: for (RDFClass sups : bean.getRDFClasses(RDFS.SUBCLASSOF)) {
			if (sups.getURI() == null)
				continue;
			String iri = sups.getURI().stringValue();
			for (Class role : roles) {
				for (Class face : role.getInterfaces()) {
					if (face.isAnnotationPresent(Iri.class)) {
						if (iri.equals(face.getAnnotation(Iri.class).value()))
							continue loop;
					}
				}
				Class parent = role.getSuperclass();
				if (parent != null && parent.isAnnotationPresent(Iri.class)) {
					if (iri.equals(parent.getAnnotation(Iri.class).value()))
						continue loop;
				}
			}
			return false;
		}
		// TODO check annotations
		return true;
	}

	private File createTempDir(String name) throws IOException {
		String tmpDirStr = System.getProperty("java.io.tmpdir");
		if (tmpDirStr != null) {
			File tmpDir = new File(tmpDirStr);
			if (!tmpDir.exists()) {
				tmpDir.mkdirs();
			}
		}
		File tmp = File.createTempFile(name, "");
		tmp.delete();
		tmp.mkdir();
		return tmp;
	}

	private JavaNameResolver buildJavaNameResolver(String pkgPrefix,
			String memberPrefix, Collection> namespaces,
			Model model, OwlNormalizer normalizer, ClassLoader cl) {
		if (model == null)
			throw new IllegalStateException("setModel not called");
		/** namespace -> package */
		Map packages = new HashMap();
		for (String ns : findUndefinedNamespaces(model, cl)) {
			String prefix = findPrefix(ns, model);
			packages.put(ns, pkgPrefix + prefix);
		}
		JavaNameResolver resolver = createJavaNameResolver(packages,
				memberPrefix, namespaces, cl);
		for (URI uri : normalizer.getAnonymousClasses()) {
			resolver.assignAnonymous(uri);
		}
		for (Map.Entry e : normalizer.getAliases().entrySet()) {
			resolver.assignAlias(e.getKey(), e.getValue());
		}
		resolver.setImplNames(normalizer.getImplNames());
		for (Resource o : model.filter(null, RDF.TYPE, OWL.CLASS).subjects()) {
			RDFClass bean = new RDFClass(model, o);
			URI uri = bean.getURI();
			if (uri == null || bean.isDatatype())
				continue;
			if (!"java:".equals(uri.getNamespace())
					&& mapper.isRecordedConcept(uri, cl)
					&& !isComplete(bean, mapper.findRoles(uri), resolver)) {
				resolver.ignoreExistingClass(uri);
				String ns = uri.getNamespace();
				if (!packages.containsKey(ns)) {
					String prefix = findPrefix(ns, model);
					packages.put(ns, pkgPrefix + prefix);
				}
			}
		}
		for (Map.Entry e : packages.entrySet()) {
			resolver.bindPackageToNamespace(e.getValue(), e.getKey());
		}
		return resolver;
	}

	private JavaNameResolver createJavaNameResolver(
			Map packages, String memberPrefix,
			Collection> namespaces, ClassLoader cl) {
		JavaNameResolver resolver = new JavaNameResolver(cl);
		resolver.setPluralForms(pluralForms);
		resolver.setModel(model);
		for (Map.Entry e : packages.entrySet()) {
			resolver.bindPackageToNamespace(e.getValue(), e.getKey());
		}
		for (Namespace e : model.getNamespaces()) {
			resolver.bindPrefixToNamespace(e.getPrefix(), e.getName());
		}
		if (memberPrefix == null) {
			for (Map p : namespaces) {
				for (Map.Entry e : p.entrySet()) {
					resolver.bindPrefixToNamespace(e.getKey(), e.getValue());
				}
			}
		} else {
			for (Map.Entry e : packages.entrySet()) {
				resolver.bindPrefixToNamespace(memberPrefix, e.getKey());
			}
		}
		resolver.setRoleMapper(mapper);
		resolver.setLiteralManager(literals);
		return resolver;
	}

	private RDFOntology findOntology(String namespace) {
		if (namespace.endsWith("#"))
			return new RDFOntology(model, new URIImpl(namespace.substring(0,
					namespace.length() - 1)));
		return new RDFOntology(model, new URIImpl(namespace));
	}

	private String findPrefix(String ns, Model model) {
		for (Namespace e : model.getNamespaces()) {
			if (ns.equals(e.getName()) && e.getPrefix().length() > 0) {
				return e.getPrefix();
			}
		}
		if (resolvingPrefix) {
			String prefix = NamespacePrefixService.getInstance().prefix(ns);
			if (prefix != null && model.getNamespace(prefix) == null) {
				model.setNamespace(prefix, ns);
				return prefix;
			}
		}
		return "ns" + Integer.toHexString(ns.hashCode());
	}

	private Set findUndefinedNamespaces(Model model, ClassLoader cl) {
		Set unknown = new HashSet();
		for (Resource subj : model.filter(null, RDF.TYPE, null).subjects()) {
			if (subj instanceof URI) {
				URI uri = (URI) subj;
				String ns = uri.getNamespace();
				if (!mapper.isRecordedConcept(uri, cl)
						&& !literals.isRecordedeType(uri)
						&& !mapper.isRecordedAnnotation(uri)) {
					unknown.add(ns);
				}
			}
		}
		return unknown;
	}

	private void printClasses(Collection roles, File dir, String entry)
			throws IOException {
		File f = new File(dir, entry);
		f.getParentFile().mkdirs();
		PrintStream out = new PrintStream(new FileOutputStream(f));
		try {
			for (String name : roles) {
				out.println(name);
			}
		} finally {
			out.close();
		}
	}

	private void printDatatypes(Map> datatypes, File dir, String META_INF_DATATYPES) throws FileNotFoundException {
		File f = new File(dir, META_INF_DATATYPES);
		f.getParentFile().mkdirs();
		PrintStream out = new PrintStream(new FileOutputStream(f));
		try {
		    for (Map.Entry> entry : datatypes.entrySet()) {
		        StringBuilder sb = new StringBuilder(entry.getKey());
		        if (entry.getValue() != null) {
		            StringBuilder temp = new StringBuilder();
		            for (URI uri : entry.getValue()) {
		                if (temp.length() > 0) {
		                    temp.append(' ');
		                }
		                temp.append(uri.stringValue());
		            }
		            if (temp.length() > 0) {
		                sb.append('=').append(temp);
		            }
		        }
		        out.println(sb);
		    }
		} finally {
		    out.close();
		}
	}

	private void packOntologies(Map rdfSources, File dir, String META_INF_ONTOLOGIES)
			throws IOException {
		File list = new File(dir, META_INF_ONTOLOGIES);
		list.getParentFile().mkdirs();
		PrintStream inf = new PrintStream(new FileOutputStream(list));
		try {
			for (URL rdf : rdfSources.keySet()) {
				try {
					RDFFormat format = rdfSources.get(rdf);
					String path = "META-INF/ontologies/";
					URLConnection conn = rdf.openConnection();
					if (format != null) {
						for (String type : format.getMIMETypes()) {
							conn.addRequestProperty("Accept", type);
						}
					}
					InputStream in = conn.getInputStream();
					try {
						String name = getLocalName(rdf.toExternalForm());
						if (format != null && !format.equals(RDFFormat.forFileName(name))) {
							name += "." + format.getDefaultFileExtension();
						}
						File file = new File(dir, path + name);
						file.getParentFile().mkdirs();
						OutputStream out = new FileOutputStream(file);
						try {
							int read;
							byte[] buf = new byte[1024];
							while ((read = in.read(buf)) >= 0) {
								out.write(buf, 0, read);
							}
						} finally {
							out.close();
						}
						inf.println(path + name);
					} finally {
						in.close();
					}
				} catch (ConnectException exc) {
					throw new IOException("Cannot connect to " + rdf, exc);
				}
			}
		} finally {
			inf.close();
		}
	}

	private String getLocalName(String uri) {
		int start = uri.indexOf('#');
		int end = uri.length();
		if (start >= 0 && start < end - 1)
			return uri.substring(start + 1, end);
		if (start >= 0 && start < end) {
			end = start;
		}

		int idx = uri.lastIndexOf('?');
		if (idx >= 0) {
			end = idx;
		}

		start = uri.lastIndexOf('/');
		if (start >= 0 && start < end - 1)
			return uri.substring(start + 1, end);
		if (start >= 0 && start < end) {
			end = start;
		}

		start = uri.lastIndexOf(':');
		if (start >= 0 && start < end - 1)
			return uri.substring(start + 1, end);
		if (start >= 0 && start < end) {
			end = start;
		}

		return uri;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy