Package org.archive.wayback.webapp

Source Code of org.archive.wayback.webapp.AccessPoint

/* WaybackContext
*
* $Id$
*
* Created on 5:37:31 PM Apr 20, 2007.
*
* Copyright (C) 2007 Internet Archive.
*
* This file is part of wayback-webapp.
*
* wayback-webapp is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* any later version.
*
* wayback-webapp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser Public License
* along with wayback-webapp; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
package org.archive.wayback.webapp;

import java.io.IOException;
import java.util.Properties;
import java.util.logging.Logger;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.archive.wayback.QueryRenderer;
import org.archive.wayback.ReplayDispatcher;
import org.archive.wayback.RequestParser;
import org.archive.wayback.ResultURIConverter;
import org.archive.wayback.WaybackConstants;
import org.archive.wayback.accesscontrol.ExclusionFilterFactory;
import org.archive.wayback.core.CaptureSearchResults;
import org.archive.wayback.core.Resource;
import org.archive.wayback.core.SearchResult;
import org.archive.wayback.core.SearchResults;
import org.archive.wayback.core.UIResults;
import org.archive.wayback.core.WaybackRequest;
import org.archive.wayback.exception.AuthenticationControlException;
import org.archive.wayback.exception.BadQueryException;
import org.archive.wayback.exception.ResourceNotAvailableException;
import org.archive.wayback.exception.ResourceNotInArchiveException;
import org.archive.wayback.exception.WaybackException;
import org.archive.wayback.util.operator.BooleanOperator;
import org.springframework.beans.factory.BeanNameAware;

/**
* Retains all information about a particular Wayback configuration
* within a ServletContext, including holding references to the
* implementation instances of the primary Wayback classes:
*
*    ResourceIndex
*    ResourceStore
*    QueryUI
*    ReplayUI 
*
* @author brad
* @version $Date$, $Revision$
*/
public class AccessPoint implements RequestContext, BeanNameAware {

  private static final Logger LOGGER = Logger.getLogger(
      AccessPoint.class.getName());
 
  private boolean useServerName = false;
  private int contextPort = 0;
  private String contextName = null;
  private WaybackCollection collection = null;
  private ReplayDispatcher replay = null;
  private QueryRenderer query = null;
  private RequestParser parser = null;
  private ResultURIConverter uriConverter = null;
  private Properties configs = null;
  private ExclusionFilterFactory exclusionFactory = null;
  private BooleanOperator<WaybackRequest> authentication = null;

  /**
   *
   */
  public AccessPoint() {
   
  }
 
  /* (non-Javadoc)
   * @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
   */
  public void setBeanName(String beanName) {
    // TODO Auto-generated method stub
    this.contextName = "";
    int idx = beanName.indexOf(':');
    if(idx > -1) {
      contextPort = Integer.valueOf(beanName.substring(0,idx));
      contextName = beanName.substring(idx + 1);
    } else {
      try {
        this.contextPort = Integer.valueOf(beanName);
      } catch(NumberFormatException e) {
        e.printStackTrace();
      }
    }
  }
  /**
   * @param httpRequest
   * @return the prefix of paths recieved by this server that are handled by
   * this WaybackContext, including the trailing '/'
   */
  public String getContextPath(HttpServletRequest httpRequest) {
//    if(contextPort != 0) {
//      return httpRequest.getContextPath();
//    }
    String httpContextPath = httpRequest.getContextPath();
    if(contextName.length() == 0) {
      return httpContextPath + "/";
    }
    return httpContextPath + "/" + contextName + "/";
  }

  /**
   * @param httpRequest
   * @param includeQuery
   * @return the portion of the request following the path to this context
   * without leading '/'
   */
  private String translateRequest(HttpServletRequest httpRequest,
      boolean includeQuery) {

    String origRequestPath = httpRequest.getRequestURI();
    if(includeQuery) {
      String queryString = httpRequest.getQueryString();
      if (queryString != null) {
        origRequestPath += "?" + queryString;
      }
    }
    String contextPath = getContextPath(httpRequest);
    if (!origRequestPath.startsWith(contextPath)) {
      if(contextPath.startsWith(origRequestPath)) {
        // missing trailing '/', just omit:
        return "";
      }
      return null;
    }
    return origRequestPath.substring(contextPath.length());
  }
 
