edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.java Source code

Java tutorial

Introduction

Here is the source code for edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.java

Source

/* $This file is distributed under the terms of the license in /doc/license.txt$ */

package edu.cornell.mannlib.vitro.webapp.modelaccess;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import edu.cornell.mannlib.vitro.webapp.modelaccess.impl.ContextModelAccessImpl;
import edu.cornell.mannlib.vitro.webapp.modelaccess.impl.RequestModelAccessImpl;
import edu.cornell.mannlib.vitro.webapp.triplesource.CombinedTripleSource;

/**
 * The root access point for the RDF data structures: RDFServices, Datasets,
 * ModelMakers, OntModels, OntModelSelectors and WebappDaoFactories.
 * 
 * Get a long-term data structure by accessing from the context. Get a
 * short-term data structure by accessing from the request.
 * 
 * <pre>
 * ModelAccess.on(ctx).getRDFService(CONFIGURATION);
 * ModelAccess.on(req).getOntModel(ModelNames.DISPLAY);
 * </pre>
 * 
 * ------------------------------------
 * 
 * The elaborate structure of options enums allows us to specify method
 * signatures like this on RequestModelAccess:
 * 
 * <pre>
 * getOntModelSelector(OntModelSelectorOption... options);
 * </pre>
 * 
 * Which can be invoked in any of these ways:
 * 
 * <pre>
 * ModelAccess.on(req).getOntModelSelector();
 * ModelAccess.on(req).getOntModelSelector(LANGUAGE_NEUTRAL);
 * ModelAccess.on(req).getOntModelSelector(INFERENCES_ONLY);
 * ModelAccess.on(req).getOntModelSelector(ASSERTIONS_ONLY, LANGUAGE_NEUTRAL);
 * </pre>
 * 
 * The compiler insures that only appropriate options are specified. However, if
 * conflicting options are supplied, it will only be caught at runtime.
 */
public class ModelAccess {
    private static final Log log = LogFactory.getLog(ModelAccess.class);

    // ----------------------------------------------------------------------
    // The options enums.
    // ----------------------------------------------------------------------

    /*
     * It may seem complicated, but it allows us to verify options at compile
     * time, and to provide or omit them in any order in a method call.
     */

    public interface ModelAccessOption {
        boolean isDefault();
    }

    public interface RdfServiceOption extends ModelAccessOption {
        // Just a marker interface
    }

    public interface DatasetOption extends ModelAccessOption {
        // Just a marker interface
    }

    public interface OntModelSelectorOption extends ModelAccessOption {
        // Just a marker interface
    }

    public interface WebappDaoFactoryOption extends ModelAccessOption {
        // Just a marker interface
    }

    @SuppressWarnings("hiding")
    public enum LanguageOption
            implements RdfServiceOption, DatasetOption, OntModelSelectorOption, WebappDaoFactoryOption {
        LANGUAGE_NEUTRAL, LANGUAGE_AWARE;
        @Override
        public boolean isDefault() {
            return this == LANGUAGE_AWARE;
        }
    }

    @SuppressWarnings("hiding")
    public enum ReasoningOption implements OntModelSelectorOption, WebappDaoFactoryOption {
        ASSERTIONS_ONLY, INFERENCES_ONLY, ASSERTIONS_AND_INFERENCES;
        @Override
        public boolean isDefault() {
            return this == ASSERTIONS_AND_INFERENCES;
        }
    }

    @SuppressWarnings("hiding")
    public enum PolicyOption implements WebappDaoFactoryOption {
        POLICY_NEUTRAL, POLICY_AWARE;
        @Override
        public boolean isDefault() {
            return this == POLICY_AWARE;
        }

    }

    @SuppressWarnings("hiding")
    public enum WhichService implements RdfServiceOption, DatasetOption {
        CONTENT, CONFIGURATION;
        @Override
        public boolean isDefault() {
            return this == CONTENT;
        }

    }

    /*
     * This is the easiest way to specify an option:
     * ModelAccess.LANGUAGE_NEUTRAL, instead of
     * ModelAccess.LanguageOption.LANGUAGE_NEUTRAL
     */
    public static final LanguageOption LANGUAGE_NEUTRAL = LanguageOption.LANGUAGE_NEUTRAL;
    public static final LanguageOption LANGUAGE_AWARE = LanguageOption.LANGUAGE_AWARE;
    public static final ReasoningOption ASSERTIONS_ONLY = ReasoningOption.ASSERTIONS_ONLY;
    public static final ReasoningOption INFERENCES_ONLY = ReasoningOption.INFERENCES_ONLY;
    public static final ReasoningOption ASSERTIONS_AND_INFERENCES = ReasoningOption.ASSERTIONS_AND_INFERENCES;
    public static final PolicyOption POLICY_NEUTRAL = PolicyOption.POLICY_NEUTRAL;
    public static final PolicyOption POLICY_AWARE = PolicyOption.POLICY_AWARE;
    public static final WhichService CONTENT = WhichService.CONTENT;
    public static final WhichService CONFIGURATION = WhichService.CONFIGURATION;

    // ----------------------------------------------------------------------
    // The factory
    // ----------------------------------------------------------------------

    private static volatile CombinedTripleSource combinedTripleSource;
    private static volatile ModelAccessFactory factory = new ModelAccessFactory();

    /** These attributes should only be accessed through this class. */
    private static final String ATTRIBUTE_NAME = ModelAccess.class.getName();

    public static void setCombinedTripleSource(CombinedTripleSource source) {
        if (combinedTripleSource != null) {
            log.warn("Assigning CombinedTripleSource " + source + ", but was already set to "
                    + combinedTripleSource);
        }
        combinedTripleSource = source;
    }

    public static RequestModelAccess on(HttpServletRequest req) {
        Object o = req.getAttribute(ATTRIBUTE_NAME);
        if (o instanceof RequestModelAccess) {
            return (RequestModelAccess) o;
        } else {
            RequestModelAccess access = factory.buildRequestModelAccess(req);
            req.setAttribute(ATTRIBUTE_NAME, access);
            return access;
        }
    }

    public static boolean isPresent(HttpServletRequest req) {
        return (req.getAttribute(ATTRIBUTE_NAME) instanceof RequestModelAccess);
    }

    public static ContextModelAccess on(ServletContext ctx) {
        Object o = ctx.getAttribute(ATTRIBUTE_NAME);
        if (o instanceof ContextModelAccess) {
            return (ContextModelAccess) o;
        } else {
            ContextModelAccess access = factory.buildContextModelAccess(ctx);
            ctx.setAttribute(ATTRIBUTE_NAME, access);
            return access;
        }
    }

    // ----------------------------------------------------------------------
    // A factory to create the instances, so we can override in unit tests.
    // ----------------------------------------------------------------------

    public static class ModelAccessFactory {
        public ContextModelAccess buildContextModelAccess(ServletContext ctx) {
            return new ContextModelAccessImpl(ctx, combinedTripleSource);
        }

        /**
         * Note that the RequestModelAccess must be closed when the request
         * closes.
         */
        public RequestModelAccess buildRequestModelAccess(HttpServletRequest req) {
            return new RequestModelAccessImpl(req, combinedTripleSource.getShortTermCombinedTripleSource(req));
        }
    }
}