Package org.mmisw.ont

Source Code of org.mmisw.ont.UriResolver2$OntologyResponse

package org.mmisw.ont;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import net.jcip.annotations.ThreadSafe;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mmisw.ont.db.Db;
import org.mmisw.ont.mmiuri.MmiUri;
import org.mmisw.ont.triplestore.ITripleStore;
import org.mmisw.ont.util.ServletUtil;

import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.Model;

/**
* This is main dispatcher used by the entry point OntServlet.
*
* <p>
* TODO: update documentation.
*
* <p>
* Note: This class is effectively a singleton as it is only instantiated once by {@link OntServlet}
* (ie., the singleton-ness is not forced here).
*
* @author Carlos Rueda
*/
@ThreadSafe
public class UriResolver2 {
 
  private final Log log = LogFactory.getLog(UriResolver2.class);
 
  private final OntConfig ontConfig;
  private final Db db;

  /** Used to obtain the thread-local OntRequest */
  private final OntServlet ontServlet;
 
  /**
   *
   * @param ontServlet
   *                    Used to obtain the thread-local OntRequest.
   * @param ontConfig
   * @param db
   * @param tripleStore
   */
  public UriResolver2(OntServlet ontServlet, OntConfig ontConfig, Db db, ITripleStore tripleStore) {
    this.ontServlet = ontServlet;
    this.ontConfig = ontConfig;
    this.db = db;
  }
 
  private OntRequest _getThreadLocalOntRequest() {
    return ontServlet.getThreadLocalOntRequest();
  }
 
  /**
   * Represents a response to be sent to the client
   */
  abstract class Response {
    /** performs the actual response */
    abstract void dispatch() throws IOException ;
  }
 
  class RedirectResponse extends Response {
    final String url;
   
    RedirectResponse(String url) {
      this.url = url;
    }
   
    void dispatch() throws IOException {
      if ( log.isDebugEnabled() ) {
        log.debug("Redirecting to latest version: " + url);
      }
      OntRequest ontReq = _getThreadLocalOntRequest();
      String redir = ontReq.response.encodeRedirectURL(url);
      ontReq.response.sendRedirect(redir);
    }
  }
 
  class NotFoundResponse extends Response {
    final String res;
   
    public NotFoundResponse(String res) {
      this.res = res;
    }
    void dispatch() throws IOException {
      OntRequest ontReq = _getThreadLocalOntRequest();
      ontReq.response.sendError(HttpServletResponse.SC_NOT_FOUND, res);
    }
  }
 
  class InternalErrorResponse extends Response {
    final String msg;
    final Throwable thr;
   