  /**
   * @param httpRequest
   * @return the portion of the request following the path to this context,
   * including any query information,without leading '/'
   */
  public String translateRequestPathQuery(HttpServletRequest httpRequest) {
    return translateRequest(httpRequest,true);
 

  /**
   * @param httpRequest
   * @return the portion of the request following the path to this context,
   * excluding any query information, without leading '/'
   */
  public String translateRequestPath(HttpServletRequest httpRequest) {
    return translateRequest(httpRequest,false);
 
 
  /**
   * Construct an absolute URL that points to the root of the context that
   * recieved the request, including a trailing "/".
   *
   * @return String absolute URL pointing to the Context root where the
   *         request was revieved.
   */
  private String getAbsoluteContextPrefix(HttpServletRequest httpRequest,
      boolean useRequestServer) {
   
    StringBuilder prefix = new StringBuilder();
    prefix.append(WaybackConstants.HTTP_URL_PREFIX);
    String waybackPort = null;
    if(useRequestServer) {
      prefix.append(httpRequest.getLocalName());
      waybackPort = String.valueOf(httpRequest.getLocalPort());
    } else {
      prefix.append(httpRequest.getServerName());
      waybackPort = String.valueOf(httpRequest.getServerPort());
    }
    if (!waybackPort.equals(WaybackConstants.HTTP_DEFAULT_PORT)) {
      prefix.append(":").append(waybackPort);
    }
    String contextPath = getContextPath(httpRequest);
//    if(contextPath.length() > 1) {
//      prefix.append(contextPath);
//    } else {
//      prefix.append(contextPath);
//    }
    prefix.append(contextPath);
    return prefix.toString();
  }
 
  /**
   * @param httpRequest
   * @return absolute URL pointing to the base of this WaybackContext, using
   * Server and port information from the HttpServletRequest argument.
   */
  public String getAbsoluteServerPrefix(HttpServletRequest httpRequest) {
    return getAbsoluteContextPrefix(httpRequest, true);
  }

  /**
   * @param httpRequest
   * @return absolute URL pointing to the base of this WaybackContext, using
   * Canonical server and port information.
   */
  public String getAbsoluteLocalPrefix(HttpServletRequest httpRequest) {
    return getAbsoluteContextPrefix(httpRequest, useServerName);
  }

  private boolean dispatchLocal(HttpServletRequest httpRequest,
      HttpServletResponse httpResponse)
  throws ServletException, IOException {
   
    WaybackRequest wbRequest = new WaybackRequest();
    wbRequest.setContextPrefix(getAbsoluteLocalPrefix(httpRequest));
    wbRequest.setContext(this);
    UIResults uiResults = new UIResults(wbRequest);
    String translated = "/" + translateRequestPathQuery(httpRequest);
    uiResults.storeInRequest(httpRequest,translated);
    RequestDispatcher dispatcher = null;
//    // special case for the front '/' page:
//    if(translated.length() == 0) {
//      translated = "/";
//    } else {
//      translated = "/" + translated;
//    }
    dispatcher = httpRequest.getRequestDispatcher(translated);
    if(dispatcher != null) {
      dispatcher.forward(httpRequest, httpResponse);
      return true;
    }
    return false;
  }
 
  /**
   * @param httpRequest
   * @param httpResponse
   * @return true if the request was actually handled
   * @throws ServletException
   * @throws IOException
   */
  public boolean handleRequest(HttpServletRequest httpRequest,
      HttpServletResponse httpResponse)
  throws ServletException, IOException {

    httpResponse.setHeader("header", httpRequest.getHeader("referer") );

    WaybackRequest wbRequest = null;
    boolean handled = false;

    try {
      wbRequest = parser.parse(httpRequest, this);

      if(wbRequest != null) {
        wbRequest.setContext(this);
        handled = true;
        wbRequest.setContextPrefix(getAbsoluteLocalPrefix(httpRequest));
        if(authentication != null) {
          if(!authentication.isTrue(wbRequest)) {
            throw new AuthenticationControlException("Not authorized");
          }
        }

        if(exclusionFactory != null) {
          wbRequest.setExclusionFilter(exclusionFactory.get());
        }
        if(wbRequest.isReplayRequest()) {

          handleReplay(wbRequest,httpRequest,httpResponse);
         
        } else {

          handleQuery(wbRequest,httpRequest,httpResponse);
        }
      } else {
        handled = dispatchLocal(httpRequest,httpResponse);
      }

    } catch (BadQueryException e) {
      query.renderException(httpRequest, httpResponse, wbRequest, e);
    } catch (AuthenticationControlException e) {
      query.renderException(httpRequest, httpResponse, wbRequest, e);
    }

    return handled;
  }

  private void handleReplay(WaybackRequest wbRequest,
      HttpServletRequest httpRequest, HttpServletResponse httpResponse)
  throws IOException, ServletException {
    Resource resource = null;
    try {
      SearchResults results = collection.getResourceIndex().query(wbRequest);
      if(!(results instanceof CaptureSearchResults)) {
        throw new ResourceNotAvailableException("Bad results...");
      }
      CaptureSearchResults captureResults = (CaptureSearchResults) results;
 
      // TODO: check which versions are actually accessible right now?
      SearchResult closest = captureResults.getClosest(wbRequest);
      resource = collection.getResourceStore().retrieveResource(closest);
 
      replay.renderResource(httpRequest, httpResponse, wbRequest,
          closest, resource, uriConverter, captureResults);
    } catch(WaybackException e) {
      logNotInArchive(e,wbRequest);
      replay.renderException(httpRequest, httpResponse, wbRequest, e);
    } finally {
      if(resource != null) {
        resource.close();
      }
    }
  }

  private void handleQuery(WaybackRequest wbRequest,
      HttpServletRequest httpRequest, HttpServletResponse httpResponse)
  throws ServletException, IOException {

    try {
      SearchResults results = collection.getResourceIndex().query(wbRequest);
      if(results.getResultsType().equals(
          WaybackConstants.RESULTS_TYPE_CAPTURE)) {
        CaptureSearchResults cResults = (CaptureSearchResults) results;
        SearchResult closest = cResults.getClosest(wbRequest);
        closest.put(WaybackConstants.RESULT_CLOSEST_INDICATOR,
            WaybackConstants.RESULT_CLOSEST_VALUE);
        query.renderUrlResults(httpRequest,httpResponse,wbRequest,
            results,uriConverter);

      } else {
        query.renderUrlPrefixResults(httpRequest,httpResponse,wbRequest,
            results,uriConverter);
      }
    } catch(WaybackException e) {
      logNotInArchive(e,wbRequest);
      query.renderException(httpRequest, httpResponse, wbRequest, e);
    }
  }
 
  public void shutdown() throws IOException {
    if(collection != null) {
      collection.shutdown();
    }
  }
 
  private void logNotInArchive(WaybackException e, WaybackRequest r) {
    if(e instanceof ResourceNotInArchiveException) {
      String url = r.get(WaybackConstants.REQUEST_URL);
      StringBuilder sb = new StringBuilder(100);
      sb.append("NotInArchive\t");
      sb.append(contextName).append("\t");
      sb.append(contextPort).append("\t");
      sb.append(url);
     
      LOGGER.info(sb.toString());
    }
  }

  /**
   * @param contextPort the contextPort to set
   */
  public void setContextPort(int contextPort) {
    this.contextPort = contextPort;
  }

  /**
   * @param contextName the contextName to set
   */
  public void setContextName(String contextName) {
    this.contextName = contextName;
  }

  /**
   * @param replay the replay to set
   */
  public void setReplay(ReplayDispatcher replay) {
    this.replay = replay;
  }

  /**
   * @param query the query to set
   */
  public void setQuery(QueryRenderer query) {
    this.query = query;
  }

  /**
   * @param parser the parser to set
   */
  public void setParser(RequestParser parser) {
    this.parser = parser;
  }

  /**
   * @param uriConverter the uriConverter to set
   */
  public void setUriConverter(ResultURIConverter uriConverter) {
    this.uriConverter = uriConverter;
  }

  /**
   * @return the URI conveter
   */
  public ResultURIConverter getUriConverter() {
    return uriConverter;
  }

  /**
   * @return the contextPort
   */
  public int getContextPort() {
    return contextPort;
  }

  /**
   * @return the configs
   */
  public Properties getConfigs() {
    return configs;
  }

  /**
   * @param configs the configs to set
   */
  public void setConfigs(Properties configs) {
    this.configs = configs;
  }

  /**
   * @return the useServerName
   */
  public boolean isUseServerName() {
    return useServerName;
  }

  /**
   * @param useServerName the useServerName to set
   */
  public void setUseServerName(boolean useServerName) {
    this.useServerName = useServerName;
  }

  public ExclusionFilterFactory getExclusionFactory() {
    return exclusionFactory;
  }

  public void setExclusionFactory(ExclusionFilterFactory exclusionFactory) {
    this.exclusionFactory = exclusionFactory;
  }

  public BooleanOperator<WaybackRequest> getAuthentication() {
    return authentication;
  }

  public void setAuthentication(BooleanOperator<WaybackRequest> authentication) {
    this.authentication = authentication;
  }

  public WaybackCollection getCollection() {
    return collection;
  }

  public void setCollection(WaybackCollection collection) {
    this.collection = collection;
  }
}
TOP

Related Classes of org.archive.wayback.webapp.AccessPoint

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.