001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.core.servlet;
028:
029: import java.io.PrintWriter;
030: import java.util.Iterator;
031: import java.util.List;
032:
033: import javax.servlet.http.HttpServletRequest;
034:
035: import org.cougaar.core.component.ServiceBroker;
036:
037: /**
038: * Base class for serlvets that have multiple frames with an
039: * agent selection list.
040: */
041: public abstract class ServletMultiFrameset extends ServletFrameset {
042:
043: // values for the FRAME url parameter
044: private static final String INFO_FRAME = "infoFrame";
045: private static final String SELECT_FRAME = "selectFrame";
046: private static final String RELOAD_FRAME = "reloadFrame";
047:
048: private static final String SELECT_FORM = "selectForm";
049:
050: // url parameter for the selected data
051: private static final String INFO_BASE = "base";
052: private static final String SELECT_NAME = "name";
053:
054: public ServletMultiFrameset(ServiceBroker sb) {
055: super (sb);
056: }
057:
058: /**
059: * Get the contents for the second drop-down list.
060: * <p>
061: * The only other information of interest is the local agent's
062: * name, which is available from the <code>getNodeID()</code>
063: * method.
064: */
065: protected abstract List getDataSelectionList(
066: HttpServletRequest request);
067:
068: /**
069: * Print the data for the dataFrame.
070: * <p>
071: * @param selectName the selected name from the secondary drop-down
072: */
073: protected abstract void printPage(String selectName,
074: HttpServletRequest request, PrintWriter out);
075:
076: //
077: // The rest is fine for most subclasses
078: //
079:
080: public final void printPage(HttpServletRequest request,
081: PrintWriter out) {
082: String selectName = request.getParameter(SELECT_NAME);
083: printPage(selectName, request, out);
084: }
085:
086: protected final String getMiddleFrame() {
087: return INFO_FRAME;
088: }
089:
090: protected final void writeJavascript(PrintWriter out) {
091: out
092: .print("<script language=\"JavaScript\">\n" + "<!--\n"
093: + "function mySubmit() {\n"
094: + " // make sure an agent was selected\n"
095: + " var topObj = top."
096: + AGENT_FRAME
097: + ".document.agent.name;\n"
098: + " var encAgent = topObj.value;\n"
099: + " if (encAgent.charAt(0) == '.') {\n"
100: + " alert(\"Please select an agent name\")\n"
101: + " return false;\n"
102: + " }\n"
103: + " // see if the top name matches the middle frames\n"
104: + " var baseObj = document."
105: + BOTTOM_FORM
106: + "."
107: + INFO_BASE
108: + ";\n"
109: + " var baseAgent = baseObj.value;\n"
110: + " if (baseAgent != null &&\n"
111: + " baseAgent != encAgent) {\n"
112: + " // reset the info frame to match the top agent selection\n"
113: + " document."
114: + BOTTOM_FORM
115: + "."
116: + INFO_BASE
117: + ".value=encAgent;\n"
118: + " document."
119: + BOTTOM_FORM
120: + "."
121: + FRAME
122: + ".value=\""
123: + INFO_FRAME
124: + "\";\n"
125: + " document."
126: + BOTTOM_FORM
127: + ".target=\""
128: + INFO_FRAME
129: + "\";\n"
130: + " document."
131: + BOTTOM_FORM
132: + ".action=\"/$\"+encAgent+\""
133: + getPath()
134: + "\";\n"
135: + " return true;\n"
136: + " }\n"
137: + " document."
138: + BOTTOM_FORM
139: + "."
140: + FRAME
141: + ".value=\""
142: + RELOAD_FRAME
143: + "\";\n"
144: + " document."
145: + BOTTOM_FORM
146: + ".target=\""
147: + DATA_FRAME
148: + "\"\n"
149: + " document."
150: + BOTTOM_FORM
151: + ".action=\"/$\"+encAgent+\""
152: + getPath()
153: + "\"\n"
154: + " return true\n"
155: + "}\n" + "// -->\n" + "</script>\n");
156: }
157:
158: /**
159: * We save the info frame's view to avoid reloading both the
160: * selection list and data frame if the user hasn't changed
161: * the agent selection.
162: */
163: protected final void printAdditionalBottomFields(PrintWriter out) {
164: out.print("<input type=hidden name=\"" + INFO_BASE
165: + "\" value=\"" + getNodeID() + "\">\n");
166: }
167:
168: private void printSelectFrame(HttpServletRequest request,
169: PrintWriter out) {
170:
171: out.print("<html><body>\n" + "<body>\n" + "<form name=\""
172: + SELECT_FORM + "\" onSubmit=\";\">\n" + getNodeID()
173: + ": " + "<select name=\"" + SELECT_NAME + "\">\n");
174:
175: // get the selection list
176: List l = getDataSelectionList(request);
177:
178: int n = (l == null ? 0 : l.size());
179: if (n > 0) {
180: Iterator iter = l.iterator();
181: for (int i = 0; i < n; i++) {
182: String si = (String) iter.next();
183: out.print(" <option>" + si + "</option>\n");
184: }
185: }
186:
187: out.print("</select> \n" + "</form></body></html>\n");
188: }
189:
190: /**
191: * Generate a temporary page that redirects to the data page
192: * with the selected name.
193: * <p>
194: * This page exists to work around some issues in javascript
195: * security and page generation ordering.
196: * <p>
197: * Say that the top frame was generated on host A. We select an
198: * agent at the top, which loads data based upon an agent on host
199: * B. The secondary selection is generated on host B. The data
200: * page depends upon the selected agent name. The bottom frame
201: * can't see the selection, since it's on a different host and
202: * javascript security denies this access, so the data frame itself
203: * must grab the selected name. Furthermore, the data frame
204: * contents must be generated before this selection lookup, since
205: * the server must generate the data contents and not the client's
206: * browser. For this reason we need an intermediate page to grab
207: * the selected name and force the data page generation.
208: * <p>
209: * This "reload" frame is a temporary page that's briefly displayed
210: * before the data frame's contents. It grabs the selection and
211: * reloads its frame with the data page.
212: * <p>
213: * The reload page is not used when periodically refreshing the
214: * data page, so the cost is minimal.
215: * <p>
216: * This basic technique should be used if additional agent-local
217: * selection options are added in the future.
218: */
219: private void printReloadFrame(HttpServletRequest request,
220: PrintWriter out) {
221: String refresh = request.getParameter(REFRESH_FIELD_PARAM);
222: if (refresh == null || refresh.length() == 0) {
223: refresh = "0";
224: }
225: out.print("<html><body>" + "<script language=\"JavaScript\">\n"
226: + "<!--\n" + "var selectObj = top."
227: + INFO_FRAME
228: + "."
229: + SELECT_FRAME
230: + ".document."
231: + SELECT_FORM
232: + ".name;\n"
233: + "var selectName = selectObj.value;\n"
234: + "if (selectName == null || selectName == '') {\n"
235: + " document.writeln(\n"
236: + " \"Select a name above and click the"
237: + "Refresh button below.\");\n"
238: + "} else {\n"
239: + " var newLoc = \""
240: + request.getRequestURI()
241: + "?"
242: + FRAME
243: + "="
244: + DATA_FRAME
245: + "&"
246: + REFRESH_FIELD_PARAM
247: + "="
248: + refresh
249: + "&"
250: + SELECT_NAME
251: + "=\"+selectName;\n"
252: + " location.href=newLoc;\n"
253: + "}\n" + "-->\n" + "</script>\n" + "</body></html>\n");
254: }
255:
256: /**
257: * The info frameset contains the selection list and the data
258: * frame.
259: * <p>
260: * This separate frameset allows the bottom frame to reload both
261: * the selection frame and data frame when the user selects a
262: * different agent.
263: */
264: private void printInfoFrame(HttpServletRequest request,
265: PrintWriter out) {
266: // Header
267: out.print("<html><head><title>");
268: out.print(getTitle());
269: out.print("</title></head>");
270:
271: // Frameset
272: out.print("<frameset rows=\"");
273: out.print(topPercentage());
274: out.print("%,");
275: out.print(100 - topPercentage());
276: out.print("%\">\n");
277:
278: // show select frame
279: out.print("<frame src=\"");
280: out.print(request.getRequestURI());
281: out.print("?");
282: out.print(FRAME);
283: out.print("=");
284: out.print(SELECT_FRAME);
285: out.print("\" name=\"");
286: out.print(SELECT_FRAME);
287: out.print("\">\n");
288:
289: // show data frame
290: out.print("<frame src=\"");
291: out.print(request.getRequestURI());
292: out.print("?");
293: out.print(FRAME);
294: out.print("=");
295: out.print(RELOAD_FRAME);
296: out.print("\" name=\"");
297: out.print(DATA_FRAME);
298: out.print("\">\n");
299:
300: // End frameset
301: out.print("</frameset>\n");
302:
303: // Frameless browser hack
304: out.print("<noframes>Please enable frame support</noframes>");
305:
306: // End
307: out.print("</html>\n");
308: }
309:
310: protected final void printFrame(String frame,
311: HttpServletRequest request, PrintWriter out) {
312: if (SELECT_FRAME.equals(frame)) {
313: printSelectFrame(request, out);
314: } else if (INFO_FRAME.equals(frame)) {
315: printInfoFrame(request, out);
316: } else if (RELOAD_FRAME.equals(frame)) {
317: printReloadFrame(request, out);
318: } else {
319: super.printFrame(frame, request, out);
320: }
321: }
322: }
|