001: /*
002: *
003: * Copyright (c) 2007, Sun Microsystems, Inc.
004: *
005: * All rights reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * * Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * * Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: * * Neither the name of Sun Microsystems nor the names of its contributors
017: * may be used to endorse or promote products derived from this software
018: * without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
024: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032: package example.http;
033:
034: import java.io.DataInputStream;
035: import java.io.IOException;
036: import java.io.InputStream;
037: import java.io.OutputStream;
038:
039: import java.lang.String;
040:
041: import java.util.Date;
042: import java.util.Vector;
043:
044: import javax.microedition.io.*;
045: import javax.microedition.lcdui.*;
046: import javax.microedition.midlet.*;
047:
048: /**
049: * An example MIDlet to fetch a page using an HttpConnection.
050: * Refer to the startApp, pauseApp, and destroyApp
051: * methods so see how it handles each requested transition.
052: */
053: public class HttpView extends MIDlet implements CommandListener,
054: Runnable {
055: /** user interface command for indicating Exit request. */
056: Command exitCommand = new Command("Exit", Command.EXIT, 2);
057:
058: /** user interface command for indicating a page reload request. */
059: Command reloadCommand = new Command("Reload", Command.SCREEN, 1);
060:
061: /** user interface command to request an HTTP HEAD transaction. */
062: Command headCommand = new Command("Head", Command.SCREEN, 1);
063:
064: /** user interface command to request an HTTP POST transaction. */
065: Command postCommand = new Command("Post", Command.SCREEN, 1);
066:
067: /** user interface command to request an HTTP GET transaction. */
068: Command getCommand = new Command("Get", Command.SCREEN, 1);
069:
070: /** user interface command to cancel the current screen. */
071: Command cancelCommand = new Command("Cancel", Command.SCREEN, 1);
072:
073: /** user interface command to return back to previous screen. */
074: Command backCommand = new Command("Back", Command.BACK, 1);
075:
076: /** user interface command to request current HTTP headers. */
077: Command headersCommand = new Command("Headers", Command.SCREEN, 1);
078:
079: /** user interface command to display current HTTP request headers. */
080: Command requestsCommand = new Command("Requests", Command.SCREEN, 1);
081:
082: /** user interface command to display errors from current request. */
083: Command errorsCommand = new Command("Errors", Command.SCREEN, 1);
084:
085: /** user interface command to enter a new URL */
086: Command newURLCommand = new Command("New URL", Command.SCREEN, 10);
087:
088: /** user interface command to remove the current URL */
089: Command removeURLCommand = new Command("Remove", Command.SCREEN, 11);
090:
091: /** user interface command to confirm current screen. */
092: Command okCommand = new Command("Ok", Command.SCREEN, 1);
093:
094: /** user interface command to display help message. */
095: Command helpCommand = new Command("Help", Command.HELP, 1);
096:
097: /** user interface component containing a list of URLs */
098: List urlList;
099:
100: /** array of current URLs */
101: Vector urls;
102:
103: /** user interface alert component. */
104: Alert alert;
105:
106: /** user interface text box for the contents of the fetched URL. */
107: TextBox content;
108:
109: /** current display. */
110: Display display;
111:
112: /** instance of a thread for asynchronous networking and user interface. */
113: Thread thread;
114:
115: /** current requested url. */
116: String url;
117:
118: /** current HTTP request type - GET, HEAD, or POST */
119: Command requestCommand;
120:
121: /** user interface form to hold progress results. */
122: Form progressForm;
123:
124: /** user interface progress indicator. */
125: Gauge progressGauge;
126:
127: /** user interface screen for HTTP headers */
128: Form headerForm;
129:
130: /** form to display request including parsing */
131: Form requestForm;
132:
133: /** form to display exceptions */
134: Form errorsForm;
135:
136: /** data entry text box for inputting URLs */
137: TextBox urlbox;
138:
139: /** initialize the MIDlet with the current display object. */
140: public HttpView() {
141: display = Display.getDisplay(this );
142: setupList();
143: alert = new Alert("Warning");
144: alert.setTimeout(2000);
145:
146: headerForm = new Form("Headers");
147: headerForm.addCommand(backCommand);
148: headerForm.addCommand(requestsCommand);
149: headerForm.setCommandListener(this );
150:
151: requestForm = new Form("Request headers");
152: requestForm.addCommand(backCommand);
153: requestForm.addCommand(errorsCommand);
154: requestForm.setCommandListener(this );
155:
156: progressForm = new Form("Progress");
157: progressForm.addCommand(cancelCommand);
158: progressForm.setCommandListener(this );
159:
160: progressGauge = new javax.microedition.lcdui.Gauge(url, false,
161: 9, 0);
162: progressForm.append(progressGauge);
163:
164: errorsForm = new Form("Errors");
165: errorsForm.addCommand(backCommand);
166: errorsForm.addCommand(headersCommand);
167: errorsForm.setCommandListener(this );
168:
169: urlbox = new TextBox("Enter Url", "http://", 400, TextField.URL);
170: urlbox.addCommand(okCommand);
171: urlbox.setCommandListener(this );
172: }
173:
174: /**
175: * Start creates the thread to do the timing.
176: * It should return immediately to keep the dispatcher
177: * from hanging.
178: */
179: public void startApp() {
180: /* Bytes read from the URL update connection. */
181: int count;
182:
183: /* Check for inbound async connection for sample Finger port. */
184: String[] connections = PushRegistry.listConnections(true);
185:
186: /* HttpView was started to handle inbound request. */
187: String pushProperty = getAppProperty("MIDlet-Push-1");
188:
189: if ((connections != null) && (connections.length > 0)) {
190: String newurl = "Pushed URL Placeholder";
191:
192: /* Test basic get registry information interfaces. */
193: try {
194: String midlet = PushRegistry.getMIDlet(connections[0]);
195: String filter = PushRegistry.getFilter(connections[0]);
196: } catch (Exception e) {
197: e.printStackTrace();
198: }
199:
200: /* Check for socket or datagram connection. */
201: if (connections[0].startsWith("socket://")) {
202: try {
203: /* Simple test assumes a server socket connection. */
204: ServerSocketConnection scn = (ServerSocketConnection) Connector
205: .open(connections[0]);
206: SocketConnection sc = (SocketConnection) scn
207: .acceptAndOpen();
208:
209: /* Read one line of text as a new URL to add to the list. */
210: DataInputStream dis = sc.openDataInputStream();
211: byte[] buf = new byte[256];
212: int endofline = 0;
213: count = dis.read(buf);
214:
215: for (int i = 0; i < count; i++) {
216: if (buf[i] == '\n') {
217: endofline = i;
218:
219: break;
220: }
221: }
222:
223: newurl = new String(buf, 0, endofline);
224:
225: dis.close();
226:
227: sc.close();
228: scn.close();
229: } catch (IOException e) {
230: e.printStackTrace();
231: }
232:
233: /*
234: * After successfully receiving a socket posted URL
235: * register a datagram connection, too.
236: */
237: try {
238: PushRegistry.registerConnection(
239: "datagram://:40080",
240: "example.http.HttpView", "129.148.*.*");
241: } catch (ClassNotFoundException e) {
242: e.printStackTrace();
243: } catch (IllegalArgumentException e) {
244: e.printStackTrace();
245: } catch (ConnectionNotFoundException e) {
246: e.printStackTrace();
247: } catch (IOException e) {
248: e.printStackTrace();
249: }
250: } else if (connections[0].startsWith("datagram://")) {
251: /* Must be a datagram connection. */
252: try {
253: UDPDatagramConnection udc = (UDPDatagramConnection) Connector
254: .open(connections[0]);
255: Datagram dg = udc.newDatagram(256);
256:
257: udc.receive(dg);
258: udc.close();
259:
260: byte[] buf = dg.getData();
261:
262: int endofline = 0;
263: count = buf.length;
264:
265: for (int i = 0; i < count; i++) {
266: if (buf[i] == '\n') {
267: endofline = i;
268:
269: break;
270: }
271: }
272:
273: newurl = new String(buf, 0, endofline);
274:
275: /* Unregister the datagram connection. */
276: PushRegistry
277: .unregisterConnection("datagram://:40080");
278: } catch (SecurityException e) {
279: e.printStackTrace();
280: } catch (IOException e) {
281: e.printStackTrace();
282: }
283: } else {
284: //unknown connection type
285: }
286:
287: urlList.append(newurl, null);
288: urls.addElement(newurl);
289: } else {
290: connections = PushRegistry.listConnections(false);
291:
292: /*
293: * If the MIDlet was started manually, set an alarm
294: * to restart automatically int one minute.
295: */
296: try {
297: Date alarm = new Date();
298: PushRegistry.registerAlarm("example.http.HttpView",
299: alarm.getTime() + 60000);
300: } catch (ClassNotFoundException e) {
301: e.printStackTrace();
302: } catch (ConnectionNotFoundException e) {
303: e.printStackTrace();
304: }
305: }
306:
307: if (urlList.size() > 0) {
308: display.setCurrent(urlList);
309: } else {
310: alert.setString("No url's configured.");
311: display.setCurrent(alert, urlList);
312: }
313: }
314:
315: /**
316: * Pause signals the thread to stop by clearing the thread field.
317: * If stopped before done with the iterations it will
318: * be restarted from scratch later.
319: */
320: public void pauseApp() {
321: }
322:
323: /**
324: * Destroy must cleanup everything. The thread is signaled
325: * to stop and no result is produced.
326: * @param unconditional true if a forced shutdown was requested
327: */
328: public void destroyApp(boolean unconditional) {
329: thread = null;
330: }
331:
332: /**
333: * Check the attributes in the descriptor that identify
334: * url's and titles and initialize the lists of urls
335: * and urlList.
336: * <P>
337: * The attributes are named "ViewTitle-n" and "ViewURL-n".
338: * The value "n" must start at "1" and increment by 1.
339: */
340: void setupList() {
341: urls = new Vector();
342: urlList = new List("URLs", List.IMPLICIT);
343: urlList.addCommand(headCommand);
344: urlList.addCommand(getCommand);
345: urlList.addCommand(postCommand);
346: urlList.addCommand(exitCommand);
347: urlList.addCommand(newURLCommand);
348: urlList.addCommand(removeURLCommand);
349: urlList.addCommand(helpCommand);
350: urlList.setCommandListener(this );
351:
352: for (int n = 1; n < 100; n++) {
353: String nthURL = "ViewURL-" + n;
354: String url = getAppProperty(nthURL);
355:
356: if ((url == null) || (url.length() == 0)) {
357: break;
358: }
359:
360: String nthTitle = "ViewTitle-" + n;
361: String title = getAppProperty(nthTitle);
362:
363: if ((title == null) || (title.length() == 0)) {
364: title = url;
365: }
366:
367: urls.addElement(url);
368: urlList.append(title, null);
369: }
370:
371: urls.addElement("http://jse.east/Telco/HttpTest.txt");
372: // urls.addElement(
373: // "http://dhcp-70-219:8080/examples/servlet/httpdbexport");
374: // urls.addElement(
375: // "http://jse.east.sun.com/~kfinn/proxy.jar");
376: // urls.addElement(
377: // "http://dhcp-70-219:8080/examples/servlet/HelloWorldKerry");
378: urlList.append("Test URL", null);
379: }
380:
381: /**
382: * Respond to commands, including exit
383: * @param c user interface command requested
384: * @param s screen object initiating the request
385: */
386: public void commandAction(Command c, Displayable s) {
387: try {
388: if (c == exitCommand) {
389: destroyApp(false);
390: notifyDestroyed();
391: } else if ((c == headCommand) || (c == getCommand)
392: || (c == postCommand) || (c == List.SELECT_COMMAND)) {
393: if (c == List.SELECT_COMMAND) {
394: c = getCommand;
395: }
396:
397: requestCommand = c;
398:
399: // Display the progress screen and
400: // start the thread to read the url
401: int i = urlList.getSelectedIndex();
402:
403: url = (String) urls.elementAt(i);
404: genProgressForm("Progress", url);
405: display.setCurrent(progressForm);
406: thread = new Thread(this );
407: thread.start();
408: } else if (c == headersCommand) {
409: display.setCurrent(headerForm);
410: } else if (c == requestsCommand) {
411: display.setCurrent(requestForm);
412: } else if (c == errorsCommand) {
413: display.setCurrent(errorsForm);
414: } else if (c == backCommand) {
415: if ((s == headerForm) || (s == requestForm)
416: || (s == errorsForm)) {
417: display.setCurrent(content);
418: } else {
419: // Display the list of urls.
420: display.setCurrent(urlList);
421: }
422: } else if (c == cancelCommand) {
423: // Signal thread to stop and put an alert.
424: thread = null;
425: alert.setString("Loading cancelled.");
426: display.setCurrent(alert, urlList);
427: } else if (c == newURLCommand) {
428: display.setCurrent(urlbox);
429: } else if (c == removeURLCommand) {
430: int i = urlList.getSelectedIndex();
431: urlList.delete(i);
432: urls.removeElementAt(i);
433: } else if ((c == okCommand) && (s == urlbox)) {
434: String newurl = urlbox.getString();
435: urlList.append(newurl, null);
436: urls.addElement(newurl);
437: display.setCurrent(urlList);
438: } else if (c == helpCommand) {
439: String helpString = "Use Head, Get or Post to download a URL.\n\n"
440: + "Use 'New URL' to enter a new URL.";
441: Alert alert = new Alert(null, helpString, null, null);
442: alert.setTimeout(Alert.FOREVER);
443: display.setCurrent(alert);
444: }
445: } catch (Exception ex) {
446: ex.printStackTrace();
447: }
448: }
449:
450: /**
451: * Fetch the specified url in a separate thread and update the
452: * progress bar as it goes.
453: * If the user cancels the fetch, the thread be changed from this thread.
454: * If this happens no further updates should be made to the
455: * displayable forms. Those shared objects may be re-used
456: * by the next fetch.
457: */
458: public void run() {
459: long start = 0;
460: long end = 0;
461: int bytecode_count_start = 0;
462: int bytecode_count_end = 0;
463:
464: Thread mythread = Thread.currentThread();
465: String method = HttpConnection.GET;
466:
467: if (requestCommand == headCommand) {
468: method = HttpConnection.HEAD;
469: } else if (requestCommand == postCommand) {
470: method = HttpConnection.POST;
471: }
472:
473: if (content == null) {
474: content = new TextBox("Content", "", 4096, 0);
475: content.addCommand(backCommand);
476: content.addCommand(headersCommand);
477: content.setCommandListener(this );
478: }
479:
480: // Clear the buffers and forms so then can be displayed
481: // even if an exception terminates reading early.
482: content.setTitle("Body len = 0");
483: content.setString("");
484: genErrorsForm("Errors", null);
485: clearForm(requestForm);
486: clearForm(headerForm);
487: progressGauge.setValue(1);
488:
489: HttpConnection conn = null;
490: InputStream input = null;
491: OutputStream output = null;
492: StringBuffer b;
493: String string = null;
494:
495: try {
496: long len = 0;
497:
498: conn = (HttpConnection) Connector.open(url);
499: conn.setRequestMethod(method);
500: setConfig(conn);
501:
502: if (mythread != thread) {
503: return;
504: }
505:
506: progressGauge.setValue(2);
507:
508: for (int hops = 0; hops < 2; hops++) {
509: // Send data to the server (if necessary). Then, see if
510: // we're redirected. If so, hop to the new URL
511: // specified by the server.
512: //
513: // You can choose how many hops to make by changing the
514: // exit condition of this loop.
515: //
516: // To see an example of this, try the link
517: // "http://www.sun.com/products" link, which will
518: // redirect you to a link with a session ID.
519: if (method == HttpConnection.POST) {
520: output = conn.openOutputStream();
521:
522: if (mythread != thread) {
523: return;
524: }
525:
526: output.write("hello midlet world".getBytes());
527: output.close();
528: output = null;
529: }
530:
531: HttpConnection newConn = handleRedirects(conn);
532:
533: if (conn != newConn) {
534: conn = newConn;
535: } else {
536: break;
537: }
538: }
539:
540: genRequestForm(conn);
541:
542: input = conn.openInputStream();
543:
544: if (mythread != thread) {
545: return;
546: }
547:
548: content.setTitle(conn.getResponseMessage() + " ("
549: + conn.getResponseCode() + ")");
550: genHeaderForm(conn);
551: progressGauge.setValue(5);
552:
553: if (mythread != thread) {
554: return;
555: }
556:
557: // Download the content of the URL. We limit our download
558: // to 4096 bytes (content.getMaxSize()), as most small
559: // devices may not be able to handler larger size.
560: //
561: // A "real program", of course, needs to handle large
562: // downloads intelligently. If possible, it should work
563: // with the server to limit downloads to small sizes. If
564: // this is not possible, it should download only part of
565: // the data and allow the user to specify which part to
566: // download.
567: len = conn.getLength();
568: b = new StringBuffer((len >= 0) ? (int) len : 1000);
569:
570: int max = content.getMaxSize();
571:
572: if (len != -1) {
573: // Read content-Length bytes, or until max is reached.
574: int ch = 0;
575:
576: for (int i = 0; i < len; i++) {
577: if ((ch = input.read()) != -1) {
578: if (ch <= ' ') {
579: ch = ' ';
580: }
581:
582: b.append((char) ch);
583:
584: if (b.length() >= max) {
585: break;
586: }
587: }
588: }
589: } else {
590: // Read til the connection is closed, or til max is reached.
591: // (Typical HTTP/1.0 script generated output)
592: int ch = 0;
593: len = 0;
594:
595: while ((ch = input.read()) != -1) {
596: if (ch <= ' ') {
597: ch = ' ';
598: }
599:
600: b.append((char) ch);
601:
602: if (b.length() >= max) {
603: break;
604: }
605: }
606: }
607:
608: string = b.toString();
609:
610: if (mythread != thread) {
611: return;
612: }
613:
614: progressGauge.setValue(8);
615:
616: content.setTitle("Body len = " + b.length());
617:
618: if (b.length() > 0) {
619: content.setString(string);
620: } else {
621: content.setString("no data");
622: }
623:
624: display.setCurrent(content);
625: progressGauge.setValue(9);
626: } catch (OutOfMemoryError mem) {
627: // Mmm, we still run out of memory, even after setting
628: // max download to 4096 bytes. Tell user about the error.
629: //
630: // A "real program" should decide on the max download
631: // size depending on available heap space, or perhaps
632: // allow the user to set the max size
633: b = null;
634: content = null; // free memory to print error
635:
636: mem.printStackTrace();
637:
638: if (mythread != thread) {
639: genErrorsForm("Memory", mem);
640: display.setCurrent(errorsForm);
641: }
642: } catch (Exception ex) {
643: ex.printStackTrace();
644:
645: genErrorsForm("Errors", ex);
646: display.setCurrent(errorsForm);
647: } finally {
648: cleanUp(conn, input, output);
649:
650: if (mythread == thread) {
651: progressGauge.setValue(10);
652: }
653: }
654: }
655:
656: /**
657: * Clean up all objects used by the HttpConnection. We must
658: * close the InputStream, OutputStream objects, as well as the
659: * HttpConnection object, to reclaim system resources. Otherwise,
660: * we may not be able to make new connections on some platforms.
661: *
662: * @param conn the HttpConnection
663: * @param input the InputStream of the HttpConnection, may be null
664: * if it's not yet opened.
665: * @param output the OutputStream the HttpConnection, may be null
666: * if it's not yet opened.
667: */
668: void cleanUp(HttpConnection conn, InputStream input,
669: OutputStream output) {
670: Thread mythread = Thread.currentThread();
671:
672: try {
673: if (input != null) {
674: input.close();
675: }
676: } catch (IOException e) {
677: if (mythread == thread) {
678: genErrorsForm("InputStream close error", e);
679: }
680: }
681:
682: try {
683: if (output != null) {
684: output.close();
685: }
686: } catch (IOException e) {
687: if (mythread == thread) {
688: genErrorsForm("OutStream close error", e);
689: }
690: }
691:
692: try {
693: if (conn != null) {
694: conn.close();
695: }
696: } catch (IOException e) {
697: if (mythread == thread) {
698: genErrorsForm("HttpConnection close error", e);
699: }
700: }
701: }
702:
703: /**
704: * Check for redirect response codes and handle
705: * the redirect by getting the new location and
706: * opening a new connection to it. The original
707: * connection is closed.
708: * The process repeats until there are no more redirects.
709: * @param c the initial HttpConnection
710: * @return the final HttpConnection
711: */
712: HttpConnection handleRedirects(HttpConnection c) throws IOException {
713: while (true) {
714: int code = c.getResponseCode();
715:
716: switch (code) {
717: case HttpConnection.HTTP_TEMP_REDIRECT:
718: case HttpConnection.HTTP_MOVED_TEMP:
719: case HttpConnection.HTTP_MOVED_PERM:
720:
721: String loc = c.getHeaderField("location");
722: c.close();
723: showAlert("Redirecting to " + loc, null);
724: progressGauge.setLabel(loc);
725:
726: c = (HttpConnection) Connector.open(loc);
727:
728: continue;
729:
730: default:
731: return c;
732: }
733: }
734: }
735:
736: /**
737: * Add request properties for the configuration, profiles,
738: * and locale of this system.
739: * @param c current HttpConnection to receive user agent header
740: */
741: void setConfig(HttpConnection c) throws IOException {
742: String conf = System.getProperty("microedition.configuration");
743: String prof = System.getProperty("microedition.profiles");
744: int space = prof.indexOf(' ');
745:
746: if (space != -1) {
747: prof = prof.substring(0, space - 1);
748: }
749:
750: String platform = System.getProperty("microedition.platform");
751: String locale = System.getProperty("microedition.locale");
752: String ua = "Profile/" + prof + " Configuration/" + conf
753: + " Platform/" + platform;
754:
755: c.setRequestProperty("User-Agent", ua);
756:
757: if (locale != null) {
758: c.setRequestProperty("Content-Language", locale);
759: }
760: }
761:
762: /**
763: * Generate and fill in the Form with the header fields.
764: * @param c the open connection with the result headers.
765: */
766: void genHeaderForm(HttpConnection c) throws IOException {
767: clearForm(headerForm);
768: headerForm.append(new StringItem("response message: ", c
769: .getResponseMessage()));
770: headerForm.append(new StringItem("response code: ", c
771: .getResponseCode()
772: + ""));
773:
774: for (int i = 0;; i++) {
775: String key = c.getHeaderFieldKey(i);
776:
777: if (key == null) {
778: break;
779: }
780:
781: String value = c.getHeaderField(i);
782: StringItem item = new StringItem(key + ": ", value);
783: headerForm.append(item);
784: }
785: }
786:
787: /**
788: * Generate the form with the request attributes and values.
789: * @param c the open connection with the request headers.
790: */
791: void genRequestForm(HttpConnection c) throws IOException {
792: clearForm(requestForm);
793:
794: requestForm.append(new StringItem("URL: ", c.getURL()));
795: requestForm.append(new StringItem("Method: ", c
796: .getRequestMethod()));
797: requestForm
798: .append(new StringItem("Protocol: ", c.getProtocol()));
799: requestForm.append(new StringItem("Host: ", c.getHost()));
800: requestForm.append(new StringItem("File: ", c.getFile()));
801: requestForm.append(new StringItem("Ref: ", c.getRef()));
802: requestForm.append(new StringItem("Query: ", c.getQuery()));
803: requestForm.append(new StringItem("Port: ", Integer.toString(c
804: .getPort())));
805: requestForm.append(new StringItem("User-Agent: ", c
806: .getRequestProperty("User-Agent")));
807: requestForm.append(new StringItem("Content-Language: ", c
808: .getRequestProperty("Content-Language")));
809: }
810:
811: /**
812: * Generate the options form with URL title and progress gauge.
813: * @param name the title of the URL to be loaded.
814: * @param url label for the progress gauge
815: */
816: void genProgressForm(String name, String url) {
817: progressGauge.setValue(0);
818: progressGauge.setLabel(url);
819: progressForm.setTitle(name);
820: }
821:
822: /**
823: * Set the Alert to the exception message and display it.
824: * @param s the Exception title string
825: * @param ex the Exception
826: */
827: void genErrorsForm(String s, Throwable ex) {
828: clearForm(errorsForm);
829:
830: if (s != null) {
831: errorsForm.setTitle(s);
832: } else {
833: errorsForm.setTitle("Exception");
834: }
835:
836: if (ex != null) {
837: ex.printStackTrace();
838: errorsForm.append(ex.getClass().getName());
839: errorsForm.append("\n");
840:
841: String m = ex.getMessage();
842:
843: if (m != null) {
844: errorsForm.append(m);
845: }
846: } else {
847: errorsForm.append("None");
848: }
849: }
850:
851: /**
852: * Set the alert string and display it.
853: * @param s the error message
854: * @param next the screen to be shown after the Alert.
855: */
856: void showAlert(String s, Screen next) {
857: alert.setString(s);
858:
859: if (next == null) {
860: display.setCurrent(alert);
861: } else {
862: display.setCurrent(alert, next);
863: }
864: }
865:
866: /**
867: * Clear out all items in a Form.
868: * @param form the Form to clear.
869: */
870: void clearForm(Form form) {
871: int s = form.size();
872:
873: for (int i = s - 1; i >= 0; i--) {
874: form.delete(i);
875: }
876: }
877: }
|