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/Main.java
38829 views
1
/*
2
* Copyright (c) 1999, 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.io.BufferedInputStream;
29
import java.io.File;
30
import java.io.FileInputStream;
31
import java.io.FileOutputStream;
32
import java.io.IOException;
33
import java.lang.reflect.Method;
34
import java.lang.reflect.InvocationTargetException;
35
import java.net.URL;
36
import java.net.MalformedURLException;
37
import java.util.Enumeration;
38
import java.util.Properties;
39
import java.util.Vector;
40
import sun.net.www.ParseUtil;
41
42
/**
43
* The main entry point into AppletViewer.
44
*/
45
public class Main {
46
/**
47
* The file which contains all of the AppletViewer specific properties.
48
*/
49
static File theUserPropertiesFile;
50
51
/**
52
* The default key/value pairs for the required user-specific properties.
53
*/
54
static final String [][] avDefaultUserProps = {
55
// There's a bootstrapping problem here. If we don't have a proxyHost,
56
// then we will not be able to connect to a URL outside the firewall;
57
// however, there's no way for us to set the proxyHost without starting
58
// AppletViewer. This problem existed before the re-write.
59
{"http.proxyHost", ""},
60
{"http.proxyPort", "80"},
61
{"package.restrict.access.sun", "true"}
62
};
63
64
static {
65
File userHome = new File(System.getProperty("user.home"));
66
// make sure we can write to this location
67
userHome.canWrite();
68
69
theUserPropertiesFile = new File(userHome, ".appletviewer");
70
}
71
72
// i18n
73
private static AppletMessageHandler amh = new AppletMessageHandler("appletviewer");
74
75
/**
76
* Member variables set according to options passed in to AppletViewer.
77
*/
78
private boolean debugFlag = false;
79
private boolean helpFlag = false;
80
private String encoding = null;
81
private boolean noSecurityFlag = false;
82
private static boolean cmdLineTestFlag = false;
83
84
/**
85
* The list of valid URLs passed in to AppletViewer.
86
*/
87
private static Vector urlList = new Vector(1);
88
89
// This is used in init(). Getting rid of this is desirable but depends
90
// on whether the property that uses it is necessary/standard.
91
public static final String theVersion = System.getProperty("java.version");
92
93
/**
94
* The main entry point into AppletViewer.
95
*/
96
public static void main(String [] args) {
97
Main m = new Main();
98
int ret = m.run(args);
99
100
// Exit immediately if we got some sort of error along the way.
101
// For debugging purposes, if we have passed in "-XcmdLineTest" we
102
// force a premature exit.
103
if ((ret != 0) || (cmdLineTestFlag))
104
System.exit(ret);
105
}
106
107
private int run(String [] args) {
108
// DECODE ARGS
109
try {
110
if (args.length == 0) {
111
usage();
112
return 0;
113
}
114
for (int i = 0; i < args.length; ) {
115
int j = decodeArg(args, i);
116
if (j == 0) {
117
throw new ParseException(lookup("main.err.unrecognizedarg",
118
args[i]));
119
}
120
i += j;
121
}
122
} catch (ParseException e) {
123
System.err.println(e.getMessage());
124
return 1;
125
}
126
127
// CHECK ARGUMENTS
128
if (helpFlag) {
129
usage();
130
return 0;
131
}
132
133
if (urlList.size() == 0) {
134
System.err.println(lookup("main.err.inputfile"));
135
return 1;
136
}
137
138
if (debugFlag) {
139
// START A DEBUG SESSION
140
// Given the current architecture, we will end up decoding the
141
// arguments again, but at least we are guaranteed to have
142
// arguments which are valid.
143
return invokeDebugger(args);
144
}
145
146
// INSTALL THE SECURITY MANAGER (if necessary)
147
if (!noSecurityFlag && (System.getSecurityManager() == null))
148
init();
149
150
// LAUNCH APPLETVIEWER FOR EACH URL
151
for (int i = 0; i < urlList.size(); i++) {
152
try {
153
// XXX 5/17 this parsing method should be changed/fixed so that
154
// it doesn't do both parsing of the html file and launching of
155
// the AppletPanel
156
AppletViewer.parse((URL) urlList.elementAt(i), encoding);
157
} catch (IOException e) {
158
System.err.println(lookup("main.err.io", e.getMessage()));
159
return 1;
160
}
161
}
162
return 0;
163
}
164
165
private static void usage() {
166
System.out.println(lookup("usage"));
167
}
168
169
/**
170
* Decode a single argument in an array and return the number of elements
171
* used.
172
*
173
* @param args The array of arguments.
174
* @param i The argument to decode.
175
* @return The number of array elements used when the argument was
176
* decoded.
177
* @exception ParseException
178
* Thrown when there is a problem with something in the
179
* argument array.
180
*/
181
private int decodeArg(String [] args, int i) throws ParseException {
182
String arg = args[i];
183
int argc = args.length;
184
185
if ("-help".equalsIgnoreCase(arg) || "-?".equals(arg)) {
186
helpFlag = true;
187
return 1;
188
} else if ("-encoding".equals(arg) && (i < argc - 1)) {
189
if (encoding != null)
190
throw new ParseException(lookup("main.err.dupoption", arg));
191
encoding = args[++i];
192
return 2;
193
} else if ("-debug".equals(arg)) {
194
debugFlag = true;
195
return 1;
196
} else if ("-Xnosecurity".equals(arg)) {
197
// This is an undocumented (and, in the future, unsupported)
198
// flag which prevents AppletViewer from installing its own
199
// SecurityManager.
200
201
System.err.println();
202
System.err.println(lookup("main.warn.nosecmgr"));
203
System.err.println();
204
205
noSecurityFlag = true;
206
return 1;
207
} else if ("-XcmdLineTest".equals(arg)) {
208
// This is an internal flag which should be used for command-line
209
// testing. It instructs AppletViewer to force a premature exit
210
// immediately after the applet has been launched.
211
cmdLineTestFlag = true;
212
return 1;
213
} else if (arg.startsWith("-")) {
214
throw new ParseException(lookup("main.err.unsupportedopt", arg));
215
} else {
216
// we found what we hope is a url
217
URL url = parseURL(arg);
218
if (url != null) {
219
urlList.addElement(url);
220
return 1;
221
}
222
}
223
return 0;
224
}
225
226
/**
227
* Following the relevant RFC, construct a valid URL based on the passed in
228
* string.
229
*
230
* @param url a string which represents either a relative or absolute URL.
231
* @return a URL when the passed in string can be interpreted according
232
* to the RFC, <code>null</code> otherwise.
233
* @exception ParseException
234
* Thrown when we are unable to construct a proper URL from the
235
* passed in string.
236
*/
237
private URL parseURL(String url) throws ParseException {
238
URL u = null;
239
// prefix of the urls with 'file' scheme
240
String prefix = "file:";
241
242
try {
243
if (url.indexOf(':') <= 1)
244
{
245
// appletviewer accepts only unencoded filesystem paths
246
u = ParseUtil.fileToEncodedURL(new File(url));
247
} else if (url.startsWith(prefix) &&
248
url.length() != prefix.length() &&
249
!(new File(url.substring(prefix.length())).isAbsolute()))
250
{
251
// relative file URL, like this "file:index.html"
252
// ensure that this file URL is absolute
253
// ParseUtil.fileToEncodedURL should be done last (see 6329251)
254
String path = ParseUtil.fileToEncodedURL(new File(System.getProperty("user.dir"))).getPath() +
255
url.substring(prefix.length());
256
u = new URL("file", "", path);
257
} else {
258
// appletviewer accepts only encoded urls
259
u = new URL(url);
260
}
261
} catch (MalformedURLException e) {
262
throw new ParseException(lookup("main.err.badurl",
263
url, e.getMessage()));
264
}
265
266
return u;
267
}
268
269
/**
270
* Invoke the debugger with the arguments passed in to appletviewer.
271
*
272
* @param args The arguments passed into the debugger.
273
* @return <code>0</code> if the debugger is invoked successfully,
274
* <code>1</code> otherwise.
275
*/
276
private int invokeDebugger(String [] args) {
277
// CONSTRUCT THE COMMAND LINE
278
String [] newArgs = new String[args.length + 1];
279
int current = 0;
280
281
// Add a -classpath argument that prevents
282
// the debugger from launching appletviewer with the default of
283
// ".". appletviewer's classpath should never contain valid
284
// classes since they will result in security exceptions.
285
// Ideally, the classpath should be set to "", but the VM won't
286
// allow an empty classpath, so a phony directory name is used.
287
String phonyDir = System.getProperty("java.home") +
288
File.separator + "phony";
289
newArgs[current++] = "-Djava.class.path=" + phonyDir;
290
291
// Appletviewer's main class is the debuggee
292
newArgs[current++] = "sun.applet.Main";
293
294
// Append all the of the original appletviewer arguments,
295
// leaving out the "-debug" option.
296
for (int i = 0; i < args.length; i++) {
297
if (!("-debug".equals(args[i]))) {
298
newArgs[current++] = args[i];
299
}
300
}
301
302
// LAUNCH THE DEBUGGER
303
// Reflection is used for two reasons:
304
// 1) The debugger classes are on classpath and thus must be loaded
305
// by the application class loader. (Currently, appletviewer are
306
// loaded through the boot class path out of rt.jar.)
307
// 2) Reflection removes any build dependency between appletviewer
308
// and jdb.
309
try {
310
Class c = Class.forName("com.sun.tools.example.debug.tty.TTY", true,
311
ClassLoader.getSystemClassLoader());
312
Method m = c.getDeclaredMethod("main",
313
new Class[] { String[].class });
314
m.invoke(null, new Object[] { newArgs });
315
} catch (ClassNotFoundException cnfe) {
316
System.err.println(lookup("main.debug.cantfinddebug"));
317
return 1;
318
} catch (NoSuchMethodException nsme) {
319
System.err.println(lookup("main.debug.cantfindmain"));
320
return 1;
321
} catch (InvocationTargetException ite) {
322
System.err.println(lookup("main.debug.exceptionindebug"));
323
return 1;
324
} catch (IllegalAccessException iae) {
325
System.err.println(lookup("main.debug.cantaccess"));
326
return 1;
327
}
328
return 0;
329
}
330
331
private void init() {
332
// GET APPLETVIEWER USER-SPECIFIC PROPERTIES
333
Properties avProps = getAVProps();
334
335
// ADD OTHER RANDOM PROPERTIES
336
// XXX 5/18 need to revisit why these are here, is there some
337
// standard for what is available?
338
339
// Standard browser properties
340
avProps.put("browser", "sun.applet.AppletViewer");
341
avProps.put("browser.version", "1.06");
342
avProps.put("browser.vendor", "Oracle Corporation");
343
avProps.put("http.agent", "Java(tm) 2 SDK, Standard Edition v" + theVersion);
344
345
// Define which packages can be extended by applets
346
// XXX 5/19 probably not needed, not checked in AppletSecurity
347
avProps.put("package.restrict.definition.java", "true");
348
avProps.put("package.restrict.definition.sun", "true");
349
350
// Define which properties can be read by applets.
351
// A property named by "key" can be read only when its twin
352
// property "key.applet" is true. The following ten properties
353
// are open by default. Any other property can be explicitly
354
// opened up by the browser user by calling appletviewer with
355
// -J-Dkey.applet=true
356
avProps.put("java.version.applet", "true");
357
avProps.put("java.vendor.applet", "true");
358
avProps.put("java.vendor.url.applet", "true");
359
avProps.put("java.class.version.applet", "true");
360
avProps.put("os.name.applet", "true");
361
avProps.put("os.version.applet", "true");
362
avProps.put("os.arch.applet", "true");
363
avProps.put("file.separator.applet", "true");
364
avProps.put("path.separator.applet", "true");
365
avProps.put("line.separator.applet", "true");
366
367
// Read in the System properties. If something is going to be
368
// over-written, warn about it.
369
Properties sysProps = System.getProperties();
370
for (Enumeration e = sysProps.propertyNames(); e.hasMoreElements(); ) {
371
String key = (String) e.nextElement();
372
String val = (String) sysProps.getProperty(key);
373
String oldVal;
374
if ((oldVal = (String) avProps.setProperty(key, val)) != null)
375
System.err.println(lookup("main.warn.prop.overwrite", key,
376
oldVal, val));
377
}
378
379
// INSTALL THE PROPERTY LIST
380
System.setProperties(avProps);
381
382
// Create and install the security manager
383
if (!noSecurityFlag) {
384
System.setSecurityManager(new AppletSecurity());
385
} else {
386
System.err.println(lookup("main.nosecmgr"));
387
}
388
389
// REMIND: Create and install a socket factory!
390
}
391
392
/**
393
* Read the AppletViewer user-specific properties. Typically, these
394
* properties should reside in the file $USER/.appletviewer. If this file
395
* does not exist, one will be created. Information for this file will
396
* be gleaned from $USER/.hotjava/properties. If that file does not exist,
397
* then default values will be used.
398
*
399
* @return A Properties object containing all of the AppletViewer
400
* user-specific properties.
401
*/
402
private Properties getAVProps() {
403
Properties avProps = new Properties();
404
405
File dotAV = theUserPropertiesFile;
406
if (dotAV.exists()) {
407
// we must have already done the conversion
408
if (dotAV.canRead()) {
409
// just read the file
410
avProps = getAVProps(dotAV);
411
} else {
412
// send out warning and use defaults
413
System.err.println(lookup("main.warn.cantreadprops",
414
dotAV.toString()));
415
avProps = setDefaultAVProps();
416
}
417
} else {
418
// create the $USER/.appletviewer file
419
420
// see if $USER/.hotjava/properties exists
421
File userHome = new File(System.getProperty("user.home"));
422
File dotHJ = new File(userHome, ".hotjava");
423
dotHJ = new File(dotHJ, "properties");
424
if (dotHJ.exists()) {
425
// just read the file
426
avProps = getAVProps(dotHJ);
427
} else {
428
// send out warning and use defaults
429
System.err.println(lookup("main.warn.cantreadprops",
430
dotHJ.toString()));
431
avProps = setDefaultAVProps();
432
}
433
434
// SAVE THE FILE
435
try (FileOutputStream out = new FileOutputStream(dotAV)) {
436
avProps.store(out, lookup("main.prop.store"));
437
} catch (IOException e) {
438
System.err.println(lookup("main.err.prop.cantsave",
439
dotAV.toString()));
440
}
441
}
442
return avProps;
443
}
444
445
/**
446
* Set the AppletViewer user-specific properties to be the default values.
447
*
448
* @return A Properties object containing all of the AppletViewer
449
* user-specific properties, set to the default values.
450
*/
451
private Properties setDefaultAVProps() {
452
Properties avProps = new Properties();
453
for (int i = 0; i < avDefaultUserProps.length; i++) {
454
avProps.setProperty(avDefaultUserProps[i][0],
455
avDefaultUserProps[i][1]);
456
}
457
return avProps;
458
}
459
460
/**
461
* Given a file, find only the properties that are setable by AppletViewer.
462
*
463
* @param inFile A Properties file from which we select the properties of
464
* interest.
465
* @return A Properties object containing all of the AppletViewer
466
* user-specific properties.
467
*/
468
private Properties getAVProps(File inFile) {
469
Properties avProps = new Properties();
470
471
// read the file
472
Properties tmpProps = new Properties();
473
try (FileInputStream in = new FileInputStream(inFile)) {
474
tmpProps.load(new BufferedInputStream(in));
475
} catch (IOException e) {
476
System.err.println(lookup("main.err.prop.cantread", inFile.toString()));
477
}
478
479
// pick off the properties we care about
480
for (int i = 0; i < avDefaultUserProps.length; i++) {
481
String value = tmpProps.getProperty(avDefaultUserProps[i][0]);
482
if (value != null) {
483
// the property exists in the file, so replace the default
484
avProps.setProperty(avDefaultUserProps[i][0], value);
485
} else {
486
// just use the default
487
avProps.setProperty(avDefaultUserProps[i][0],
488
avDefaultUserProps[i][1]);
489
}
490
}
491
return avProps;
492
}
493
494
/**
495
* Methods for easier i18n handling.
496
*/
497
498
private static String lookup(String key) {
499
return amh.getMessage(key);
500
}
501
502
private static String lookup(String key, String arg0) {
503
return amh.getMessage(key, arg0);
504
}
505
506
private static String lookup(String key, String arg0, String arg1) {
507
return amh.getMessage(key, arg0, arg1);
508
}
509
510
private static String lookup(String key, String arg0, String arg1,
511
String arg2) {
512
return amh.getMessage(key, arg0, arg1, arg2);
513
}
514
515
class ParseException extends RuntimeException
516
{
517
public ParseException(String msg) {
518
super(msg);
519
}
520
521
public ParseException(Throwable t) {
522
super(t.getMessage());
523
this.t = t;
524
}
525
526
Throwable t = null;
527
}
528
}
529
530