/*
 * BIToolbarServlet.java
 *
 * Copyright © 1994-2004, Oracle. All rights reserved. Oracle grants
 * you ("Licensee") a non-exclusive, royalty-free, worldwide license to use,
 * modify and redistribute this software in source and binary code form, provided
 * that (i) this copyright notice and license appear on all copies of the
 * software; (ii) Licensee does not utilize the software in a manner disparaging
 * to Oracle; and (iii) Licensee does not utilize the software in a manner that
 * violates the terms of any Licensee agreement with Oracle.
 */
package samples.servlet;

import java.io.PrintWriter;

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

import oracle.cabo.share.util.CaboHttpUtils;
import oracle.cabo.ui.beans.StyleSheetBean;
import oracle.cabo.ui.beans.form.FormBean;
import oracle.cabo.ui.ServletRenderingContext;

import oracle.dss.thin.beans.BIConstants;
import oracle.dss.thin.beans.EventTargetImpl;
import oracle.dss.thin.beans.ThinBeanUI;
import oracle.dss.thin.beans.dataView.ThinDataviewCommon;
import oracle.dss.thin.beans.dataView.Presentation;
import oracle.dss.thin.beans.dataView.PresentationBean;
import oracle.dss.thin.beans.toolbar.ViewToolbar;
import oracle.dss.thin.beans.toolbar.ViewToolbarBean;
import oracle.dss.thin.beans.tools.ViewToolEvent;
import oracle.dss.thin.beans.tools.ViewToolListener;
import oracle.dss.thin.beans.tools.ViewTypeTool;
import oracle.dss.thin.servlet.ServletQueryParameterProvider;
import oracle.dss.thin.servlet.ServletRequestHandler;

import oracle.dss.util.DataSource;


/** 
 * The main class for the BIToolbarServlet sample. This sample extends the
 * BIServlet sample.
 * <P>
 * The BIToolbarServlet sample illustrates the following:
 * <ol>
 * <li>Using the toolbar to modify the view</li>
 * <li>Event handling. The current event and the source bean is displayed on the page</li>
 * </ol>
 * <P>
 */
public class BIToolbarServlet extends BIServlet {

  // the key for storing the BIHttpSession object on the HTTP session
  private static final String BI_HTTP_SESSION_KEY = "BIToolHttpSessionKey";

  // the name of the dataview
  protected static final String DATAVIEW_NAME = "dataview";
  // the name of the toolbar
  protected static final String TOOLBAR_NAME = "toolbar";
  // the name of the UIX FormBean component containing the thin bean components
  protected static final String FORM_NAME = "FormToolbarPresentation";
  
  /**
   * Processes the request while connected to the OLAP Server and for the BI Beans Catalog.
   *
   * @param request An HttpServletRequest object that contains the request that the
   * client has made of the servlet.
   * @param response An HttpServletResponse object that contains the response
   * that the servlet sends to the client
   *
   * @return <code>true</code> if the request was handled, <code>false</code>
   * otherwise.
   *
   * @throws Exception If the request could not be handled
   */
  protected boolean processRequest(HttpServletRequest request,
                                   HttpServletResponse response) throws Exception {
    
    BIHttpSession biHttpSession = getBIHttpSession(request);

    // make sure thin beans are initialized
    initializeThinBeans(request);

    // retrieves a query parameter value from the current request's URL    
    ServletQueryParameterProvider provider = new ServletQueryParameterProvider(
                                             request, response);
    
    // retrieve the request handler from the session. 
    ServletRequestHandler handler = biHttpSession.getServletRequestHandler();

    // use locale retrieved from browser
    setLocale(CaboHttpUtils.determineLocale(request));
    handler.setLocale(getLocale());

    // process form fields of all registered ThinBeans
    handler.processInput(provider);

    // handle thin bean events. The ServletRequestHandler object determines 
    // the thin bean object that should handle a thin bean event using the 
    // BIConstants.SOURCE parameter from the provider object. The thin beans
    // are registered with the handler object in the initializeThinBeans method.
    // The handleEvent method on the thin bean object is invoked to allow the
    // thin bean to handle the event. The thin bean returns the result of the
    // event handling
    int nRetVal = handler.handleEvent(provider);

    // test whether processing is completed for the request. The thin bean 
    // will return ThinBeanUI.EVENT_RESPONSE_DONE if the 
    // BIConstants.EXPORT_EVENT event is handled. No rendering is required
    // after the BIConstants.EXPORT_EVENT event is processed
    if (nRetVal == ThinBeanUI.EVENT_RESPONSE_DONE) {
      return false;
    }
    
    // begin generating HTML 
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    
    // create rendering context for UIX Components (UINodes)
    ServletRenderingContext renderingContext = createRenderingContext(request, response);

    // prepare the ServletRenderingContext for output
    renderingContext.prepareOutput(out, null, "text/html", null);

    out.println("<HTML>");
    out.println("<HEAD>");
    out.println("<TITLE>BI Beans Sample - Toolbar/View Interaction and Event Handling</TITLE>");
    
    // render the style sheet for the UIX components
    StyleSheetBean.sharedInstance().render(renderingContext);

    out.println("</HEAD>");
    out.println("<BODY>");
      
    renderPageHeader(out, request, response);

    String event = provider.getQueryParameter(BIConstants.EVENT);
    String source = provider.getQueryParameter(BIConstants.SOURCE);
    if(event != null && source != null) {
      out.println("<BR>");
      out.println("<TABLE>");
      out.println("<TR>");
      out.println("<TD>Event<TD>");
      out.println("<TD>=<TD>");
      out.println("<TD>" + event + "<TD>");
      out.println("</TR>");
      out.println("<TR>");
      out.println("<TD>Source<TD>");
      out.println("<TD>=<TD>");
      out.println("<TD>" + source + "<TD>");
      out.println("</TR>");
      out.println("</TABLE>");
      out.println("<BR>");
    }
            
    // prepare UIX Component (UINode) tree
    FormBean rootNode = new FormBean(FORM_NAME);
    rootNode.setMethod("POST");
    
    // retrieve the toolbar from the servlet request handler
    ViewToolbar viewToolbar = (ViewToolbar) handler.getThinBean(TOOLBAR_NAME);
    if(viewToolbar != null) {
      // add the toolbar as a child of the rootNode i.e. FormBean
      ViewToolbarBean viewToolbarBean = new ViewToolbarBean(viewToolbar);
      rootNode.addIndexedChild(viewToolbarBean);
    }

    // retrieve the data view from the servlet request handler
    Presentation presentation = (Presentation)handler.getThinBean(PRESENTATION_NAME);
    if (presentation != null) {
      rootNode.addIndexedChild(new PresentationBean(presentation));

      // update the data view reference in the toolbar
      if (BIConstants.VIEW_TYPE_CHANGED_EVENT.equalsIgnoreCase(event))
        viewToolbar.setView(presentation.getView());
    }

    rootNode.render(renderingContext);
    
    renderPageFooter(out, request, response);
    
    out.println("</BODY>");
    out.println("</HTML>");
    
    return true;
  }
  
