/* Copyright (c) 2001, 2002 Oracle Corporation. All Rights Reserved. */
package oracle.portal.sample.v2.devguide.partnerApp;

import java.io.Writer;
import java.io.IOException;

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

import oracle.portal.provider.v2.PortletException;
import oracle.portal.provider.v2.ProviderSession;
import oracle.portal.provider.v2.http.ServletProviderSession;
import oracle.portal.provider.v2.http.HttpCommonConstants;
import oracle.portal.provider.v2.render.PortletRenderRequest;
import oracle.portal.provider.v2.render.PortletRenderer;

import oracle.webdb.utils.SimpleStringBuffer;

/**
 * <code>FlightDispatch</code> handles renditions for the Fancy Flights
 * application both in standalone mode and in a portlet context, thus
 * demonstrating the ease with which existing applications can be integrated
 * with Oracle 9<i>i</i>AS Portal.<P>
 *
 * The servlet based implementation of this example application facilitates
 * demonstration of communication between standalone and portlet mode via the
 * session.
 */
public class FlightDispatch
{
    // Application params.
    private static final String ACTION = "FlightAction";
    private static final String ID = "FlightId";
    private static final String SHOWDETAILS = "details";
    private static final String ACCESS_COUNT_ATTR = "count";

    // Link fragment to save generating multiple times.
    private static final String LINK_FRAGMENT = "?" + ACTION + "=" +
        SHOWDETAILS + "&" + ID + "=";

    // Path to the Fancy Flights servlet. The path is required to build up the
    // deep links, this field is only required in the portlet context where
    // getServletPath() returns the path to the JPDK servlet.
    private String mServletPath = null;

    /**
     * Constructs a <code>FlightDispatch</code> instance.
     */
    public FlightDispatch(String servletPath)
    {
        mServletPath = servletPath;
    }

    /**
     * Performs the rendition when the Fancy Flights application is accessed
     * from the web application font end. By this stage, users will have
     * already been authenticated by <code>mod_osso</code>.
     *
     * @param req the <code>javax.servlet.http.HttpServleRequest</code> object.
     * @param res the <code>javax.servlet.http.HttpServleResponse</code>
     * object.
     */
    public void process(HttpServletRequest req, HttpServletResponse res)
        throws ServletException, IOException
    {
        // mod_osso should be sending us the username, cry if not.
        String username = req.getRemoteUser();
        if (username == null)
        {
            throw new ServletException("Unauthenticated user");
        }

        // Grab the HttpSession and increment the access counter.
        HttpSession session = req.getSession(true);
        int[] count = null;
        count = (int[])session.getAttribute(ACCESS_COUNT_ATTR);
        if (count == null)
        {
            count = new int[1];
            session.setAttribute(ACCESS_COUNT_ATTR, count);
        }
        count[0]++;


        // Grab all the necessary bits and pieces to hand off to the rendition
        // methods.
        String baseUrl = getBaseUrl(req);
        res.setContentType(PortletRenderer.TYPE_HTML);
        Writer out = res.getWriter();
        String action = req.getParameter(ACTION);
        String id = req.getParameter(ID);

        //Render the flight details if we have the relevant params, otherwise
        //just render the summary pages.
        if (action != null && id != null && id.length() > 0 &&
            action.equalsIgnoreCase(SHOWDETAILS))
        {
            showDetails(username, count[0], id, out);
        }
        else
        {
            showList(username, count[0], baseUrl, out, false);
        }

    }

    /**
     * Performs the rendition when the Fancy Flights application is accessed
     * from the web application font end. By this stage, users will have
     * already been authenticated by <code>mod_osso</code>.
     *
     * @param pr the
     * <code>oracle.portal.provider.v2.render.PortletRenderRequest</code>
     * for this rendition.
     */
    public void process(PortletRenderRequest pr) throws PortletException,
        IOException
    {
        // Portal user must me strongly authenticated to use this portlet.
        if (!pr.getUser().isLoggedOn())
        {
            throw new PortletException("User not logged on");
        }

        // Get the http request/response objects for this rendition.
        HttpServletRequest req = (HttpServletRequest)
            pr.getAttribute(HttpCommonConstants.SERVLET_REQUEST);
        HttpServletResponse res = (HttpServletResponse)
            pr.getAttribute(HttpCommonConstants.SERVLET_RESPONSE);

        // Grab the provider session and increment the access counter.
        ProviderSession session = pr.getSession();
        int[] count = { -1 };
        if (session != null)
        {
            count = ((int[])session.getAttribute(ACCESS_COUNT_ATTR));
            if (count == null)
            {
                count = new int[1];
                session.setAttribute(ACCESS_COUNT_ATTR, count);
            }
            count[0]++;
        }

        // Grab all the necessary bits and pieces to hand off to the rendition
        // method.
        String username = pr.getUser().getName();
        String baseUrl = getBaseUrl(req);
        res.setContentType(PortletRenderer.TYPE_HTML);
        Writer out = res.getWriter();

        // For the portlet version, we only render the summary page which
        // contains deep links to the flight detail pages.
        showList(username, count[0], baseUrl, out, true);
    }

