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