    public InternalErrorResponse(String msg) {
      this(msg, null);
    }
    public InternalErrorResponse(String msg, Throwable thr) {
      this.msg = msg;
      this.thr = thr;
    }
    void dispatch() throws IOException {
      log.error(msg, thr);
      OntRequest ontReq = _getThreadLocalOntRequest();
      ontReq.response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg);
    }
  }
 

  class ModelResponse extends Response {
    final Model model;
   
    ModelResponse(Model model) {
      this.model = model;
    }
   
    void dispatch() throws IOException {
      OntRequest ontReq = _getThreadLocalOntRequest();
     
      if ( log.isDebugEnabled() ) {
        log.debug(this.getClass().getName()+ ": dispatching with outFormat=" +ontReq.outFormat);
      }

      ServletOutputStream os = ontReq.response.getOutputStream();

      ///////////////////////////////////////////////////////////////////
      // OWL
      if ( ontReq.outFormat.equalsIgnoreCase("owl")
      ||   ontReq.outFormat.equalsIgnoreCase("rdf")
      ) {
        if ( log.isDebugEnabled() ) {
          log.debug(this.getClass().getName()+ ": Serializing to RDF/XML-ABBREV");
        }
        ServletUtil.setContentTypeRdfXml(ontReq.response);
//        is = OntServlet.serializeModel(model, "RDF/XML-ABBREV");
        OntServlet.serializeModelToOutputStream(model, "RDF/XML-ABBREV", os);
      }
     
      ///////////////////////////////////////////////////////////////////
      // N3
      else if ( ontReq.outFormat.equalsIgnoreCase("n3") ) {
        ServletUtil.setContentTypeTextPlain(ontReq.response);
        OntServlet.serializeModelToOutputStream(model, "N3", os);
      }
     
      ///////////////////////////////////////////////////////////////////
      // NT
      else if ( ontReq.outFormat.equalsIgnoreCase("nt") ) {
        ServletUtil.setContentTypeTextPlain(ontReq.response);
        OntServlet.serializeModelToOutputStream(model, "N-TRIPLE", os);
      }
     
      ///////////////////////////////////////////////////////////////////
      // TTL
      else if ( ontReq.outFormat.equalsIgnoreCase("ttl") ) {
        ServletUtil.setContentTypeTextPlain(ontReq.response);
        OntServlet.serializeModelToOutputStream(model, "TURTLE", os);
      }
     
      ///////////////////////////////////////////////////////////////////
      // HTML
      else if ( ontReq.outFormat.equalsIgnoreCase("html") ) {
       
        // Redirect to the appropriate service.
       
        String ontologyUri;
       
        if ( ontReq.ontology != null ) {
          ontologyUri = ontReq.ontology.getUri();
        }
        else if ( ontReq.mmiUri != null ) {
          // Note: drop any extension here (the Orr service will do the appropriate request
          // back to this Ont service):
          ontologyUri = ontReq.mmiUri.getOntologyUriWithExtension("");
        }
        else {
          ontologyUri = ontReq.fullRequestedUri;
        }
       
        String portalServiceUrl = OntConfig.Prop.PORTAL_SERVICE_URL.getValue();
       
        String url = portalServiceUrl+ "/#" +ontologyUri;
        if ( log.isDebugEnabled() ) {
          log.debug("REDIRECTING TO: " +url);
        }
        String redir = ontReq.response.encodeRedirectURL(url);
        ontReq.response.sendRedirect(redir);
        return;
      }
     
      ///////////////////////////////////////////////////////////////////
      // BAD REQUEST
      else {
        ontReq.response.sendError(HttpServletResponse.SC_BAD_REQUEST,
            "ModelResponse: outFormat " +ontReq.outFormat+ " not recognized"
        );
        return;
      }
     
      os.close();
    }
   
  }

  /** Response for a term -- currently it behaves exactly as ModelResponse */
  class TermResponse extends ModelResponse {
    TermResponse(Model termModel) {
      super(termModel);
    }
  }
 
  /** Response for an ontology -- currently it behaves exactly as ModelResponse */
  class OntologyResponse extends ModelResponse {
    OntologyResponse(Model ontologyModel) {
      super(ontologyModel);
    }
  }
 
 
 
  /**
   * The main dispatcher.
   */
  void service() throws ServletException, IOException {
    OntRequest ontReq = _getThreadLocalOntRequest();
   
    Response resp = null;
   
   
    if ( log.isDebugEnabled() ) {
      log.debug("UriResolver2.service: mmiUri = " +ontReq.mmiUri);
    }
   
    if ( ontReq.mmiUri != null ) {
      if ( log.isDebugEnabled() ) {
        log.debug("UriResolver2._getResponseForMmiUri.");
      }
      resp = _getResponseForMmiUri();
    }
    else {
      // NOT a regular MmiUri request.
      if ( log.isDebugEnabled() ) {
        log.debug("UriResolver2._getResponseForNonMmiUri.");
      }
      resp = _getResponseForNonMmiUri();
    }
   
    if ( resp != null ) {
      resp.dispatch();
    }
    else {
      String fullRequestedUri = ontReq.request.getRequestURL().toString();
      ontReq.response.sendError(HttpServletResponse.SC_NOT_FOUND, fullRequestedUri);   
    }
  }
 
 
  /**
   * Gets the response for a requested MmiUri.
   */
  private Response _getResponseForMmiUri() throws ServletException, IOException {
   
    // the ontology we need to access:
    OntologyInfo ontology = null;
   
   
    // this flag will be true if we have an unversioned request, see Issue 24.
    boolean unversionedRequest = false;
    MmiUri foundMmiUri = null;
   
    OntRequest ontReq = _getThreadLocalOntRequest();
    String version = ontReq.mmiUri.getVersion();
    if ( version == null || version.equals(MmiUri.LATEST_VERSION_INDICATOR) ) {
     
      //
      // handling of unversioned and latest-version requests.  (see Issue 24)
      //
     
      // Get latest version trying all possible topic extensions:
      OntologyInfo mostRecentOntology = db.getMostRecentOntologyVersion(ontReq.mmiUri);

      if ( mostRecentOntology != null ) {
       
        try {
          //
          // Note that mostRecentOntology.getUri() won't have the term component.
          // So, we have to transfer it to foundMmiUri:
          //
          foundMmiUri = new MmiUri(mostRecentOntology.getUri()).copyWithTerm(ontReq.mmiUri.getTerm());
         
          if ( log.isDebugEnabled() ) {
            log.debug("Found ontology version: " +mostRecentOntology.getUri());

            if ( ! ontReq.mmiUri.getExtension().equals(foundMmiUri.getExtension()) ) {
              log.debug("Restored requested extension to: " +ontReq.mmiUri);
            }
          }
         
          // also, restore the original requested extension:
          foundMmiUri = foundMmiUri.copyWithExtension(ontReq.mmiUri.getExtension());
        }
        catch (URISyntaxException e) {
          return new InternalErrorResponse("Shouldn't happen", e);
        }
       
        // OK: here, foundMmiUri refers to the latest version.
       
        if ( version == null ) {
          // unversioned request.
          unversionedRequest = true;
         
          ontology = mostRecentOntology;
         
          // and let the dispatch continue.
        }
        else {
          // request was with version = MmiUri.LATEST_VERSION_INDICATOR.
          // Use a redirect so the user gets the actual latest version:
          String latestUri = foundMmiUri.getTermUri();
          return new RedirectResponse(latestUri);
        }
      }
      else {
        // No versions available!
        if ( log.isDebugEnabled() ) {
          log.debug("No versions found.");
        }
        return null;
      }
    }
    else {
      // Version explicitly given: let the dispatch continue.
    }
   

    if ( ontology == null ) {
      // obtain info about the ontology:
      ontology = db.getOntologyWithExts(ontReq.mmiUri, null);
    }
   
    if ( ontology == null ) {
      if ( log.isDebugEnabled() ) {
        log.debug("_getResponseForMmiUri: not dispatched here. mmiUri = " +ontReq.mmiUri);
      }
      return null;
    }
   
    final File file = OntServlet.getFullPath(ontology, ontConfig, log);
   
    if ( !file.canRead() ) {
      // This should not happen.
      return new InternalErrorResponse(
          file.getAbsolutePath()+ ": internal error: uploaded file "
          + (file.exists() ? "exists but cannot be read." : "not found.")
          + "Please, report this bug."
      );
    }

    // original model:
    final String uriFile = file.toURI().toString();
    final OntModel originalModel = JenaUtil2.loadModel(uriFile, false);

    if ( originalModel == null ) {
      // This should not happen.
      return new InternalErrorResponse(
          file.getAbsolutePath()+ ": internal error: uploaded file "
          + "cannot be read as an ontology model. "
          + "Please, report this bug."
      );
    }

    // corresponding unversioned model in case is requested:
    OntModel unversionedModel = null;
   
    if ( unversionedRequest ) {

      unversionedModel = UnversionedConverter.getUnversionedModel(originalModel, ontReq.mmiUri);
     
      if ( unversionedModel != null ) {
        if ( log.isDebugEnabled() ) {
          log.debug("_getResponseForMmiUri: obtained unversioned model");
        }
      }
      else {
        // error in conversion to unversioned version.
        // this is unexpected.
        // Continue with original model, if necessary; see below.
        log.error("_getResponseForMmiUri: unexpected: error in conversion to unversioned version.  But continuing with original model");
      }
    }

    String term = ontReq.mmiUri.getTerm();
   
    OntModel model = unversionedModel != null ? unversionedModel : originalModel;

    if ( term.length() == 0 ) {
      return new OntologyResponse(model);
    }
    else {
      // Term included.
      if ( log.isDebugEnabled() ) {
        log.debug("_getResponseForMmiUri: term=[" +term+ "].");
      }
      Model termModel = TermExtractor.getTermModel(model, ontReq.mmiUri);
      if ( termModel != null ) {
        return new TermResponse(termModel);
      }
      else {
        return null;
      }
    }
  }

 
  /**
   * Gets the response for a given ontology
   */
  void serviceForOntology() throws ServletException, IOException {
    OntRequest ontReq = _getThreadLocalOntRequest();
   
    if ( log.isDebugEnabled() ) {
      log.debug("serviceForOntology: req: " +ontReq);
    }
   
    Response resp = null;
   
    final File file = OntServlet.getFullPath(ontReq.ontology, ontConfig, log);
   
    if ( !file.canRead() ) {
      // This should not happen.
      String error = file.getAbsolutePath()+ ": internal error: uploaded file "
        + (file.exists() ? "exists but cannot be read." : "not found.")
        + "Please, report this bug."
      ;
      log.warn(error);
      resp = new InternalErrorResponse(error);
    }
    else {
      // original model:
      final String uriFile = file.toURI().toString();
      final OntModel originalModel = JenaUtil2.loadModel(uriFile, false);

      if ( originalModel == null ) {
        // This should not happen.
        String error = file.getAbsolutePath()+ ": internal error: uploaded file "
          + "cannot be read as an ontology model. "
          + "Please, report this bug."
        ;
        log.warn(error);
        resp = new InternalErrorResponse(error);
      }
      else {
        OntModel model = originalModel;

        // no explicit version requested and it's an unversioned MmiUri?
        if ( ontReq.version == null && ontReq.mmiUri != null && ontReq.mmiUri.getVersion() == null ) {
          model = UnversionedConverter.getUnversionedModel(originalModel, ontReq.mmiUri);
        }
        // issue #252: "omv:version gone?"
        else {
          String assignedVersion = JenaUtil2.setVersionFromCreationDateIfNecessary(model);
          if ( assignedVersion != null ) {
            // there actually was a synthetic assignment to omv.version
            log.info("synthetic assignment to omv.version: " +assignedVersion);
          }
        }

        resp = new OntologyResponse(model);
      }
    }
   
    if ( resp != null ) {
      resp.dispatch();
    }
    else {
      ontReq.response.sendError(HttpServletResponse.SC_NOT_FOUND, ontReq.ontology.getUri());   
    }

  }

 
  private Response _getResponseForNonMmiUri() {
    // ...  
    // NOT HANDLED YET -- I'm still testing the main dispatch above so I should be
    // only making regular MmiUri request for the moment. (see "ur2" in OntServlet)
    return null;
  }


}
TOP

Related Classes of org.mmisw.ont.UriResolver2$OntologyResponse

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.