  /**
   * This method returns the key for storing the BIHttpSession object on the HTTP session
   *
   * @return The key for storing the BIHttpSession object on the HTTP session
   */
  protected String getHttpSessionKey() {
    return BI_HTTP_SESSION_KEY;
  }

  /**
   * Retrieves the title of the sample. Derived classes should override this
   * method to provide custom titles.
   *
   * @return The title of the sample.
   */
  protected String getSampleTitle() {
    return "BI Beans Sample - Toolbar/View Interaction and Event Handling";
  }

  /**
   * Retrieves the description of the sample. Derived classes should override
   * this method to provide custom descriptions.
   *
   * @return The description of the sample.
   */
  protected String getSampleDescription() {
    return "This sample shows the interaction between a thin-bean toolbar and a presentation. " + 
           "The sample shows how thin-bean events are routed to different beans.";
  }
  
  /**
   * Initializes thin beans
   *
   * @param request An HttpServletRequest object that contains the request that
   * the client has made of the servlet.
   *
   * @throws Exception If an error is detected when the thin beans are being
   * initialized.
   */
  protected void initializeThinBeans(HttpServletRequest request) throws Exception {
    BIHttpSession biHttpSession = getBIHttpSession(request);

    ServletRequestHandler handler = biHttpSession.getServletRequestHandler();
    
    Presentation presentation = (Presentation) handler.getThinBean(PRESENTATION_NAME);
    if (null == presentation) {
      //retrieve default data source from the base class
      DataSource dataSource = getDefaultDataSource(request);

      // create a Crosstab by default
      presentation = new Presentation(ViewTypeTool.CROSSTAB);
      presentation.setThinBeanName(PRESENTATION_NAME);

      ThinDataviewCommon crosstab = presentation.getView();
      crosstab.setPagingControlVisible(true);
      crosstab.setDataSource(dataSource);
      handler.registerThinBean(presentation);

      // create and register a ViewToolbar bean
      ViewToolbar viewToolbar = new ViewToolbar();
      viewToolbar.setThinBeanName(TOOLBAR_NAME);
      viewToolbar.setView(crosstab);
      handler.registerThinBean(viewToolbar);

      // let presentation bean handles the viewTypeChange event
      for (int i = 0; i < viewToolbar.getChildCount(); i++) {
        if (viewToolbar.getChild(i) instanceof ViewTypeTool) {
          ViewTypeTool tool = (ViewTypeTool)viewToolbar.getChild(i);

          EventTargetImpl eventTarget = (EventTargetImpl)tool.getEventTarget(BIConstants.VIEW_TYPE_CHANGED_EVENT);

          if (eventTarget == null) {
            eventTarget = new EventTargetImpl(null, null, PRESENTATION_NAME, null);
            tool.setEventTarget(BIConstants.VIEW_TYPE_CHANGED_EVENT, eventTarget);
          }
        }
      }
    }
  }

}
