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

org.geneontology.obographs.io.PrefixHelper Maven / Gradle / Ivy

package org.geneontology.obographs.io;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.util.DefaultPrefixManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.jsonldjava.core.Context;
import com.github.jsonldjava.core.JsonLdApi;
import com.github.jsonldjava.core.JsonLdOptions;
import com.github.jsonldjava.core.JsonLdProcessor;
import com.github.jsonldjava.utils.JsonUtils;

/**
 * Provides convenience methods for working with JSON LD contexts and prefixes
 *
 * Taken from ROBOT
 * @author James A. Overton
 */
public class PrefixHelper {
    /**
     * Logger.
     */
    private static final Logger logger =
        LoggerFactory.getLogger(PrefixHelper.class);

   
    /**
     * Path to default context as a resource.
     */
    private static String defaultContextPath = "/obo_context.jsonld";

    /**
     * Store the current JSON-LD context.
     */
    private Context context = new Context();

    /**
     * Create a new IOHelper with the default prefixes.
     */
    public PrefixHelper() {
        try {
            setContext(getDefaultContext());
        } catch (IOException e) {
            logger.warn("Could not load default prefixes.");
            logger.warn(e.getMessage());
        }
    }

    /**
     * Create a new IOHelper with or without the default prefixes.
     *
     * @param defaults false if defaults should not be used
     */
    public PrefixHelper(boolean defaults) {
        try {
            if (defaults) {
                setContext(getDefaultContext());
            } else {
                setContext();
            }
        } catch (IOException e) {
            logger.warn("Could not load default prefixes.");
            logger.warn(e.getMessage());
        }
    }

    /**
     * Create a new IOHelper with the specified prefixes.
     *
     * @param map the prefixes to use
     */
    public PrefixHelper(Map map) {
        setContext(map);
    }

    /**
     * Create a new IOHelper with prefixes from a file path.
     *
     * @param path to a JSON-LD file with a @context
     */
    public PrefixHelper(String path) {
        try {
            String jsonString = FileUtils.readFileToString(new File(path));
            setContext(jsonString);
        } catch (IOException e) {
            logger.warn("Could not load prefixes from " + path);
            logger.warn(e.getMessage());
        }
    }

    /**
     * Create a new IOHelper with prefixes from a file.
     *
     * @param file a JSON-LD file with a @context
     */
    public PrefixHelper(File file) {
        try {
            String jsonString = FileUtils.readFileToString(file);
            setContext(jsonString);
        } catch (IOException e) {
            logger.warn("Could not load prefixes from " + file);
            logger.warn(e.getMessage());
        }
    }

    /**
     * Try to guess the location of the catalog.xml file.
     * Looks in the directory of the given ontology file for a catalog file.
     *
     * @param ontologyFile the
     * @return the guessed catalog File; may not exist!
     */
    public File guessCatalogFile(File ontologyFile) {
        String path = ontologyFile.getParent();
        String catalogPath = "catalog-v001.xml";
        if (path != null) {
            catalogPath = path + "/catalog-v001.xml";
        }
        return new File(catalogPath);
    }

    

 
   

    /**
     * Given a term string, use the current prefixes to create an IRI.
     *
     * @param term the term to convert to an IRI
     * @return the new IRI
     */
    public IRI createIRI(String term) {
        if (term == null) {
            return null;
        }

        try {
            // This is stupid, because better methods aren't public.
            // We create a new JSON map and add one entry
            // with the term as the key and some string as the value.
            // Then we run the JsonLdApi to expand the JSON map
            // in the current context, and just grab the first key.
            // If everything worked, that key will be our expanded iri.
            Map jsonMap = new HashMap();
            jsonMap.put(term, "ignore this string");
            Object expanded = new JsonLdApi().expand(context, jsonMap);
            String result = ((Map) expanded)
                .keySet().iterator().next();
            if (result != null) {
                return IRI.create(result);
            }
        } catch (Exception e) {
            logger.warn("Could not create IRI for {}", term);
            logger.warn(e.getMessage());
        }
        return null;
    }

 
   

  
    /**
     * Load a map of prefixes from the "@context" of a JSON-LD string.
     *
     * @param jsonString the JSON-LD string
     * @return a map from prefix name strings to prefix IRI strings
     * @throws IOException on any problem
     */
    public static Context parseContext(String jsonString) throws IOException {
        try {
            Object jsonObject = JsonUtils.fromString(jsonString);
            if (!(jsonObject instanceof Map)) {
                return null;
            }
            Map jsonMap = (Map) jsonObject;
            if (!jsonMap.containsKey("@context")) {
                return null;
            }
            Object jsonContext = jsonMap.get("@context");
            return new Context().parse(jsonContext);
        } catch (Exception e) {
            throw new IOException(e);
        }
    }

