/* * Licensed Materials - Property of Perforce Software, Inc. * © Copyright Perforce Software, Inc. 2014, 2021 * © Copyright IBM Corp. 2009, 2014 * © Copyright ILOG 1996, 2009 * All Rights Reserved. * * Note to U.S. Government Users Restricted Rights: * The Software and Documentation were developed at private expense and * are "Commercial Items" as that term is defined at 48 CFR 2.101, * consisting of "Commercial Computer Software" and * "Commercial Computer Software Documentation", as such terms are * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4, * as applicable. */ package thinstock; import java.awt.Point; import java.awt.Rectangle; import java.io.IOException; import java.io.PrintWriter; import java.text.DateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import ilog.views.chart.IlvChart; import ilog.views.chart.IlvDataInterval; import ilog.views.chart.IlvDataWindow; import ilog.views.chart.IlvDoublePoints; import ilog.views.chart.data.IlvDataPoints; import ilog.views.chart.data.IlvDataSetPoint; import ilog.views.chart.faces.servlet.IlvFacesChartServlet; import ilog.views.chart.faces.servlet.IlvFacesChartServletSupport; import ilog.views.chart.servlet.IlvChartServerAction; import ilog.views.chart.servlet.IlvChartServerActionEvent; import ilog.views.chart.servlet.IlvChartServletSupport; import ilog.views.chart.servlet.IlvDefaultIMapAttributes; import ilog.views.chart.servlet.IlvDefaultIMapDefinition; import ilog.views.chart.servlet.IlvIMapArea; import ilog.views.chart.servlet.IlvIMapAttributes; import ilog.views.chart.servlet.IlvIMapDefinition; import ilog.views.chart.servlet.IlvJPEGEncoder; import ilog.views.chart.servlet.IlvPanAction; import ilog.views.chart.servlet.IlvParameterException; import ilog.views.chart.servlet.IlvServletRequestParameters; import ilog.views.chart.servlet.IlvZoomAction; import ilog.views.util.IlvResourceUtil; import ilog.views.util.servlet.IlvServletPageIdUtil; import stock.ExponentAxisTransformer; import stock.StockUtil; import stock.ThresholdLines; /** * A <code>ChartServletSupport</code> subclass to display stock quotes in DHTML * views. */ class StockDemoSupport extends IlvFacesChartServletSupport { public static final String LOAD_QUOTES_ACTION = "LoadQuotesAction"; public static final String LOWER_INDICATOR_ACTION = "SetLowerIndicatorAction"; public static final String UPPER_INDICATOR_ACTION = "SetUpperIndicatorAction"; public static final String CHART_PARAM = "chart"; public static final String MAIN_CHART = "main"; public static final String LOWER1_CHART = "lower1"; public static final String LOWER2_CHART = "lower2"; // A ServerAction to load quotes final class LoadQuotesServerAction implements IlvChartServerAction { Override public void actionPerformed(IlvChartServerActionEvent e) throws ServletException { StockDemoApp demo = getApp(e.getRequest()); String symbol = e.getStringParameter(0); Date from = new Date(e.getLongParameter(1)); Date to = new Date(e.getLongParameter(2)); int freq = e.getIntParameter(3); int ns = e.getParameterCount() - 4; String[] secsymbols = null; if (ns > 0) { secsymbols = new String[ns]; for (int i = 0; i < ns; ++i) secsymbols[i] = e.getStringParameter(4 + i); } demo.loadQuotes(symbol, from, to, freq, secsymbols); } Override public int getExecutionThread() { return IlvChartServerAction.REQUEST_THREAD; } } // A ServerAction to set an indicator on a lower chart final class LowerIndicatorServerAction implements IlvChartServerAction { Override public void actionPerformed(IlvChartServerActionEvent event) throws ServletException { StockDemoApp demo = getApp(event.getRequest()); int indicatorIdx = event.getIntParameter(0); // int chartIdx = event.getIntParameter(1); String chartId = event.getStringParameter(1); int chartIdx; // if (LOWER1_CHART.equals(chartId)) // chartIdx = 0; // else // chartIdx = 1; String nb = chartId.substring(5); chartIdx = Integer.parseInt(nb) - 1; demo.setLowerIndicator(chartIdx, indicatorIdx); } Override public int getExecutionThread() { return IlvChartServerAction.REQUEST_THREAD; } } // A ServerAction to set an indicator on the main chart final class UpperIndicatorServerAction implements IlvChartServerAction { Override public void actionPerformed(IlvChartServerActionEvent event) throws ServletException { StockDemoApp demo = getApp(event.getRequest()); int[] indicators = new int[event.getParameterCount()]; for (int i = 0; i < event.getParameterCount(); ++i) indicators[i] = event.getIntParameter(i); demo.setUpperIndicators(indicators); } Override public int getExecutionThread() { return IlvChartServerAction.REQUEST_THREAD; } } // A ServerAction to change the type of the overview representation final class SetOverviewRepAction implements IlvChartServerAction { Override public void actionPerformed(IlvChartServerActionEvent evt) throws ServletException { StockDemoApp demo = getApp(evt.getRequest()); demo.setOverviewRepresentation(evt.getIntParameter(0)); } Override public int getExecutionThread() { return IlvChartServerAction.REQUEST_THREAD; } } // A ServerAction to adjust threshold lines. static final class SetThresholdAction implements IlvChartServerAction { Override public void actionPerformed(IlvChartServerActionEvent evt) throws ServletException { if (ThresholdLines.get(evt.getChart(), 0) == null) return; Point upperPt = new Point((int) evt.getFloatParameter(0), (int) evt.getFloatParameter(1)); Point lowerPt = new Point((int) evt.getFloatParameter(2), (int) evt.getFloatParameter(3)); IlvChart chart = evt.getChart(); try { upperPt = IlvChartServletSupport.toChartArea(upperPt, new IlvServletRequestParameters(evt.getRequest()), chart); lowerPt = IlvChartServletSupport.toChartArea(lowerPt, new IlvServletRequestParameters(evt.getRequest()), chart); } catch (IlvParameterException e) { throw new ServletException(e.getMessage()); } IlvDoublePoints pts = new IlvDoublePoints(2); pts.add(lowerPt.x, lowerPt.y); pts.add(upperPt.x, upperPt.y); chart.toData(pts); ThresholdLines.get(evt.getChart(), 0) .setThresholds(new IlvDataInterval(Math.floor(pts.getY(0)), Math.floor(pts.getY(1)))); } Override public int getExecutionThread() { return IlvChartServerAction.SWING_EVENT_THREAD; } } // A ServerAction to toggle the threshold lines visibility. final class ToggleThresholdAction implements IlvChartServerAction { Override public void actionPerformed(IlvChartServerActionEvent evt) throws ServletException { StockDemoApp app = getApp(evt.getRequest()); app.setThreshold(evt.getIntParameter(0) == 1 ? true : false); } Override public int getExecutionThread() { return IlvChartServerAction.REQUEST_THREAD; } } // A ServerAction to set/unset a Logarithmic Price Axis. static final class ToggleLogScaleAction implements IlvChartServerAction { Override public void actionPerformed(IlvChartServerActionEvent evt) throws ServletException { if (evt.getIntParameter(0) == 1) evt.getChart().getYAxis(0).setTransformer(new ExponentAxisTransformer(.5)); else evt.getChart().getYAxis(0).setTransformer(null); } Override public int getExecutionThread() { return IlvChartServerAction.REQUEST_THREAD; } } // -------------------------------------------------------------------------- // IMapAttributes subclasses // -------------------------------------------------------------------------- /** * A IlvDefaultIMapAttributes subclass that generates map area tags for a * detailed renderer. */ static final class StockDemoIMapAttributes extends IlvDefaultIMapAttributes { private int ptidx; private int pos; private StockDemoApp app; public StockDemoIMapAttributes(StockDemoApp app, int pos, int ptIdx) { super("javascript:void(0)"); this.ptidx = ptIdx; this.pos = pos; this.app = app; } Override public String getExtraAttributes() { StringBuffer buffer = new StringBuffer("onMouseOver=\""); buffer.append("highlightPoint("); buffer.append(pos); buffer.append(","); buffer.append(app.getStockDataSource().getDate(ptidx).getTime()); buffer.append(","); buffer.append(app.getStockDataSource().getOpenDataSet().getYData(ptidx)); buffer.append(","); buffer.append(app.getStockDataSource().getHighDataSet().getYData(ptidx)); buffer.append(","); buffer.append(app.getStockDataSource().getLowDataSet().getYData(ptidx)); buffer.append(","); buffer.append(app.getStockDataSource().getCloseDataSet().getYData(ptidx)); buffer.append(");return true;\" onMouseOut=\""); buffer.append("unhighlightPoint();return true;\""); return buffer.toString(); } } /** * An IlvDefaultIMapAttributes subclass that generates map area tags for the * lower charts. */ static final class LowerIndicatorIMapAttributes extends IlvDefaultIMapAttributes { private String caption; private String date; private String value; public LowerIndicatorIMapAttributes(String date, String value, String caption) { super("javascript:void(0)"); this.caption = caption; this.value = value; this.date = date; } Override public String getExtraAttributes() { StringBuffer buffer = new StringBuffer("onmouseover=\"return tooltipMouseOver(event, '"); buffer.append("<b>Date:</b>"); buffer.append(date); buffer.append("<br/><b>Value:</b>"); buffer.append(value); buffer.append("','"); buffer.append(caption); buffer.append("');\" onmouseout=\"return tooltipMouseOut();\""); return buffer.toString(); } } // --------------------------------------------------------------------------- private static DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT); /** * Initializes a new <code>StockDemo</code>. */ public StockDemoSupport(ServletConfig config) { ((IlvJPEGEncoder) getImageEncoder(JPEG_IMAGE_FORMAT)).setJPEGQuality(1.0f); installServerActions(); } Override public void setServlet(HttpServlet servlet) { super.setServlet(servlet); setParameterValidationListener(new ChartStockParameterValidationListener(servlet.getServletContext())); } /** * Install server actions. */ private void installServerActions() { addServerAction(LOAD_QUOTES_ACTION, new LoadQuotesServerAction()); addServerAction(LOWER_INDICATOR_ACTION, new LowerIndicatorServerAction()); addServerAction(UPPER_INDICATOR_ACTION, new UpperIndicatorServerAction()); addServerAction("ZoomAction", new IlvZoomAction()); addServerAction("PanAction", new IlvPanAction()); addServerAction("SetOverviewRepAction", new SetOverviewRepAction()); addServerAction("SetThresholdAction", new SetThresholdAction()); addServerAction("ToggleThresholdAction", new ToggleThresholdAction()); addServerAction("ToggleLogScaleAction", new ToggleLogScaleAction()); } // --------------- IlvChartServletSupport overrided methods ----------------- /** * Allows you to prepare the chart content before the presentation is * generated. This method is invoked on the AWT event dispatch thread. This * default implementation does nothing. * * @param params * The parameters parsed from the HTTP request. * @param chart * The chart returned by {@link #getChart}. */ Override protected void prepareChart(IlvServletRequestParameters params, IlvChart chart) throws ServletException { super.prepareChart(params, chart); String[] actionParams = null; try { actionParams = params.getStringArray(ACTION_PARAM, ",()"); } catch (IlvParameterException e) { return; } String actionName = actionParams[0]; if (LOAD_QUOTES_ACTION.equals(actionName)) { // data have been loaded in the request thread by the LoadQuotes server // action int ns = actionParams.length - 5; String[] secsymbols = null; if (ns > 0) { secsymbols = new String[ns]; for (int i = 0; i < ns; ++i) secsymbols[i] = actionParams[5 + i]; } getApp(params.getServletRequest()).primaryDataLoaded(actionParams[1], secsymbols); } } Override protected IlvChart getChart(IlvServletRequestParameters params) throws javax.servlet.ServletException { String chartType = params.getString(CHART_PARAM, MAIN_CHART); IlvChart chart = null; StockDemoApp demo = getApp(params.getServletRequest()); if (demo == null) { String msg = IlvResourceUtil.getCurrentLocaleString(StockDemo.class, "notRetriveAppInstance"); throw new ServletException(msg); } if (chartType.equals(MAIN_CHART)) chart = demo.getMainChart(); else if (chartType.equals(LOWER1_CHART)) chart = demo.getLowerChart(0); else if (chartType.equals(LOWER2_CHART)) chart = demo.getLowerChart(1); if (chart == null) { String msg = IlvResourceUtil.getCurrentLocaleString(StockDemo.class, "unknownChartType"); throw new ServletException(msg); } return chart; } /** * Returns the requested visible window. The default implementation returns * the current visible window updated according to the xMin, xMax, yMin and * yMax optional request parameters. */ Override protected IlvDataWindow getRequestedVisibleWindow(IlvServletRequestParameters params, IlvChart chart) throws ServletException { IlvDataWindow dw = super.getRequestedVisibleWindow(params, chart); if (params.getString(REQUEST_PARAM, IMAGE_REQUEST).equals(IMAGE_REQUEST) && params.getString(CHART_PARAM, MAIN_CHART).equals(MAIN_CHART)) dw.yRange = StockUtil.getYDataRange(chart, 0, dw.xRange); return dw; } // Fix JV-4108 Override protected Map<String, Object> getAdditionalCapabilities(IlvChart chart, IlvServletRequestParameters params) { Map<String, Object> addCapabilities = new HashMap<String, Object>(); boolean resetForms = false; HttpServletRequest request = params.getServletRequest(); synchronized (request.getSession(false)) { if (StockDemo.getSessionAttribute(request, StockDemo.NEW_SESSION_ATT) != null) { resetForms = true; StockDemo.setSessionAttribute(request, StockDemo.NEW_SESSION_ATT, null); } } addCapabilities.put("resetForms", resetForms); if (params.getString(CHART_PARAM, MAIN_CHART).equals(MAIN_CHART)) { ThresholdLines threshold = ThresholdLines.get(chart, 0); StockDemoApp app; try { app = getApp(params.getServletRequest()); addCapabilities.put("detailedViewVisible", Boolean.valueOf(!app.isOverviewVisible())); addCapabilities.put("symbolFound", app.getStockDataSource().getSymbol()); if (threshold != null) { Rectangle r = threshold.getUpperAnnotation().getBounds(null).getBounds(); try { r = toRefComp(r, params, chart); } catch (IlvParameterException e) { // Logger.getLogger("thinstock").log(Level.SEVERE, // "An error occurred during additional capabilities generation"); // e.printStackTrace() ; throw new ServletException(e.getMessage()); } Map<String, Object> objMap = new HashMap<String, Object>(); objMap.put("left", r.x); objMap.put("top", r.y); objMap.put("width", r.width); objMap.put("height", r.height); addCapabilities.put("upperAnnoBounds", objMap); r = threshold.getLowerAnnotation().getBounds(null).getBounds(); try { r = toRefComp(r, params, chart); } catch (IlvParameterException e) { // Logger.getLogger("thinstock").log(Level.SEVERE, // "An error occurred during additional capabilities generation"); throw new ServletException(e.getMessage()); } objMap = new HashMap<String, Object>(); objMap.put("left", r.x); objMap.put("top", r.y); objMap.put("width", r.width); objMap.put("height", r.height); addCapabilities.put("lowerAnnoBounds", objMap); } } catch (ServletException e1) { // Logger.getLogger("thinstock").log(Level.SEVERE, "An error occurred // during additional capabilities generation"); e1.printStackTrace(); } } return addCapabilities; } /** * Allows you to add additional capabilities to a capability request when the * mime format is "text/html". This default implementation does nothing. * * @param chart * The chart returned by {@link #getChart getChart}. * @param params * The parameters parsed from the current HTTP request. * @param writer * The servlet print writer for writing additional text/html * capabilities. */ // protected void additionalTextCapabilities(IlvChart chart, // IlvServletRequestParameters params, PrintWriter out) // throws IOException, ServletException { // boolean resetForms = false; // HttpServletRequest request = params.getServletRequest(); // synchronized (request.getSession(false)) { // if (StockDemo.getSessionAttribute(request, StockDemo.NEW_SESSION_ATT) != // null) { // resetForms = true; // StockDemo.setSessionAttribute(request, StockDemo.NEW_SESSION_ATT, null); // } // } // out.println("var resetForms=" + resetForms); // if (params.getString(CHART_PARAM, MAIN_CHART).equals(MAIN_CHART)) { // ThresholdLines threshold = ThresholdLines.get(chart, 0); // StockDemoApp app = getApp(params.getServletRequest()); // out.println("var detailedViewVisible=" + !app.isOverviewVisible()); // out.println("var symbolFound='" + app.getStockDataSource().getSymbol() + // "';"); // if (threshold != null) { // Rectangle r = null; // try { // r = threshold.getUpperAnnotation().getBounds(null).getBounds(); // } catch (Exception e) { // e.printStackTrace() ; // } // try { // r = toRefComp(r, params, chart); // } catch (IlvParameterException e) { // throw new ServletException(e.getMessage()); // } // out.println("var upperAnnoBounds=new Object();"); // out.println("upperAnnoBounds.left=" + r.x); // out.println("upperAnnoBounds.top=" + r.y); // out.println("upperAnnoBounds.width=" + r.width); // out.println("upperAnnoBounds.height=" + r.height); // r = threshold.getLowerAnnotation().getBounds(null).getBounds(); // try { // r = toRefComp(r, params, chart); // } catch (IlvParameterException e) { // throw new ServletException(e.getMessage()); // } // out.println("var lowerAnnoBounds=new Object();"); // out.println("lowerAnnoBounds.left=" + r.x); // out.println("lowerAnnoBounds.top=" + r.y); // out.println("lowerAnnoBounds.width=" + r.width); // out.println("lowerAnnoBounds.height=" + r.height); // } // } // } /** * Allows you to add additional capabilities to a capability request when the * mime format is "application/octet-stream". This default implementation does * nothing. * * @param chart * The chart returned by {@link #getChart getChart}. * @param params * The parameters parsed from the current HTTP request. * @param dataStream * The servlet data output stream for writing additional binary * capabilities. */ // protected void additionalBinaryCapabilities(IlvChart chart, // IlvServletRequestParameters params, DataOutputStream dout) // throws IOException, ServletException { // boolean resetForms = false; // HttpServletRequest request = params.getServletRequest(); // synchronized (request.getSession(false)) { // if (StockDemo.getSessionAttribute(request, StockDemo.NEW_SESSION_ATT) != // null) { // resetForms = true; // StockDemo.setSessionAttribute(request, StockDemo.NEW_SESSION_ATT, null); // } // } // dout.writeBoolean(resetForms); // if (params.getString(CHART_PARAM, MAIN_CHART).equals(MAIN_CHART)) { // ThresholdLines threshold = ThresholdLines.get(chart, 0); // StockDemoApp app = getApp(params.getServletRequest()); // dout.writeBoolean(!app.isOverviewVisible()); // dout.writeUTF(app.getStockDataSource().getSymbol()); // dout.writeBoolean(params.getBoolean(StockDemo.NEW_SESSION_ATT, false)); // if (threshold != null) { // Rectangle r = threshold.getUpperAnnotation().getBounds(null).getBounds(); // try { // r = toRefComp(r, params, chart); // } catch (IlvParameterException e) { // throw new ServletException(e.getMessage()); // } // dout.writeInt(r.x); // dout.writeInt(r.y); // dout.writeInt(r.width); // dout.writeInt(r.height); // r = threshold.getLowerAnnotation().getBounds(null).getBounds(); // try { // r = toRefComp(r, params, chart); // } catch (IlvParameterException e) { // throw new ServletException(e.getMessage()); // } // dout.writeInt(r.x); // dout.writeInt(r.y); // dout.writeInt(r.width); // dout.writeInt(r.height); // } // } // } /** * Writes the image map area tags into the specified writer. This method is * invoked on the AWT event dispatch thread during the image map generation * process to generate the area tags. * * @param output * The output writer. * @param params * The parameters parsed from the request. * @param chart * The <code>IlvChart</code> for the specified request. */ Override protected void generateMapAreaTags(PrintWriter output, IlvServletRequestParameters params, IlvChart chart) throws IOException { super.generateMapAreaTags(output, params, chart); String chartName = params.getString(CHART_PARAM, null); if (chartName == null) return; Rectangle plotRect = chart.getChartArea().getPlotRect(); try { plotRect = toRefComp(plotRect, params, chart); } catch (IlvParameterException e) { } // Generate "background area" to forward events IlvIMapAttributes attr = null; if (chartName.equals(MAIN_CHART)) { attr = new IlvDefaultIMapAttributes("javascript:void(0)") { Override public String getExtraAttributes() { // Fix JV-5629 for FF return "onmousedown=\"mapMouseDown(event);return false;\" onmouseup=\"mapMouseUp(event);return false;\" onmousemove=\"mapMouseMove(event);return false;\" onmouseover=\"window.status=' ';return true;\""; } }; } if (attr != null) { IlvIMapArea area = new IlvIMapArea(plotRect, attr); output.println(area.getTag()); } } /** * Returns the <code>IlvIMapDefinition</code> used by the * <code>IlvImageMapBuilder</code> to generate the image map tags. */ Override protected IlvIMapDefinition getIMapDefinition(IlvServletRequestParameters params, IlvChart chart) { String chartName = params.getString(CHART_PARAM, null); if (chartName == null) return null; IlvIMapDefinition mapDef = null; StockDemoApp app; try { app = getApp(params.getServletRequest()); } catch (ServletException e) { return null; } if (chartName.equals(MAIN_CHART)) { IlvDataPoints pts = app.getDetailedDataSet().getDataInside(chart.getCoordinateSystem(0).getVisibleWindow(), 0, false); IlvDataSetPoint[] dspts = new IlvDataSetPoint[pts.size()]; IlvIMapAttributes[] attrs = new IlvIMapAttributes[pts.size()]; for (int i = 0; i < attrs.length; ++i) { attrs[i] = new StockDemoIMapAttributes(app, i, pts.getIndex(i)); dspts[i] = new IlvDataSetPoint(app.getDetailedDataSet(), pts.getIndex(i)); } pts.dispose(); try { mapDef = new IlvDefaultIMapDefinition(dspts, attrs); } catch (IllegalArgumentException e) { String msg = IlvResourceUtil.getServerLocaleString(StockDemo.class, "notCreateMapDefinition"); System.out.println(msg + e.getMessage()); } } else { int chartIdx = chartName.equals(LOWER1_CHART) ? 0 : 1; IlvDataPoints pts = app.getLowerIndicatorDataSet(chartIdx) .getDataInside(chart.getCoordinateSystem(0).getVisibleWindow(), 0, false); if (pts != null) { IlvDataSetPoint[] dspts = new IlvDataSetPoint[pts.size()]; IlvIMapAttributes[] attrs = new IlvIMapAttributes[pts.size()]; for (int i = 0; i < attrs.length; ++i) { String date = dateFormat.format(app.getStockDataSource().getDate(pts.getIndex(i))); String label = chart.getYScale(0) .computeLabel(app.getLowerIndicatorDataSet(chartIdx).getYData(pts.getIndex(i))); attrs[i] = new LowerIndicatorIMapAttributes(date, label, app.getLowerIndicatorName(chartIdx)); dspts[i] = new IlvDataSetPoint(app.getLowerIndicatorDataSet(chartIdx), pts.getIndex(i)); } pts.dispose(); try { mapDef = new IlvDefaultIMapDefinition(dspts, attrs); } catch (IllegalArgumentException e) { String msg = IlvResourceUtil.getServerLocaleString(StockDemo.class, "notCreateMapDefinition"); System.out.println(msg + e.getMessage()); } } } return mapDef; } // -------------------------------------------------------------------------- private StockDemoApp getApp(HttpServletRequest request) throws ServletException { HttpSession session = request.getSession(); if (session != null) { StockDemoApp app = null; synchronized (session) { app = (StockDemoApp) StockDemo.getSessionAttribute(request, StockDemo.APP_SESSION_KEY); if (app == null) { app = ((StockDemo) getServlet()).createApp(); StockDemo.setSessionAttribute(request, StockDemo.APP_SESSION_KEY, app); } } if (app != null) return app; } String msg = IlvResourceUtil.getCurrentLocaleString(StockDemo.class, "notRetrieveAppFromSession"); throw new ServletException(msg); } } class FacesStockDemoSupport extends StockDemoSupport { public FacesStockDemoSupport(ServletConfig conf) { super(conf); } Override protected void prepareChart(IlvServletRequestParameters params, IlvChart chart) throws ServletException { } } /** * A simple application that displays stock information. The sample loads quotes * from the Yahoo finance Web pages and displays them in two distinct charts on * which you can perform interactions. The displayed information is the stock * prices and the exchanged volume. The data is retrieved by sending a formatted * <i>cgi query </i> to the Yahoo Web site, and the result is decoded using a * custom <code>IlvDataReader</code> object. This reader (an instance of * <code>CSVDataReader</code>) extracts the data from the input stream and * initializes the data source with the corresponding data sets. */ public class StockDemo extends IlvFacesChartServlet { public static final String APP_SESSION_KEY = "StockDemoApp"; public static final String NEW_SESSION_ATT = "thinstock_New_Session"; // --------------- Support for multiple browser pages (tabs) ---------------- /** * This method allows support for multiple browser pages to this application * as it retrieves the session attributes using a page identifier that is * unique to the page accessing this application. Different pages will have * different identifiers. * * @param request * The request associated with the session * @param attributeKey * The attribute key to access the attribute value * @return The attribute value, if any. */ public static Object getSessionAttribute(HttpServletRequest request, String attributeKey) { // Since the 'request' is already known, class IlvServletPageIdUtil // is used. Otherwise, class IlvFacesPageIdUtil is able to retrieve the // session directly from the FacesContext return IlvServletPageIdUtil.getSessionAttributeWithPageId(request, attributeKey); } /** * This method allows support for multiple browser pages to this application * as it stores the session attributes using a page identifier that is unique * to the page accessing this application. Different pages will have different * identifiers. * * If the given value is null, the attribute is removed from the session. * * @param request * The request associated with the session * @param attributeKey * The attribute key to access the attribute value * @param attributeValue * The attribute value to be stored in the session, or */ static void setSessionAttribute(HttpServletRequest request, String attributeKey, Object attributeValue) { // Since the 'request' is already known, class IlvServletPageIdUtil // is used. Otherwise, class IlvFacesPageIdUtil is able to retrieve the // session directly from the FacesContext IlvServletPageIdUtil.setSessionAttributeWithPageId(request, attributeKey, attributeValue); } /** * Creates an <code>IlvChartServletSupport</code> instance. This method is * called by the {link #getServletSupport} method when the support has not * been created. This method should be overridden to provide a default * implementation. */ Override protected IlvChartServletSupport createServletSupport() { return new FacesStockDemoSupport(getServletConfig()); } /** * Prepares a session for the client. This method is called at every request * before any other method to allow the user to prepare a session for his * servlet. The actual implementation is empty, but if your servlet needs to * create a session you can overwrite this method to do it. * * @param request * The current HTTP request. * @exception ServletException * If the request for the GET could not be handled. */ Override protected void prepareSession(HttpServletRequest request) throws ServletException { HttpSession session = request.getSession(true); synchronized (session) { StockDemoApp demo = (StockDemoApp) StockDemo.getSessionAttribute(request, APP_SESSION_KEY); if (null == demo) { // new page in session demo = createApp(); StockDemo.setSessionAttribute(request, APP_SESSION_KEY, demo); StockDemo.setSessionAttribute(request, NEW_SESSION_ATT, new Object()); } } } /** * Create a new <code>StockDemoApp</code> instace. */ protected StockDemoApp createApp() { return new FacesStockDemoApp(getServletConfig()); } Override protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { // System.out.println("---> " + arg0.getQueryString()); HttpSession session = arg0.getSession(true); synchronized (session) { super.service(arg0, arg1); } } }