    /**
     * Renders the flights summary screen.
     *
     * @param user The user who is logged in.
     * @param count The number of times this application has been
     * accessed.
     * @param baseUrl absolute path to the servlet for building deep links.
     * @param out output writer for output.
     */
    private void showList(String user, int count, String baseUrl, Writer out,
                          boolean isWebProvider)
        throws IOException
    {
        if (!isWebProvider)
        {
            out.write("<HTML>");
            out.write("<HEAD>");
            out.write("<TITLE>Flights</TITLE></HEAD>");
            out.write("</HEAD>");
            out.write("<BODY>");
        }
        out.write("<font size=-2>Welcome " + user + "</font><br>");
        out.write("<CENTER>");
        out.write("<center><b><font color=\"#33CCFF\"><font size=+1>");
        out.write("Flights Of Fancy</font></font></b></center>");

        out.write("<br><b><font color=\"#3366FF\"></font></b>&nbsp;");
        out.write("<table BORDER=0 CELLSPACING=2 CELLPADDING=2 " +
                  "WIDTH=\"100%\" >");
        out.write("<tr>");
        out.write("<td><b><font color=\"#3333FF\">Flight Num</font></b></td>");
        out.write("<td><b><font color=\"#3333FF\">From</font></b></td>");
        out.write("<td><b><font color=\"#3333FF\">To</font></b></td>");
        out.write("<td><b><font color=\"#3333FF\">Departure</font></b></td>");
        out.write("<td><b><font color=\"#3333FF\">Arrival</font></b></td>");
        out.write("</tr>");
        out.write("<tr>");
        out.write("<TD><A href=\"" + getFullUrl("123456", baseUrl) + "\">");
        out.write("<font size=-1>123456</font></A></td>");
        out.write("<td><font size=-1>JFK</font></td>");
        out.write("<td><font size=-1>MIA</font></td>");
        out.write("<td><font size=-1>6:00 AM EST 12/12/2002</font></td>");
        out.write("<td><font size=-1>9:37 AM EST 12/12/2002</font></td>");
        out.write("</tr>");
        out.write("<tr>");
        out.write("<TD><A href=\"" + getFullUrl("234567", baseUrl) + "\">");
        out.write("<font size=-1>234567</font></A></td>");
        out.write("<td><font size=-1>IAD</font></td>");
        out.write("<td><font size=-1>BWI</font></td>");
        out.write("<td><font size=-1>5:00 PM EST 8/22/2002</font></td>");
        out.write("<td><font size=-1>6:45 PM EST 8/22/2002</font></td>");
        out.write("</tr>");
        out.write("<tr>");
        out.write("<td><A href=\"" + getFullUrl("345678", baseUrl) + "\">");
        out.write("<font size=-1>345678</font></A></td>");
        out.write("<td><font size=-1>SFI</font></td>");
        out.write("<td><font size=-1>NAT</font></td>");
        out.write("<td><font size=-1>1:25 PM PST 10/18/2002</font></td>");
        out.write("<td><font size=-1>4:37 AM EST 10/19/2002</font></td>");
        out.write("</tr>");
        out.write("<tr>");
        out.write("<td><A href=\"" + getFullUrl("456789", baseUrl) + "\">");
        out.write("<font size=-1>456789</font></A></td>");
        out.write("<td><font size=-1>OCH</font></td>");
        out.write("<td><font size=-1>DIA</font></td>");
        out.write("<td><font size=-1>10:00 PM CST 2/05/2002</font></td>");
        out.write("<td><font size=-1>2:11 AM CST 2/06/2002</font></td>");
        out.write("</tr>");
        out.write("</table>");
        out.write("<center><font color=\"#33CCFF\"><font size=-2>");
        out.write("All Times and flights are subject");
        out.write("to change without notification.&nbsp; Please consult our ");
        out.write("reservations center ");
        out.write("for exact flights and times.</font></font></center>");
        out.write("</CENTER>");
        if (count > -1)
        {
            out.write("<font size=-2>This session has rendered " + count +
                      " times</font><br>");
        }
        else
        {
            out.write("<font size=-2>Your session is lost. Please log out " +
                      "then log back in.</font><br>");
        }
        if (!isWebProvider)
        {
            out.write("</BODY>");
            out.write("</HTML>");
        }
        else
        {
            out.write("</td></tr></table>");
        }
        out.flush();
        out.close();
    }

    /**
     *  Displays full details about a paticular flight.
     *
     *  @param user The user who is logged in.
     *  @param count The number of times this application has been accessed.
     *  @param out output writer for output.
     *  @param id id of the flight being displayed.
     */
    private void showDetails(String user, int count, String id, Writer out)
        throws IOException
    {
        out.write("<HTML>");
        out.write("<HEAD>");
        out.write("<TITLE>Flight "+ id + "</TITLE></HEAD>");
        out.write("</HEAD>");
        out.write("<BODY>");
        out.write("<font size=-2>Welcome " + user + "</font><br>");
        out.write("<center><b><font color=\"#33CCFF\"><font size=+1>");
        out.write("Flights Of Fancy</font></font></b></center>");
        out.write("<b><font color=\"#3333FF\">Details for " + id +
                  "</font></b>");
        out.write("<br>");
        out.write("<hr WIDTH=\"100%\">");
        out.write("<br><font color=\"#000000\"><font size=-1>");
        out.write("Flight " + id + " operated by Fancy");
        out.write("Flying Airlines on a Wing Stream 77 Turbo Prop." +
                  "</font></font>");
        out.write("<blockquote><font size=-1><font color=\"#000000\">");
        out.write("Departs:&nbsp;&nbsp; </font>6:00");
        out.write("AM EST 12/12/2002 From: JFK</font>");
        out.write("<br><font size=-1>Arrives:&nbsp; 9:37 AM EST 12/12/2002");
        out.write(" At: MIA</font>");
        out.write("<br><font size=-1>Stops:&nbsp; None</font>");
        out.write("<blockquote><font size=-1>Altitude:&nbsp; 35,000ft</font>");
        out.write("<br><font size=-1>Seating:&nbsp; Coach</font>");
        out.write("<br><font size=-1>Preferences:&nbsp; Exit Row</font>");
        out.write("<br><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.write("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        out.write("&nbsp;&nbsp;&nbsp;&nbsp;");
        out.write("Window</font>");
        out.write("<br><font size=-1>Smoking:&nbsp; No</font>");
        out.write("<br><font size=-1>Meals:&nbsp; ");
        out.write("Breakfast / Snack</font></blockquote>");
        out.write("<font size=-1>Price:&nbsp; $875</font></blockquote>");
        out.write("<hr WIDTH=\"100%\">");
        out.write("<center><font color=\"#33CCFF\"><font size=-2>");
        out.write("All Times and flights are subject");
        out.write("to change without notification.&nbsp; Please consult ");
        out.write("our reservations center");
        out.write("for exact flights and times.</font></font></center>");
        out.write("<font size=-2>This session has rendered " + count +
                  " times</font><br>");
        out.write("</BODY>");
        out.write("</HTML>");
        out.flush();
        out.close();
    }

    /**
     * Builds the base url. If present, mServletPath overides the path obtained
     * from the request.
     */
    private String getBaseUrl(HttpServletRequest req)
    {
        SimpleStringBuffer buff = new SimpleStringBuffer(50);
        buff.append(req.getScheme());
        buff.append("://");
        buff.append(req.getServerName());
        buff.append(":");
        buff.append(req.getServerPort());
        buff.append(req.getContextPath());
        if (mServletPath == null)
        {
            buff.append(req.getServletPath());
        }
        else
        {
            buff.append(mServletPath);
        }
        return buff.toString();
    }

    /**
     * Builds a full url for a deep link.
     */
    private String getFullUrl(String id, String baseUrl)
    {
        SimpleStringBuffer url = new SimpleStringBuffer(baseUrl);
        url.append(LINK_FRAGMENT);
        url.append(id);
        return url.toString();
    }

}
