History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/applet/AppletViewer.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/applet/AppletViewer.java+1278−0
@@ -0,0 +1,1278 @@
1+/*
2+ * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.applet;
27+
28+import java.util.*;
29+import java.io.*;
30+import java.awt.*;
31+import java.awt.event.*;
32+import java.awt.print.*;
33+import javax.print.attribute.*;
34+import java.applet.*;
35+import java.net.URL;
36+import java.net.MalformedURLException;
37+import java.net.SocketPermission;
38+import sun.misc.Ref;
39+import java.security.AccessController;
40+import java.security.PrivilegedAction;
41+import java.lang.reflect.InvocationTargetException;
42+import java.lang.reflect.Method;
43+import sun.awt.SunToolkit;
44+import sun.awt.AppContext;
45+import java.lang.ref.WeakReference;
46+
47+/**
48+ * A frame to show the applet tag in.
49+ */
50+class TextFrame extends Frame {
51+
52+ /**
53+ * Create the tag frame.
54+ */
55+ TextFrame(int x, int y, String title, String text) {
56+ setTitle(title);
57+ TextArea txt = new TextArea(20, 60);
58+ txt.setText(text);
59+ txt.setEditable(false);
60+
61+ add("Center", txt);
62+
63+ Panel p = new Panel();
64+ add("South", p);
65+ Button b = new Button(amh.getMessage("button.dismiss", "Dismiss"));
66+ p.add(b);
67+
68+ class ActionEventListener implements ActionListener {
69+ public void actionPerformed(ActionEvent evt) {
70+ dispose();
71+ }
72+ }
73+ b.addActionListener(new ActionEventListener());
74+
75+ pack();
76+ move(x, y);
77+ setVisible(true);
78+
79+ WindowListener windowEventListener = new WindowAdapter() {
80+
81+ public void windowClosing(WindowEvent evt) {
82+ dispose();
83+ }
84+ };
85+
86+ addWindowListener(windowEventListener);
87+ }
88+ private static AppletMessageHandler amh = new AppletMessageHandler("textframe");
89+
90+}
91+
92+/**
93+ * Lets us construct one using unix-style one shot behaviors
94+ */
95+
96+class StdAppletViewerFactory implements AppletViewerFactory
97+{
98+ public AppletViewer createAppletViewer(int x, int y,
99+ URL doc, Hashtable atts) {
100+ return new AppletViewer(x, y, doc, atts, System.out, this);
101+ }
102+
103+ public MenuBar getBaseMenuBar() {
104+ return new MenuBar();
105+ }
106+
107+ public boolean isStandalone() {
108+ return true;
109+ }
110+}
111+
112+/**
113+ * The applet viewer makes it possible to run a Java applet without using a browser.
114+ * For details on the syntax that <B>appletviewer</B> supports, see
115+ * <a href="../../../docs/tooldocs/appletviewertags.html">AppletViewer Tags</a>.
116+ * (The document named appletviewertags.html in the JDK's docs/tooldocs directory,
117+ * once the JDK docs have been installed.)
118+ */
119+public class AppletViewer extends Frame implements AppletContext,
120+ Printable {
121+
122+ /**
123+ * Some constants...
124+ */
125+ private static String defaultSaveFile = "Applet.ser";
126+
127+ /**
128+ * The panel in which the applet is being displayed.
129+ */
130+ AppletViewerPanel panel;
131+
132+ /**
133+ * The status line.
134+ */
135+ Label label;
136+
137+ /**
138+ * output status messages to this stream
139+ */
140+
141+ PrintStream statusMsgStream;
142+
143+ /**
144+ * For cloning
145+ */
146+ AppletViewerFactory factory;
147+
148+
149+ private final class UserActionListener implements ActionListener {
150+ public void actionPerformed(ActionEvent evt) {
151+ processUserAction(evt);
152+ }
153+ }
154+
155+ /**
156+ * Create the applet viewer
157+ */
158+ public AppletViewer(int x, int y, URL doc, Hashtable atts,
159+ PrintStream statusMsgStream, AppletViewerFactory factory) {
160+ this.factory = factory;
161+ this.statusMsgStream = statusMsgStream;
162+ setTitle(amh.getMessage("tool.title", atts.get("code")));
163+
164+ MenuBar mb = factory.getBaseMenuBar();
165+
166+ Menu m = new Menu(amh.getMessage("menu.applet"));
167+
168+ addMenuItem(m, "menuitem.restart");
169+ addMenuItem(m, "menuitem.reload");
170+ addMenuItem(m, "menuitem.stop");
171+ addMenuItem(m, "menuitem.save");
172+ addMenuItem(m, "menuitem.start");
173+ addMenuItem(m, "menuitem.clone");
174+ m.add(new MenuItem("-"));
175+ addMenuItem(m, "menuitem.tag");
176+ addMenuItem(m, "menuitem.info");
177+ addMenuItem(m, "menuitem.edit").disable();
178+ addMenuItem(m, "menuitem.encoding");
179+ m.add(new MenuItem("-"));
180+ addMenuItem(m, "menuitem.print");
181+ m.add(new MenuItem("-"));
182+ addMenuItem(m, "menuitem.props");
183+ m.add(new MenuItem("-"));
184+ addMenuItem(m, "menuitem.close");
185+ if (factory.isStandalone()) {
186+ addMenuItem(m, "menuitem.quit");
187+ }
188+
189+ mb.add(m);
190+
191+ setMenuBar(mb);
192+
193+ add("Center", panel = new AppletViewerPanel(doc, atts));
194+ add("South", label = new Label(amh.getMessage("label.hello")));
195+ panel.init();
196+ appletPanels.addElement(panel);
197+
198+ pack();
199+ move(x, y);
200+ setVisible(true);
201+
202+ WindowListener windowEventListener = new WindowAdapter() {
203+
204+ public void windowClosing(WindowEvent evt) {
205+ appletClose();
206+ }
207+
208+ public void windowIconified(WindowEvent evt) {
209+ appletStop();
210+ }
211+
212+ public void windowDeiconified(WindowEvent evt) {
213+ appletStart();
214+ }
215+ };
216+
217+ class AppletEventListener implements AppletListener
218+ {
219+ final Frame frame;
220+
221+ public AppletEventListener(Frame frame)
222+ {
223+ this.frame = frame;
224+ }
225+
226+ public void appletStateChanged(AppletEvent evt)
227+ {
228+ AppletPanel src = (AppletPanel)evt.getSource();
229+
230+ switch (evt.getID()) {
231+ case AppletPanel.APPLET_RESIZE: {
232+ if(src != null) {
233+ resize(preferredSize());
234+ validate();
235+ }
236+ break;
237+ }
238+ case AppletPanel.APPLET_LOADING_COMPLETED: {
239+ Applet a = src.getApplet(); // sun.applet.AppletPanel
240+
241+ // Fixed #4754451: Applet can have methods running on main
242+ // thread event queue.
243+ //
244+ // The cause of this bug is that the frame of the applet
245+ // is created in main thread group. Thus, when certain
246+ // AWT/Swing events are generated, the events will be
247+ // dispatched through the wrong event dispatch thread.
248+ //
249+ // To fix this, we rearrange the AppContext with the frame,
250+ // so the proper event queue will be looked up.
251+ //
252+ // Swing also maintains a Frame list for the AppContext,
253+ // so we will have to rearrange it as well.
254+ //
255+ if (a != null)
256+ AppletPanel.changeFrameAppContext(frame, SunToolkit.targetToAppContext(a));
257+ else
258+ AppletPanel.changeFrameAppContext(frame, AppContext.getAppContext());
259+
260+ break;
261+ }
262+ }
263+ }
264+ };
265+
266+ addWindowListener(windowEventListener);
267+ panel.addAppletListener(new AppletEventListener(this));
268+
269+ // Start the applet
270+ showStatus(amh.getMessage("status.start"));
271+ initEventQueue();
272+ }
273+
274+ // XXX 99/9/10 probably should be "private"
275+ public MenuItem addMenuItem(Menu m, String s) {
276+ MenuItem mItem = new MenuItem(amh.getMessage(s));
277+ mItem.addActionListener(new UserActionListener());
278+ return m.add(mItem);
279+ }
280+
281+ /**
282+ * Send the initial set of events to the appletviewer event queue.
283+ * On start-up the current behaviour is to load the applet and call
284+ * Applet.init() and Applet.start().
285+ */
286+ private void initEventQueue() {
287+ // appletviewer.send.event is an undocumented and unsupported system
288+ // property which is used exclusively for testing purposes.
289+ String eventList = System.getProperty("appletviewer.send.event");
290+
291+ if (eventList == null) {
292+ // Add the standard events onto the event queue.
293+ panel.sendEvent(AppletPanel.APPLET_LOAD);
294+ panel.sendEvent(AppletPanel.APPLET_INIT);
295+ panel.sendEvent(AppletPanel.APPLET_START);
296+ } else {
297+ // We're testing AppletViewer. Force the specified set of events
298+ // onto the event queue, wait for the events to be processed, and
299+ // exit.
300+
301+ // The list of events that will be executed is provided as a
302+ // ","-separated list. No error-checking will be done on the list.
303+ String [] events = splitSeparator(",", eventList);
304+
305+ for (int i = 0; i < events.length; i++) {
306+ System.out.println("Adding event to queue: " + events[i]);
307+ if (events[i].equals("dispose"))
308+ panel.sendEvent(AppletPanel.APPLET_DISPOSE);
309+ else if (events[i].equals("load"))
310+ panel.sendEvent(AppletPanel.APPLET_LOAD);
311+ else if (events[i].equals("init"))
312+ panel.sendEvent(AppletPanel.APPLET_INIT);
313+ else if (events[i].equals("start"))
314+ panel.sendEvent(AppletPanel.APPLET_START);
315+ else if (events[i].equals("stop"))
316+ panel.sendEvent(AppletPanel.APPLET_STOP);
317+ else if (events[i].equals("destroy"))
318+ panel.sendEvent(AppletPanel.APPLET_DESTROY);
319+ else if (events[i].equals("quit"))
320+ panel.sendEvent(AppletPanel.APPLET_QUIT);
321+ else if (events[i].equals("error"))
322+ panel.sendEvent(AppletPanel.APPLET_ERROR);
323+ else
324+ // non-fatal error if we get an unrecognized event
325+ System.out.println("Unrecognized event name: " + events[i]);
326+ }
327+
328+ while (!panel.emptyEventQueue()) ;
329+ appletSystemExit();
330+ }
331+ }
332+
333+ /**
334+ * Split a string based on the presence of a specified separator. Returns
335+ * an array of arbitrary length. The end of each element in the array is
336+ * indicated by the separator of the end of the string. If there is a
337+ * separator immediately before the end of the string, the final element
338+ * will be empty. None of the strings will contain the separator. Useful
339+ * when separating strings such as "foo/bar/bas" using separator "/".
340+ *
341+ * @param sep The separator.
342+ * @param s The string to split.
343+ * @return An array of strings. Each string in the array is determined
344+ * by the location of the provided sep in the original string,
345+ * s. Whitespace not stripped.
346+ */
347+ private String [] splitSeparator(String sep, String s) {
348+ Vector v = new Vector();
349+ int tokenStart = 0;
350+ int tokenEnd = 0;
351+
352+ while ((tokenEnd = s.indexOf(sep, tokenStart)) != -1) {
353+ v.addElement(s.substring(tokenStart, tokenEnd));
354+ tokenStart = tokenEnd+1;
355+ }
356+ // Add the final element.
357+ v.addElement(s.substring(tokenStart));
358+
359+ String [] retVal = new String[v.size()];
360+ v.copyInto(retVal);
361+ return retVal;
362+ }
363+
364+ /*
365+ * Methods for java.applet.AppletContext
366+ */
367+
368+ private static Map audioClips = new HashMap();
369+
370+ /**
371+ * Get an audio clip.
372+ */
373+ public AudioClip getAudioClip(URL url) {
374+ checkConnect(url);
375+ synchronized (audioClips) {
376+ AudioClip clip = (AudioClip)audioClips.get(url);
377+ if (clip == null) {
378+ audioClips.put(url, clip = new AppletAudioClip(url));
379+ }
380+ return clip;
381+ }
382+ }
383+
384+ private static Map imageRefs = new HashMap();
385+
386+ /**
387+ * Get an image.
388+ */
389+ public Image getImage(URL url) {
390+ return getCachedImage(url);
391+ }
392+
393+ static Image getCachedImage(URL url) {
394+ // System.getSecurityManager().checkConnection(url.getHost(), url.getPort());
395+ return (Image)getCachedImageRef(url).get();
396+ }
397+
398+ /**
399+ * Get an image ref.
400+ */
401+ static Ref getCachedImageRef(URL url) {
402+ synchronized (imageRefs) {
403+ AppletImageRef ref = (AppletImageRef)imageRefs.get(url);
404+ if (ref == null) {
405+ ref = new AppletImageRef(url);
406+ imageRefs.put(url, ref);
407+ }
408+ return ref;
409+ }
410+ }
411+
412+ /**
413+ * Flush the image cache.
414+ */
415+ static void flushImageCache() {
416+ imageRefs.clear();
417+ }
418+
419+ static Vector appletPanels = new Vector();
420+
421+ /**
422+ * Get an applet by name.
423+ */
424+ public Applet getApplet(String name) {
425+ AppletSecurity security = (AppletSecurity)System.getSecurityManager();
426+ name = name.toLowerCase();
427+ SocketPermission panelSp =
428+ new SocketPermission(panel.getCodeBase().getHost(), "connect");
429+ for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) {
430+ AppletPanel p = (AppletPanel)e.nextElement();
431+ String param = p.getParameter("name");
432+ if (param != null) {
433+ param = param.toLowerCase();
434+ }
435+ if (name.equals(param) &&
436+ p.getDocumentBase().equals(panel.getDocumentBase())) {
437+
438+ SocketPermission sp =
439+ new SocketPermission(p.getCodeBase().getHost(), "connect");
440+
441+ if (panelSp.implies(sp)) {
442+ return p.applet;
443+ }
444+ }
445+ }
446+ return null;
447+ }
448+
449+ /**
450+ * Return an enumeration of all the accessible
451+ * applets on this page.
452+ */
453+ public Enumeration getApplets() {
454+ AppletSecurity security = (AppletSecurity)System.getSecurityManager();
455+ Vector v = new Vector();
456+ SocketPermission panelSp =
457+ new SocketPermission(panel.getCodeBase().getHost(), "connect");
458+
459+ for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) {
460+ AppletPanel p = (AppletPanel)e.nextElement();
461+ if (p.getDocumentBase().equals(panel.getDocumentBase())) {
462+
463+ SocketPermission sp =
464+ new SocketPermission(p.getCodeBase().getHost(), "connect");
465+ if (panelSp.implies(sp)) {
466+ v.addElement(p.applet);
467+ }
468+ }
469+ }
470+ return v.elements();
471+ }
472+
473+ /**
474+ * Ignore.
475+ */
476+ public void showDocument(URL url) {
477+ }
478+
479+ /**
480+ * Ignore.
481+ */
482+ public void showDocument(URL url, String target) {
483+ }
484+
485+ /**
486+ * Show status.
487+ */
488+ public void showStatus(String status) {
489+ label.setText(status);
490+ }
491+
492+ public void setStream(String key, InputStream stream)throws IOException{
493+ // We do nothing.
494+ }
495+
496+ public InputStream getStream(String key){
497+ // We do nothing.
498+ return null;
499+ }
500+
501+ public Iterator getStreamKeys(){
502+ // We do nothing.
503+ return null;
504+ }
505+
506+ /**
507+ * System parameters.
508+ */
509+ static Hashtable systemParam = new Hashtable();
510+
511+ static {
512+ systemParam.put("codebase", "codebase");
513+ systemParam.put("code", "code");
514+ systemParam.put("alt", "alt");
515+ systemParam.put("width", "width");
516+ systemParam.put("height", "height");
517+ systemParam.put("align", "align");
518+ systemParam.put("vspace", "vspace");
519+ systemParam.put("hspace", "hspace");
520+ }
521+
522+ /**
523+ * Print the HTML tag.
524+ */
525+ public static void printTag(PrintStream out, Hashtable atts) {
526+ out.print("<applet");
527+
528+ String v = (String)atts.get("codebase");
529+ if (v != null) {
530+ out.print(" codebase=\"" + v + "\"");
531+ }
532+
533+ v = (String)atts.get("code");
534+ if (v == null) {
535+ v = "applet.class";
536+ }
537+ out.print(" code=\"" + v + "\"");
538+ v = (String)atts.get("width");
539+ if (v == null) {
540+ v = "150";
541+ }
542+ out.print(" width=" + v);
543+
544+ v = (String)atts.get("height");
545+ if (v == null) {
546+ v = "100";
547+ }
548+ out.print(" height=" + v);
549+
550+ v = (String)atts.get("name");
551+ if (v != null) {
552+ out.print(" name=\"" + v + "\"");
553+ }
554+ out.println(">");
555+
556+ // A very slow sorting algorithm
557+ int len = atts.size();
558+ String params[] = new String[len];
559+ len = 0;
560+ for (Enumeration e = atts.keys() ; e.hasMoreElements() ;) {
561+ String param = (String)e.nextElement();
562+ int i = 0;
563+ for (; i < len ; i++) {
564+ if (params[i].compareTo(param) >= 0) {
565+ break;
566+ }
567+ }
568+ System.arraycopy(params, i, params, i + 1, len - i);
569+ params[i] = param;
570+ len++;
571+ }
572+
573+ for (int i = 0 ; i < len ; i++) {
574+ String param = params[i];
575+ if (systemParam.get(param) == null) {
576+ out.println("<param name=" + param +
577+ " value=\"" + atts.get(param) + "\">");
578+ }
579+ }
580+ out.println("</applet>");
581+ }
582+
583+ /**
584+ * Make sure the atrributes are uptodate.
585+ */
586+ public void updateAtts() {
587+ Dimension d = panel.size();
588+ Insets in = panel.insets();
589+ panel.atts.put("width",
590+ Integer.toString(d.width - (in.left + in.right)));
591+ panel.atts.put("height",
592+ Integer.toString(d.height - (in.top + in.bottom)));
593+ }
594+
595+ /**
596+ * Restart the applet.
597+ */
598+ void appletRestart() {
599+ panel.sendEvent(AppletPanel.APPLET_STOP);
600+ panel.sendEvent(AppletPanel.APPLET_DESTROY);
601+ panel.sendEvent(AppletPanel.APPLET_INIT);
602+ panel.sendEvent(AppletPanel.APPLET_START);
603+ }
604+
605+ /**
606+ * Reload the applet.
607+ */
608+ void appletReload() {
609+ panel.sendEvent(AppletPanel.APPLET_STOP);
610+ panel.sendEvent(AppletPanel.APPLET_DESTROY);
611+ panel.sendEvent(AppletPanel.APPLET_DISPOSE);
612+
613+ /**
614+ * Fixed #4501142: Classlaoder sharing policy doesn't
615+ * take "archive" into account. This will be overridden
616+ * by Java Plug-in. [stanleyh]
617+ */
618+ AppletPanel.flushClassLoader(panel.getClassLoaderCacheKey());
619+
620+ /*
621+ * Make sure we don't have two threads running through the event queue
622+ * at the same time.
623+ */
624+ try {
625+ panel.joinAppletThread();
626+ panel.release();
627+ } catch (InterruptedException e) {
628+ return; // abort the reload
629+ }
630+
631+ panel.createAppletThread();
632+ panel.sendEvent(AppletPanel.APPLET_LOAD);
633+ panel.sendEvent(AppletPanel.APPLET_INIT);
634+ panel.sendEvent(AppletPanel.APPLET_START);
635+ }
636+
637+ /**
638+ * Save the applet to a well known file (for now) as a serialized object
639+ */
640+ void appletSave() {
641+ AccessController.doPrivileged(new PrivilegedAction() {
642+
643+ public Object run() {
644+ // XXX: this privileged block should be made smaller
645+ // by initializing a private static variable with "user.dir"
646+
647+ // Applet needs to be stopped for serialization to succeed.
648+ // Since panel.sendEvent only queues the event, there is a
649+ // chance that the event will not be processed before
650+ // serialization begins. However, by sending the event before
651+ // FileDialog is created, enough time is given such that this
652+ // situation is unlikely to ever occur.
653+
654+ panel.sendEvent(AppletPanel.APPLET_STOP);
655+ FileDialog fd = new FileDialog(AppletViewer.this,
656+ amh.getMessage("appletsave.filedialogtitle"),
657+ FileDialog.SAVE);
658+ // needed for a bug under Solaris...
659+ fd.setDirectory(System.getProperty("user.dir"));
660+ fd.setFile(defaultSaveFile);
661+ fd.show();
662+ String fname = fd.getFile();
663+ if (fname == null) {
664+ // Restart applet if Save is cancelled.
665+ panel.sendEvent(AppletPanel.APPLET_START);
666+ return null; // cancelled
667+ }
668+ String dname = fd.getDirectory();
669+ File file = new File(dname, fname);
670+
671+ try {
672+ BufferedOutputStream s = new BufferedOutputStream(new FileOutputStream(file));
673+ ObjectOutputStream os = new ObjectOutputStream(s);
674+ showStatus(amh.getMessage("appletsave.err1",
675+ panel.applet.toString(), file.toString()));
676+ os.writeObject(panel.applet);
677+ } catch (IOException ex) {
678+ System.err.println(amh.getMessage("appletsave.err2", ex));
679+ } finally {
680+ panel.sendEvent(AppletPanel.APPLET_START);
681+ }
682+ return null;
683+ }
684+ });
685+ }
686+
687+ /**
688+ * Clone the viewer and the applet.
689+ */
690+ void appletClone() {
691+ Point p = location();
692+ updateAtts();
693+ factory.createAppletViewer(p.x + XDELTA, p.y + YDELTA,
694+ panel.documentURL, (Hashtable)panel.atts.clone());
695+ }
696+
697+ /**
698+ * Show the applet tag.
699+ */
700+ void appletTag() {
701+ ByteArrayOutputStream out = new ByteArrayOutputStream();
702+ updateAtts();
703+ printTag(new PrintStream(out), panel.atts);
704+ showStatus(amh.getMessage("applettag"));
705+
706+ Point p = location();
707+ new TextFrame(p.x + XDELTA, p.y + YDELTA, amh.getMessage("applettag.textframe"), out.toString());
708+ }
709+
710+ /**
711+ * Show the applet info.
712+ */
713+ void appletInfo() {
714+ String str = panel.applet.getAppletInfo();
715+ if (str == null) {
716+ str = amh.getMessage("appletinfo.applet");
717+ }
718+ str += "\n\n";
719+
720+ String atts[][] = panel.applet.getParameterInfo();
721+ if (atts != null) {
722+ for (int i = 0 ; i < atts.length ; i++) {
723+ str += atts[i][0] + " -- " + atts[i][1] + " -- " + atts[i][2] + "\n";
724+ }
725+ } else {
726+ str += amh.getMessage("appletinfo.param");
727+ }
728+
729+ Point p = location();
730+ new TextFrame(p.x + XDELTA, p.y + YDELTA, amh.getMessage("appletinfo.textframe"), str);
731+
732+ }
733+
734+ /**
735+ * Show character encoding type
736+ */
737+ void appletCharacterEncoding() {
738+ showStatus(amh.getMessage("appletencoding", encoding));
739+ }
740+
741+ /**
742+ * Edit the applet.
743+ */
744+ void appletEdit() {
745+ }
746+
747+ /**
748+ * Print the applet.
749+ */
750+ void appletPrint() {
751+ PrinterJob pj = PrinterJob.getPrinterJob();
752+
753+ if (pj != null) {
754+ PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
755+ if (pj.printDialog(aset)) {
756+ pj.setPrintable(this);
757+ try {
758+ pj.print(aset);
759+ statusMsgStream.println(amh.getMessage("appletprint.finish"));
760+ } catch (PrinterException e) {
761+ statusMsgStream.println(amh.getMessage("appletprint.fail"));
762+ }
763+ } else {
764+ statusMsgStream.println(amh.getMessage("appletprint.cancel"));
765+ }
766+ } else {
767+ statusMsgStream.println(amh.getMessage("appletprint.fail"));
768+ }
769+ }
770+
771+ public int print(Graphics graphics, PageFormat pf, int pageIndex) {
772+ if (pageIndex > 0) {
773+ return Printable.NO_SUCH_PAGE;
774+ } else {
775+ Graphics2D g2d = (Graphics2D)graphics;
776+ g2d.translate(pf.getImageableX(), pf.getImageableY());
777+ panel.applet.printAll(graphics);
778+ return Printable.PAGE_EXISTS;
779+ }
780+ }
781+
782+ /**
783+ * Properties.
784+ */
785+ static AppletProps props;
786+ public static synchronized void networkProperties() {
787+ if (props == null) {
788+ props = new AppletProps();
789+ }
790+ props.addNotify();
791+ props.setVisible(true);
792+ }
793+
794+ /**
795+ * Start the applet.
796+ */
797+ void appletStart() {
798+ panel.sendEvent(AppletPanel.APPLET_START);
799+ }
800+
801+ /**
802+ * Stop the applet.
803+ */
804+ void appletStop() {
805+ panel.sendEvent(AppletPanel.APPLET_STOP);
806+ }
807+
808+ /**
809+ * Shutdown a viewer.
810+ * Stop, Destroy, Dispose and Quit a viewer
811+ */
812+ private void appletShutdown(AppletPanel p) {
813+ p.sendEvent(AppletPanel.APPLET_STOP);
814+ p.sendEvent(AppletPanel.APPLET_DESTROY);
815+ p.sendEvent(AppletPanel.APPLET_DISPOSE);
816+ p.sendEvent(AppletPanel.APPLET_QUIT);
817+ }
818+
819+ /**
820+ * Close this viewer.
821+ * Stop, Destroy, Dispose and Quit an AppletView, then
822+ * reclaim resources and exit the program if this is
823+ * the last applet.
824+ */
825+ void appletClose() {
826+
827+ // The caller thread is event dispatch thread, so
828+ // spawn a new thread to avoid blocking the event queue
829+ // when calling appletShutdown.
830+ //
831+ final AppletPanel p = panel;
832+
833+ new Thread(new Runnable()
834+ {
835+ public void run()
836+ {
837+ appletShutdown(p);
838+ appletPanels.removeElement(p);
839+ dispose();
840+
841+ if (countApplets() == 0) {
842+ appletSystemExit();
843+ }
844+ }
845+ }).start();
846+ }
847+
848+ /**
849+ * Exit the program.
850+ * Exit from the program (if not stand alone) - do no clean-up
851+ */
852+ private void appletSystemExit() {
853+ if (factory.isStandalone())
854+ System.exit(0);
855+ }
856+
857+ /**
858+ * Quit all viewers.
859+ * Shutdown all viewers properly then
860+ * exit from the program (if not stand alone)
861+ */
862+ protected void appletQuit()
863+ {
864+ // The caller thread is event dispatch thread, so
865+ // spawn a new thread to avoid blocking the event queue
866+ // when calling appletShutdown.
867+ //
868+ new Thread(new Runnable()
869+ {
870+ public void run()
871+ {
872+ for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) {
873+ AppletPanel p = (AppletPanel)e.nextElement();
874+ appletShutdown(p);
875+ }
876+ appletSystemExit();
877+ }
878+ }).start();
879+ }
880+
881+ /**
882+ * Handle events.
883+ */
884+ public void processUserAction(ActionEvent evt) {
885+
886+ String label = ((MenuItem)evt.getSource()).getLabel();
887+
888+ if (amh.getMessage("menuitem.restart").equals(label)) {
889+ appletRestart();
890+ return;
891+ }
892+
893+ if (amh.getMessage("menuitem.reload").equals(label)) {
894+ appletReload();
895+ return;
896+ }
897+
898+ if (amh.getMessage("menuitem.clone").equals(label)) {
899+ appletClone();
900+ return;
901+ }
902+
903+ if (amh.getMessage("menuitem.stop").equals(label)) {
904+ appletStop();
905+ return;
906+ }
907+
908+ if (amh.getMessage("menuitem.save").equals(label)) {
909+ appletSave();
910+ return;
911+ }
912+
913+ if (amh.getMessage("menuitem.start").equals(label)) {
914+ appletStart();
915+ return;
916+ }
917+
918+ if (amh.getMessage("menuitem.tag").equals(label)) {
919+ appletTag();
920+ return;
921+ }
922+
923+ if (amh.getMessage("menuitem.info").equals(label)) {
924+ appletInfo();
925+ return;
926+ }
927+
928+ if (amh.getMessage("menuitem.encoding").equals(label)) {
929+ appletCharacterEncoding();
930+ return;
931+ }
932+
933+ if (amh.getMessage("menuitem.edit").equals(label)) {
934+ appletEdit();
935+ return;
936+ }
937+
938+ if (amh.getMessage("menuitem.print").equals(label)) {
939+ appletPrint();
940+ return;
941+ }
942+
943+ if (amh.getMessage("menuitem.props").equals(label)) {
944+ networkProperties();
945+ return;
946+ }
947+
948+ if (amh.getMessage("menuitem.close").equals(label)) {
949+ appletClose();
950+ return;
951+ }
952+
953+ if (factory.isStandalone() && amh.getMessage("menuitem.quit").equals(label)) {
954+ appletQuit();
955+ return;
956+ }
957+ //statusMsgStream.println("evt = " + evt);
958+ }
959+
960+ /**
961+ * How many applets are running?
962+ */
963+
964+ public static int countApplets() {
965+ return appletPanels.size();
966+ }
967+
968+
969+ /**
970+ * The current character.
971+ */
972+ static int c;
973+
974+ /**
975+ * Scan spaces.
976+ */
977+ public static void skipSpace(Reader in) throws IOException {
978+ while ((c >= 0) &&
979+ ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'))) {
980+ c = in.read();
981+ }
982+ }
983+
984+ /**
985+ * Scan identifier
986+ */
987+ public static String scanIdentifier(Reader in) throws IOException {
988+ StringBuffer buf = new StringBuffer();
989+ while (true) {
990+ if (((c >= 'a') && (c <= 'z')) ||
991+ ((c >= 'A') && (c <= 'Z')) ||
992+ ((c >= '0') && (c <= '9')) || (c == '_')) {
993+ buf.append((char)c);
994+ c = in.read();
995+ } else {
996+ return buf.toString();
997+ }
998+ }
999+ }
1000+
1001+ /**
1002+ * Scan tag
1003+ */
1004+ public static Hashtable scanTag(Reader in) throws IOException {
1005+ Hashtable atts = new Hashtable();
1006+ skipSpace(in);
1007+ while (c >= 0 && c != '>') {
1008+ String att = scanIdentifier(in);
1009+ String val = "";
1010+ skipSpace(in);
1011+ if (c == '=') {
1012+ int quote = -1;
1013+ c = in.read();
1014+ skipSpace(in);
1015+ if ((c == '\'') || (c == '\"')) {
1016+ quote = c;
1017+ c = in.read();
1018+ }
1019+ StringBuffer buf = new StringBuffer();
1020+ while ((c > 0) &&
1021+ (((quote < 0) && (c != ' ') && (c != '\t') &&
1022+ (c != '\n') && (c != '\r') && (c != '>'))
1023+ || ((quote >= 0) && (c != quote)))) {
1024+ buf.append((char)c);
1025+ c = in.read();
1026+ }
1027+ if (c == quote) {
1028+ c = in.read();
1029+ }
1030+ skipSpace(in);
1031+ val = buf.toString();
1032+ }
1033+ //statusMsgStream.println("PUT " + att + " = '" + val + "'");
1034+ if (! val.equals("")) {
1035+ atts.put(att.toLowerCase(java.util.Locale.ENGLISH), val);
1036+ }
1037+ while (true) {
1038+ if ((c == '>') || (c < 0) ||
1039+ ((c >= 'a') && (c <= 'z')) ||
1040+ ((c >= 'A') && (c <= 'Z')) ||
1041+ ((c >= '0') && (c <= '9')) || (c == '_'))
1042+ break;
1043+ c = in.read();
1044+ }
1045+ //skipSpace(in);
1046+ }
1047+ return atts;
1048+ }
1049+
1050+ /* values used for placement of AppletViewer's frames */
1051+ private static int x = 0;
1052+ private static int y = 0;
1053+ private static final int XDELTA = 30;
1054+ private static final int YDELTA = XDELTA;
1055+
1056+ static String encoding = null;
1057+
1058+ static private Reader makeReader(InputStream is) {
1059+ if (encoding != null) {
1060+ try {
1061+ return new BufferedReader(new InputStreamReader(is, encoding));
1062+ } catch (IOException x) { }
1063+ }
1064+ InputStreamReader r = new InputStreamReader(is);
1065+ encoding = r.getEncoding();
1066+ return new BufferedReader(r);
1067+ }
1068+
1069+ /**
1070+ * Scan an html file for <applet> tags
1071+ */
1072+ public static void parse(URL url, String enc) throws IOException {
1073+ encoding = enc;
1074+ parse(url, System.out, new StdAppletViewerFactory());
1075+ }
1076+
1077+ public static void parse(URL url) throws IOException {
1078+ parse(url, System.out, new StdAppletViewerFactory());
1079+ }
1080+
1081+ public static void parse(URL url, PrintStream statusMsgStream,
1082+ AppletViewerFactory factory) throws IOException {
1083+ // <OBJECT> <EMBED> tag flags
1084+ boolean isAppletTag = false;
1085+ boolean isObjectTag = false;
1086+ boolean isEmbedTag = false;
1087+
1088+ // warning messages
1089+ String requiresNameWarning = amh.getMessage("parse.warning.requiresname");
1090+ String paramOutsideWarning = amh.getMessage("parse.warning.paramoutside");
1091+ String appletRequiresCodeWarning = amh.getMessage("parse.warning.applet.requirescode");
1092+ String appletRequiresHeightWarning = amh.getMessage("parse.warning.applet.requiresheight");
1093+ String appletRequiresWidthWarning = amh.getMessage("parse.warning.applet.requireswidth");
1094+ String objectRequiresCodeWarning = amh.getMessage("parse.warning.object.requirescode");
1095+ String objectRequiresHeightWarning = amh.getMessage("parse.warning.object.requiresheight");
1096+ String objectRequiresWidthWarning = amh.getMessage("parse.warning.object.requireswidth");
1097+ String embedRequiresCodeWarning = amh.getMessage("parse.warning.embed.requirescode");
1098+ String embedRequiresHeightWarning = amh.getMessage("parse.warning.embed.requiresheight");
1099+ String embedRequiresWidthWarning = amh.getMessage("parse.warning.embed.requireswidth");
1100+ String appNotLongerSupportedWarning = amh.getMessage("parse.warning.appnotLongersupported");
1101+
1102+ java.net.URLConnection conn = url.openConnection();
1103+ Reader in = makeReader(conn.getInputStream());
1104+ /* The original URL may have been redirected - this
1105+ * sets it to whatever URL/codebase we ended up getting
1106+ */
1107+ url = conn.getURL();
1108+
1109+ int ydisp = 1;
1110+ Hashtable atts = null;
1111+
1112+ while(true) {
1113+ c = in.read();
1114+ if (c == -1)
1115+ break;
1116+
1117+ if (c == '<') {
1118+ c = in.read();
1119+ if (c == '/') {
1120+ c = in.read();
1121+ String nm = scanIdentifier(in);
1122+ if (nm.equalsIgnoreCase("applet") ||
1123+ nm.equalsIgnoreCase("object") ||
1124+ nm.equalsIgnoreCase("embed")) {
1125+
1126+ // We can't test for a code tag until </OBJECT>
1127+ // because it is a parameter, not an attribute.
1128+ if(isObjectTag) {
1129+ if (atts.get("code") == null && atts.get("object") == null) {
1130+ statusMsgStream.println(objectRequiresCodeWarning);
1131+ atts = null;
1132+ }
1133+ }
1134+
1135+ if (atts != null) {
1136+ // XXX 5/18 In general this code just simply
1137+ // shouldn't be part of parsing. It's presence
1138+ // causes things to be a little too much of a
1139+ // hack.
1140+ factory.createAppletViewer(x, y, url, atts);
1141+ x += XDELTA;
1142+ y += YDELTA;
1143+ // make sure we don't go too far!
1144+ Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
1145+ if ((x > d.width - 300) || (y > d.height - 300)) {
1146+ x = 0;
1147+ y = 2 * ydisp * YDELTA;
1148+ ydisp++;
1149+ }
1150+ }
1151+ atts = null;
1152+ isAppletTag = false;
1153+ isObjectTag = false;
1154+ isEmbedTag = false;
1155+ }
1156+ }
1157+ else {
1158+ String nm = scanIdentifier(in);
1159+ if (nm.equalsIgnoreCase("param")) {
1160+ Hashtable t = scanTag(in);
1161+ String att = (String)t.get("name");
1162+ if (att == null) {
1163+ statusMsgStream.println(requiresNameWarning);
1164+ } else {
1165+ String val = (String)t.get("value");
1166+ if (val == null) {
1167+ statusMsgStream.println(requiresNameWarning);
1168+ } else if (atts != null) {
1169+ atts.put(att.toLowerCase(), val);
1170+ } else {
1171+ statusMsgStream.println(paramOutsideWarning);
1172+ }
1173+ }
1174+ }
1175+ else if (nm.equalsIgnoreCase("applet")) {
1176+ isAppletTag = true;
1177+ atts = scanTag(in);
1178+ if (atts.get("code") == null && atts.get("object") == null) {
1179+ statusMsgStream.println(appletRequiresCodeWarning);
1180+ atts = null;
1181+ } else if (atts.get("width") == null) {
1182+ statusMsgStream.println(appletRequiresWidthWarning);
1183+ atts = null;
1184+ } else if (atts.get("height") == null) {
1185+ statusMsgStream.println(appletRequiresHeightWarning);
1186+ atts = null;
1187+ }
1188+ }
1189+ else if (nm.equalsIgnoreCase("object")) {
1190+ isObjectTag = true;
1191+ atts = scanTag(in);
1192+ // The <OBJECT> attribute codebase isn't what
1193+ // we want. If its defined, remove it.
1194+ if(atts.get("codebase") != null) {
1195+ atts.remove("codebase");
1196+ }
1197+
1198+ if (atts.get("width") == null) {
1199+ statusMsgStream.println(objectRequiresWidthWarning);
1200+ atts = null;
1201+ } else if (atts.get("height") == null) {
1202+ statusMsgStream.println(objectRequiresHeightWarning);
1203+ atts = null;
1204+ }
1205+ }
1206+ else if (nm.equalsIgnoreCase("embed")) {
1207+ isEmbedTag = true;
1208+ atts = scanTag(in);
1209+
1210+ if (atts.get("code") == null && atts.get("object") == null) {
1211+ statusMsgStream.println(embedRequiresCodeWarning);
1212+ atts = null;
1213+ } else if (atts.get("width") == null) {
1214+ statusMsgStream.println(embedRequiresWidthWarning);
1215+ atts = null;
1216+ } else if (atts.get("height") == null) {
1217+ statusMsgStream.println(embedRequiresHeightWarning);
1218+ atts = null;
1219+ }
1220+ }
1221+ else if (nm.equalsIgnoreCase("app")) {
1222+ statusMsgStream.println(appNotLongerSupportedWarning);
1223+ Hashtable atts2 = scanTag(in);
1224+ nm = (String)atts2.get("class");
1225+ if (nm != null) {
1226+ atts2.remove("class");
1227+ atts2.put("code", nm + ".class");
1228+ }
1229+ nm = (String)atts2.get("src");
1230+ if (nm != null) {
1231+ atts2.remove("src");
1232+ atts2.put("codebase", nm);
1233+ }
1234+ if (atts2.get("width") == null) {
1235+ atts2.put("width", "100");
1236+ }
1237+ if (atts2.get("height") == null) {
1238+ atts2.put("height", "100");
1239+ }
1240+ printTag(statusMsgStream, atts2);
1241+ statusMsgStream.println();
1242+ }
1243+ }
1244+ }
1245+ }
1246+ in.close();
1247+ }
1248+
1249+ /**
1250+ * Old main entry point.
1251+ *
1252+ * @deprecated
1253+ */
1254+ @Deprecated
1255+ public static void main(String argv[]) {
1256+ // re-route everything to the new main entry point
1257+ Main.main(argv);
1258+ }
1259+
1260+ private static AppletMessageHandler amh = new AppletMessageHandler("appletviewer");
1261+
1262+ private static void checkConnect(URL url)
1263+ {
1264+ SecurityManager security = System.getSecurityManager();
1265+ if (security != null) {
1266+ try {
1267+ java.security.Permission perm =
1268+ url.openConnection().getPermission();
1269+ if (perm != null)
1270+ security.checkPermission(perm);
1271+ else
1272+ security.checkConnect(url.getHost(), url.getPort());
1273+ } catch (java.io.IOException ioe) {
1274+ security.checkConnect(url.getHost(), url.getPort());
1275+ }
1276+ }
1277+ }
1278+}