    /**
     * Get a copy of the default context.
     *
     * @return a copy of the current context
     * @throws IOException if default context file cannot be read
     */
    public Context getDefaultContext() throws IOException {
        InputStream stream =
            PrefixHelper.class.getResourceAsStream(defaultContextPath);
        String jsonString = IOUtils.toString(stream);
        return parseContext(jsonString);
    }

    /**
     * Get a copy of the current context.
     *
     * @return a copy of the current context
     */
    public Context getContext() {
        return this.context.clone();
    }

    /**
     * Set an empty context.
     */
    public void setContext() {
        this.context = new Context();
    }

    /**
     * Set the current JSON-LD context to the given context.
     *
     * @param context the new JSON-LD context
     */
    public void setContext(Context context) {
        if (context == null) {
            setContext();
        } else {
            this.context = context;
        }
    }

    /**
     * Set the current JSON-LD context to the given context.
     *
     * @param jsonString the new JSON-LD context as a JSON string
     */
    public void setContext(String jsonString) {
        try {
            this.context = parseContext(jsonString);
        } catch (Exception e) {
            logger.warn("Could not set context from JSON");
            logger.warn(e.getMessage());
        }
    }

    /**
     * Set the current JSON-LD context to the given map.
     *
     * @param map a map of strings for the new JSON-LD context
     */
    public void setContext(Map map) {
        try {
            this.context = new Context().parse(map);
        } catch (Exception e) {
            logger.warn("Could not set context {}", map);
            logger.warn(e.getMessage());
        }
    }

    /**
     * Make an OWLAPI DefaultPrefixManager from a map of prefixes.
     *
     * @param prefixes a map from prefix name strings to prefix IRI strings
     * @return a new DefaultPrefixManager
     */
    public static DefaultPrefixManager makePrefixManager(
            Map prefixes) {
        DefaultPrefixManager pm = new DefaultPrefixManager();
        for (Map.Entry entry: prefixes.entrySet()) {
            pm.setPrefix(entry.getKey() + ":", entry.getValue());
        }
        return pm;
    }

    /**
     * Get a prefix manager with the current prefixes.
     *
     * @return a new DefaultPrefixManager
     */
    public DefaultPrefixManager getPrefixManager() {
        return makePrefixManager(context.getPrefixes(false));
    }

    /**
     * Add a prefix mapping as a single string "foo: http://example.com#".
     *
     * @param combined both prefix and target
     * @throws IllegalArgumentException on malformed input
     */
    public void addPrefix(String combined) throws IllegalArgumentException {
        String[] results = combined.split(":", 2);
        if (results.length < 2) {
            throw new IllegalArgumentException(
                    "Invalid prefix string: " + combined);
        }
        addPrefix(results[0], results[1]);
    }

    /**
     * Add a prefix mapping to the current JSON-LD context,
     * as a prefix string and target string.
     * Rebuilds the context.
     *
     * @param prefix the short prefix to add; should not include ":"
     * @param target the IRI string that is the target of the prefix
     */
    public void addPrefix(String prefix, String target) {
        try {
            context.put(prefix.trim(), target.trim());
            context.remove("@base");
            setContext((Map) context);
        } catch (Exception e) {
            logger.warn("Could not load add prefix \"{}\" \"{}\"",
                    prefix, target);
            logger.warn(e.getMessage());
        }
    }

    /**
     * Get a copy of the current prefix map.
     *
     * @return a copy of the current prefix map
     */
    public Map getPrefixes() {
        return this.context.getPrefixes(false);
    }

    /**
     * Set the current prefix map.
     *
     * @param map the new map of prefixes to use
     */
    public void setPrefixes(Map map) {
        setContext(map);
    }

    /**
     * Return the current prefixes as a JSON-LD string.
     *
     * @return the current prefixes as a JSON-LD string
     * @throws IOException on any error
     */
    public String getContextString() throws IOException {
        try {
            Object compact = JsonLdProcessor.compact(
                    JsonUtils.fromString("{}"),
                    context.getPrefixes(false),
                    new JsonLdOptions());
            return JsonUtils.toPrettyString(compact);
        } catch (Exception e) {
            throw new IOException("JSON-LD could not be generated", e);
        }
    }

    /**
     * Write the current context as a JSON-LD file.
     *
     * @param path the path to write the context
     * @throws IOException on any error
     */
    public void saveContext(String path) throws IOException {
        saveContext(new File(path));
    }

    /**
     * Write the current context as a JSON-LD file.
     *
     * @param file the file to write the context
     * @throws IOException on any error
     */
    public void saveContext(File file) throws IOException {
        FileWriter writer = new FileWriter(file);
        writer.write(getContextString());
        writer.close();
    }

  
 


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy