au.org.ands.vocabs.toolkit.provider.publish.SISSVocPublishProvider.java Source code

Java tutorial

Introduction

Here is the source code for au.org.ands.vocabs.toolkit.provider.publish.SISSVocPublishProvider.java

Source

/** See the file "LICENSE" for the full license governing this code. */
package au.org.ands.vocabs.toolkit.provider.publish;

import java.io.File;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Properties;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.WebTarget;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.text.StrSubstitutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.JsonNode;

import au.org.ands.vocabs.toolkit.db.AccessPointUtils;
import au.org.ands.vocabs.toolkit.db.model.AccessPoint;
import au.org.ands.vocabs.toolkit.tasks.TaskInfo;
import au.org.ands.vocabs.toolkit.tasks.TaskStatus;
import au.org.ands.vocabs.toolkit.utils.PropertyConstants;
import au.org.ands.vocabs.toolkit.utils.ToolkitFileUtils;
import au.org.ands.vocabs.toolkit.utils.ToolkitNetUtils;
import au.org.ands.vocabs.toolkit.utils.ToolkitProperties;

/** SISSVoc publish provider. */
public class SISSVocPublishProvider extends PublishProvider {

    /** Logger for this class. */
    private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

    /** Key of the subtask object that contains additional
     * replacements to use in the spec file template.
     */
    private static final String SPEC_SETTINGS_KEY = "spec_settings";

    /** Access to the Toolkit properties. */
    protected static final Properties PROPS = ToolkitProperties.getProperties();

    /** The location of the spec file template. */
    private String sissvocSpecTemplatePath = PROPS.getProperty(PropertyConstants.SISSVOC_SPECTEMPLATE);

    /** The directory in which to write generated spec files. */
    private String sissvocSpecOutputPath = PROPS.getProperty(PropertyConstants.SISSVOC_SPECSPATH);

    /** URL that is a prefix to all SISSVoc endpoints. */
    private String sissvocEndpointsPrefix = PROPS.getProperty(PropertyConstants.SISSVOC_ENDPOINTSPREFIX);

    /** Values to be substituted in the spec file template. */
    private final HashMap<String, String> specProperties = new HashMap<String, String>();

    @Override
    public final String getInfo() {
        return "";
    }

    @Override
    public final boolean publish(final TaskInfo taskInfo, final JsonNode subtask,
            final HashMap<String, String> results) {
        addBasicSpecProperties(taskInfo);
        addAdditionalSpecProperties(subtask);
        if (!writeSpecFile(taskInfo, subtask, results)) {
            return false;
        }

        // Use the nice JAX-RS libraries to construct the path to
        // the SPARQL endpoint.
        Client client = ToolkitNetUtils.getClient();
        WebTarget target = client.target(sissvocEndpointsPrefix);
        WebTarget sparqlTarget = target.path(ToolkitFileUtils.getSISSVocRepositoryPath(taskInfo));
        results.put("sissvoc_endpoints", sparqlTarget.getUri().toString());
        // Add sissvoc endpoint.
        AccessPointUtils.createSissvocAccessPoint(taskInfo.getVersion(), sparqlTarget.getUri().toString(),
                AccessPoint.SYSTEM_SOURCE);
        return true;
    }

    @Override
    public final boolean unpublish(final TaskInfo taskInfo, final JsonNode subtask,
            final HashMap<String, String> results) {
        // Remove the sissvoc access point.
        AccessPointUtils.deleteAccessPointsForVersionAndType(taskInfo.getVersion(), AccessPoint.SISSVOC_TYPE);
        // Use the following version when the elda library
        // supports it.
        //        removeSpecFile(taskInfo, subtask, results);
        // For now, use the truncation method.
        if (!truncateSpecFileIfExists(taskInfo, subtask, results)) {
            return false;
        }

        // results.put("sissvoc_path",
        //   TasksUtils.getTaskRepositoryId(taskInfo));
        return true;
    }

    /** Add the essential properties required by the spec file template.
     * @param taskInfo The TaskInfo object for this task.
     */
    private void addBasicSpecProperties(final TaskInfo taskInfo) {
        // Top-level of deployment path
        specProperties.put("DEPLOYPATH",
                PROPS.getProperty(PropertyConstants.SISSVOC_VARIABLE_DEPLOYPATH, "/repository/api/lda"));
        // The name of the ANDS Vocabulary service
        specProperties.put("SERVICE_TITLE", PROPS.getProperty(PropertyConstants.SISSVOC_VARIABLE_SERVICE_TITLE,
                "ANDS Vocabularies LDA service"));
        // The name of the ANDS Vocabulary service owner
        specProperties.put("SERVICE_AUTHOR",
                PROPS.getProperty(PropertyConstants.SISSVOC_VARIABLE_SERVICE_AUTHOR, "ANDS Services"));
        // Contact email address for the ANDS Vocabulary service owner
        specProperties.put("SERVICE_AUTHOR_EMAIL",
                PROPS.getProperty(PropertyConstants.SISSVOC_VARIABLE_SERVICE_AUTHOR_EMAIL, "services@ands.org.au"));
        // Homepage of the ANDS Vocabulary service
        // ANDS home page for now; in future, could be
        // vocabs.ands.org.au itself.
        specProperties.put("SERVICE_HOMEPAGE",
                PROPS.getProperty(PropertyConstants.SISSVOC_VARIABLE_SERVICE_HOMEPAGE, "http://www.ands.org.au/"));
        // Vocabulary title
        specProperties.put("SERVICE_LABEL", StringEscapeUtils.escapeJava(taskInfo.getVocabulary().getTitle()));
        String repositoryId = ToolkitFileUtils.getSesameRepositoryId(taskInfo);
        // SPARQL endpoint to use for doing queries
        specProperties
                .put("SPARQL_ENDPOINT",
                        PROPS.getProperty(PropertyConstants.SISSVOC_VARIABLE_SPARQL_ENDPOINT_PREFIX,
                                "http://localhost:8080/repository/" + "openrdf-sesame/repositories/")
                                + repositoryId);
        specProperties.put("SVC_ID", repositoryId);
        // Additional path to all the endpoints for this repository.
        // The template assumes the variable begins with a slash.
        specProperties.put("SVC_PREFIX", "/" + ToolkitFileUtils.getSISSVocRepositoryPath(taskInfo));
        // Path to the XSL stylesheet that generates the HTML pages.
        // Path is relative to the SISSVoc webapp.
        specProperties.put("HTML_STYLESHEET", PROPS.getProperty(PropertyConstants.SISSVOC_VARIABLE_HTML_STYLESHEET,
                "resources/default/transform/ands-ashtml-sissvoc.xsl"));
        // Empty string for now
        specProperties.put("NAMESPACES", "");
        // Title of the vocab displayed at the top of HTML pages
        specProperties.put("ANDS_VOCABNAME", StringEscapeUtils.escapeJava(taskInfo.getVocabulary().getTitle()));
        // Add more properties here, if/when needed.
        //        specProperties.put("", "");
        // The above properties are all more-or-less required.
        // Below are properties that are optional, and
        // may be overridden by the subtask settings.
        specProperties.put("ANDS_VOCABMORE", "");
        specProperties.put("ANDS_VOCABAPIDOCO", "");
    }

    /** Add the additional properties as provided in the subtask
     * specification. Values are escaped using StringEscapeUtils.escapeJava()
     * to prevent nasty injection.
     * @param subtask The specification of this publish subtask
     */
    private void addAdditionalSpecProperties(final JsonNode subtask) {
        if (subtask.get(SPEC_SETTINGS_KEY) == null) {
            // No additional properties specified.
            return;
        }
        for (Iterator<Entry<String, JsonNode>> nodeIterator = subtask.get(SPEC_SETTINGS_KEY).fields(); nodeIterator
                .hasNext();) {
            Entry<String, JsonNode> specProperty = nodeIterator.next();
            logger.debug("addAdditionalSpecProperties replacing with" + " value: "
                    + specProperty.getValue().textValue());
            specProperties.put(specProperty.getKey(),
                    StringEscapeUtils.escapeJava(specProperty.getValue().textValue()));
        }
    }

    /** Write out the spec file for SISSVoc.
     * @param taskInfo The TaskInfo object for this task.
     * @param subtask The specification of this publish subtask
     * @param results HashMap representing the result of the publish.
     * @return True iff success.
     */
    private boolean writeSpecFile(final TaskInfo taskInfo, final JsonNode subtask,
            final HashMap<String, String> results) {
        File templateFile = new File(sissvocSpecTemplatePath);
        String specTemplate;
        try {
            specTemplate = FileUtils.readFileToString(templateFile);
        } catch (IOException e) {
            results.put(TaskStatus.EXCEPTION, "SISSVoc writeSpecFile: can't open template file");
            logger.error("SISSVoc writeSpecFile: can't open template file", e);
            return false;
        }
        StrSubstitutor sub = new StrSubstitutor(specProperties);
        String customSpec = sub.replace(specTemplate);
        ToolkitFileUtils.requireDirectory(sissvocSpecOutputPath);
        File specFile = new File(Paths.get(sissvocSpecOutputPath)
                .resolve(ToolkitFileUtils.getSesameRepositoryId(taskInfo) + ".ttl").toString());
        try {
            FileUtils.writeStringToFile(specFile, customSpec);
        } catch (IOException e) {
            results.put(TaskStatus.EXCEPTION, "SISSVoc writeSpecFile: can't write spec file");
            logger.error("SISSVoc writeSpecFile: can't write spec file.", e);
            return false;
        }
        return true;
    }

    /** If there is an existing spec file for SISSVoc, overwrite
     * it and truncate it to zero size. This is the workaround
     * for unpublication until the elda library supports detection
     * of deleted files.
     * @param taskInfo The TaskInfo object for this task.
     * @param subtask The specification of this publish subtask
     * @param results HashMap representing the result of the unpublish.
     * @return True iff success.
     */
    private boolean truncateSpecFileIfExists(final TaskInfo taskInfo, final JsonNode subtask,
            final HashMap<String, String> results) {
        try {
            Path specFilePath = Paths.get(sissvocSpecOutputPath)
                    .resolve(ToolkitFileUtils.getSesameRepositoryId(taskInfo) + ".ttl");
            if (Files.exists(specFilePath)) {
                Files.write(specFilePath, new byte[0]);
            }

        } catch (IOException e) {
            // This may mean a file permissions problem, so do log it.
            results.put(TaskStatus.EXCEPTION, "SISSVoc truncateSpecFileIfExists: failed");
            logger.error("truncateSpecFileIfExists failed", e);
            return false;
        }
        return true;
    }

    /** Remove any existing spec file for SISSVoc.
     * @param taskInfo The TaskInfo object for this task.
     * @param subtask The specification of this publish subtask
     * @param results HashMap representing the result of the unpublish.
     * @return True iff success.
     */
    @SuppressWarnings("unused")
    private boolean removeSpecFile(final TaskInfo taskInfo, final JsonNode subtask,
            final HashMap<String, String> results) {
        try {
            Files.deleteIfExists(Paths.get(sissvocSpecOutputPath)
                    .resolve(ToolkitFileUtils.getSesameRepositoryId(taskInfo) + ".ttl"));
        } catch (IOException e) {
            // This may mean a file permissions problem, so do log it.
            results.put(TaskStatus.EXCEPTION, "SISSVoc removeSpecFile: failed");
            logger.error("removeSpecFile failed", e);
            return false;
        }
        return true;
    }

}