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/rmi/rmic/Main.java
38831 views
1
/*
2
* Copyright (c) 1996, 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
/*
27
* Licensed Materials - Property of IBM
28
* RMI-IIOP v1.0
29
* Copyright IBM Corp. 1998 1999 All Rights Reserved
30
*
31
*/
32
33
package sun.rmi.rmic;
34
35
import java.util.Vector;
36
import java.util.Enumeration;
37
import java.util.ResourceBundle;
38
import java.util.StringTokenizer;
39
import java.util.MissingResourceException;
40
41
import java.io.OutputStream;
42
import java.io.PrintStream;
43
import java.io.IOException;
44
import java.io.File;
45
import java.io.FileNotFoundException;
46
import java.io.FileOutputStream;
47
import java.io.ByteArrayOutputStream;
48
49
import sun.tools.java.ClassFile;
50
import sun.tools.java.ClassDefinition;
51
import sun.tools.java.ClassDeclaration;
52
import sun.tools.java.ClassNotFound;
53
import sun.tools.java.Identifier;
54
import sun.tools.java.ClassPath;
55
56
import sun.tools.javac.SourceClass;
57
import sun.tools.util.CommandLine;
58
import java.lang.reflect.Constructor;
59
import java.util.Properties;
60
61
/**
62
* Main "rmic" program.
63
*
64
* WARNING: The contents of this source file are not part of any
65
* supported API. Code that depends on them does so at its own risk:
66
* they are subject to change or removal without notice.
67
*/
68
public class Main implements sun.rmi.rmic.Constants {
69
String sourcePathArg;
70
String sysClassPathArg;
71
String extDirsArg;
72
String classPathString;
73
File destDir;
74
int flags;
75
long tm;
76
Vector<String> classes;
77
boolean nowrite;
78
boolean nocompile;
79
boolean keepGenerated;
80
boolean status;
81
String[] generatorArgs;
82
Vector<Generator> generators;
83
Class<? extends BatchEnvironment> environmentClass =
84
BatchEnvironment.class;
85
boolean iiopGeneration = false;
86
87
/**
88
* Name of the program.
89
*/
90
String program;
91
92
/**
93
* The stream where error message are printed.
94
*/
95
OutputStream out;
96
97
/**
98
* Constructor.
99
*/
100
public Main(OutputStream out, String program) {
101
this.out = out;
102
this.program = program;
103
}
104
105
/**
106
* Output a message.
107
*/
108
public void output(String msg) {
109
PrintStream out =
110
this.out instanceof PrintStream ? (PrintStream)this.out
111
: new PrintStream(this.out, true);
112
out.println(msg);
113
}
114
115
/**
116
* Top level error message. This method is called when the
117
* environment could not be set up yet.
118
*/
119
public void error(String msg) {
120
output(getText(msg));
121
}
122
123
public void error(String msg, String arg1) {
124
output(getText(msg, arg1));
125
}
126
127
public void error(String msg, String arg1, String arg2) {
128
output(getText(msg, arg1, arg2));
129
}
130
131
/**
132
* Usage
133
*/
134
public void usage() {
135
error("rmic.usage", program);
136
}
137
138
/**
139
* Run the compiler
140
*/
141
public synchronized boolean compile(String argv[]) {
142
143
/*
144
* Handle internal option to use the new (and incomplete) rmic
145
* implementation. This option is handled here, rather than
146
* in parseArgs, so that none of the arguments will be nulled
147
* before delegating to the new implementation.
148
*/
149
for (int i = 0; i < argv.length; i++) {
150
if (argv[i].equals("-Xnew")) {
151
return (new sun.rmi.rmic.newrmic.Main(out,
152
program)).compile(argv);
153
}
154
}
155
156
if (!parseArgs(argv)) {
157
return false;
158
}
159
160
if (classes.size() == 0) {
161
usage();
162
return false;
163
}
164
165
if ((flags & F_WARNINGS) != 0) {
166
for (Generator g : generators) {
167
if (g instanceof RMIGenerator) {
168
output(getText("rmic.jrmp.stubs.deprecated", program));
169
break;
170
}
171
}
172
}
173
174
return doCompile();
175
}
176
177
/**
178
* Get the destination directory.
179
*/
180
public File getDestinationDir() {
181
return destDir;
182
}
183
184
/**
185
* Parse the arguments for compile.
186
*/
187
public boolean parseArgs(String argv[]) {
188
sourcePathArg = null;
189
sysClassPathArg = null;
190
extDirsArg = null;
191
192
classPathString = null;
193
destDir = null;
194
flags = F_WARNINGS;
195
tm = System.currentTimeMillis();
196
classes = new Vector<>();
197
nowrite = false;
198
nocompile = false;
199
keepGenerated = false;
200
generatorArgs = getArray("generator.args",true);
201
if (generatorArgs == null) {
202
return false;
203
}
204
generators = new Vector<>();
205
206
// Pre-process command line for @file arguments
207
try {
208
argv = CommandLine.parse(argv);
209
} catch (FileNotFoundException e) {
210
error("rmic.cant.read", e.getMessage());
211
return false;
212
} catch (IOException e) {
213
e.printStackTrace(out instanceof PrintStream ?
214
(PrintStream) out :
215
new PrintStream(out, true));
216
return false;
217
}
218
219
// Parse arguments
220
for (int i = 0 ; i < argv.length ; i++) {
221
if (argv[i] != null) {
222
if (argv[i].equals("-g")) {
223
flags &= ~F_OPT;
224
flags |= F_DEBUG_LINES | F_DEBUG_VARS;
225
argv[i] = null;
226
} else if (argv[i].equals("-O")) {
227
flags &= ~F_DEBUG_LINES;
228
flags &= ~F_DEBUG_VARS;
229
flags |= F_OPT | F_DEPENDENCIES;
230
argv[i] = null;
231
} else if (argv[i].equals("-nowarn")) {
232
flags &= ~F_WARNINGS;
233
argv[i] = null;
234
} else if (argv[i].equals("-debug")) {
235
flags |= F_DUMP;
236
argv[i] = null;
237
} else if (argv[i].equals("-depend")) {
238
flags |= F_DEPENDENCIES;
239
argv[i] = null;
240
} else if (argv[i].equals("-verbose")) {
241
flags |= F_VERBOSE;
242
argv[i] = null;
243
} else if (argv[i].equals("-nowrite")) {
244
nowrite = true;
245
argv[i] = null;
246
} else if (argv[i].equals("-Xnocompile")) {
247
nocompile = true;
248
keepGenerated = true;
249
argv[i] = null;
250
} else if (argv[i].equals("-keep") ||
251
argv[i].equals("-keepgenerated")) {
252
keepGenerated = true;
253
argv[i] = null;
254
} else if (argv[i].equals("-show")) {
255
error("rmic.option.unsupported", "-show");
256
usage();
257
return false;
258
} else if (argv[i].equals("-classpath")) {
259
if ((i + 1) < argv.length) {
260
if (classPathString != null) {
261
error("rmic.option.already.seen", "-classpath");
262
usage();
263
return false;
264
}
265
argv[i] = null;
266
classPathString = argv[++i];
267
argv[i] = null;
268
} else {
269
error("rmic.option.requires.argument", "-classpath");
270
usage();
271
return false;
272
}
273
} else if (argv[i].equals("-sourcepath")) {
274
if ((i + 1) < argv.length) {
275
if (sourcePathArg != null) {
276
error("rmic.option.already.seen", "-sourcepath");
277
usage();
278
return false;
279
}
280
argv[i] = null;
281
sourcePathArg = argv[++i];
282
argv[i] = null;
283
} else {
284
error("rmic.option.requires.argument", "-sourcepath");
285
usage();
286
return false;
287
}
288
} else if (argv[i].equals("-bootclasspath")) {
289
if ((i + 1) < argv.length) {
290
if (sysClassPathArg != null) {
291
error("rmic.option.already.seen", "-bootclasspath");
292
usage();
293
return false;
294
}
295
argv[i] = null;
296
sysClassPathArg = argv[++i];
297
argv[i] = null;
298
} else {
299
error("rmic.option.requires.argument", "-bootclasspath");
300
usage();
301
return false;
302
}
303
} else if (argv[i].equals("-extdirs")) {
304
if ((i + 1) < argv.length) {
305
if (extDirsArg != null) {
306
error("rmic.option.already.seen", "-extdirs");
307
usage();
308
return false;
309
}
310
argv[i] = null;
311
extDirsArg = argv[++i];
312
argv[i] = null;
313
} else {
314
error("rmic.option.requires.argument", "-extdirs");
315
usage();
316
return false;
317
}
318
} else if (argv[i].equals("-d")) {
319
if ((i + 1) < argv.length) {
320
if (destDir != null) {
321
error("rmic.option.already.seen", "-d");
322
usage();
323
return false;
324
}
325
argv[i] = null;
326
destDir = new File(argv[++i]);
327
argv[i] = null;
328
if (!destDir.exists()) {
329
error("rmic.no.such.directory", destDir.getPath());
330
usage();
331
return false;
332
}
333
} else {
334
error("rmic.option.requires.argument", "-d");
335
usage();
336
return false;
337
}
338
} else {
339
if (!checkGeneratorArg(argv,i)) {
340
usage();
341
return false;
342
}
343
}
344
}
345
}
346
347
348
// Now that all generators have had a chance at the args,
349
// scan what's left for classes and illegal args...
350
351
for (int i = 0; i < argv.length; i++) {
352
if (argv[i] != null) {
353
if (argv[i].startsWith("-")) {
354
error("rmic.no.such.option", argv[i]);
355
usage();
356
return false;
357
} else {
358
classes.addElement(argv[i]);
359
}
360
}
361
}
362
363
364
// If the generators vector is empty, add the default generator...
365
366
if (generators.size() == 0) {
367
addGenerator("default");
368
}
369
370
return true;
371
}
372
373
/**
374
* If this argument is for a generator, instantiate it, call
375
* parseArgs(...) and add generator to generators vector.
376
* Returns false on error.
377
*/
378
protected boolean checkGeneratorArg(String[] argv, int currentIndex) {
379
boolean result = true;
380
if (argv[currentIndex].startsWith("-")) {
381
String arg = argv[currentIndex].substring(1).toLowerCase(); // Remove '-'
382
for (int i = 0; i < generatorArgs.length; i++) {
383
if (arg.equalsIgnoreCase(generatorArgs[i])) {
384
// Got a match, add Generator and call parseArgs...
385
Generator gen = addGenerator(arg);
386
if (gen == null) {
387
return false;
388
}
389
result = gen.parseArgs(argv,this);
390
break;
391
}
392
}
393
}
394
return result;
395
}
396
397
/**
398
* Instantiate and add a generator to the generators array.
399
*/
400
protected Generator addGenerator(String arg) {
401
402
Generator gen;
403
404
// Create an instance of the generator and add it to
405
// the array...
406
407
String className = getString("generator.class." + arg);
408
if (className == null) {
409
error("rmic.missing.property",arg);
410
return null;
411
}
412
413
try {
414
gen = (Generator) Class.forName(className).newInstance();
415
} catch (Exception e) {
416
error("rmic.cannot.instantiate",className);
417
return null;
418
}
419
420
generators.addElement(gen);
421
422
// Get the environment required by this generator...
423
424
Class<?> envClass = BatchEnvironment.class;
425
String env = getString("generator.env." + arg);
426
if (env != null) {
427
try {
428
envClass = Class.forName(env);
429
430
// Is the new class a subclass of the current one?
431
432
if (environmentClass.isAssignableFrom(envClass)) {
433
434
// Yes, so switch to the new one...
435
436
environmentClass = envClass.asSubclass(BatchEnvironment.class);
437
438
} else {
439
440
// No. Is the current class a subclass of the
441
// new one?
442
443
if (!envClass.isAssignableFrom(environmentClass)) {
444
445
// No, so it's a conflict...
446
447
error("rmic.cannot.use.both",environmentClass.getName(),envClass.getName());
448
return null;
449
}
450
}
451
} catch (ClassNotFoundException e) {
452
error("rmic.class.not.found",env);
453
return null;
454
}
455
}
456
457
// If this is the iiop stub generator, cache
458
// that fact for the jrmp generator...
459
460
if (arg.equals("iiop")) {
461
iiopGeneration = true;
462
}
463
return gen;
464
}
465
466
/**
467
* Grab a resource string and parse it into an array of strings. Assumes
468
* comma separated list.
469
* @param name The resource name.
470
* @param mustExist If true, throws error if resource does not exist. If
471
* false and resource does not exist, returns zero element array.
472
*/
473
protected String[] getArray(String name, boolean mustExist) {
474
String[] result = null;
475
String value = getString(name);
476
if (value == null) {
477
if (mustExist) {
478
error("rmic.resource.not.found",name);
479
return null;
480
} else {
481
return new String[0];
482
}
483
}
484
485
StringTokenizer parser = new StringTokenizer(value,", \t\n\r", false);
486
int count = parser.countTokens();
487
result = new String[count];
488
for (int i = 0; i < count; i++) {
489
result[i] = parser.nextToken();
490
}
491
492
return result;
493
}
494
495
/**
496
* Get the correct type of BatchEnvironment
497
*/
498
public BatchEnvironment getEnv() {
499
500
ClassPath classPath =
501
BatchEnvironment.createClassPath(classPathString,
502
sysClassPathArg,
503
extDirsArg);
504
BatchEnvironment result = null;
505
try {
506
Class<?>[] ctorArgTypes = {OutputStream.class,ClassPath.class,Main.class};
507
Object[] ctorArgs = {out,classPath,this};
508
Constructor<? extends BatchEnvironment> constructor =
509
environmentClass.getConstructor(ctorArgTypes);
510
result = constructor.newInstance(ctorArgs);
511
result.reset();
512
}
513
catch (Exception e) {
514
error("rmic.cannot.instantiate",environmentClass.getName());
515
}
516
return result;
517
}
518
519
520
/**
521
* Do the compile with the switches and files already supplied
522
*/
523
public boolean doCompile() {
524
// Create batch environment
525
BatchEnvironment env = getEnv();
526
env.flags |= flags;
527
528
// Set the classfile version numbers
529
// Compat and 1.1 stubs must retain the old version number.
530
env.majorVersion = 45;
531
env.minorVersion = 3;
532
533
// Preload the "out of memory" error string just in case we run
534
// out of memory during the compile.
535
String noMemoryErrorString = getText("rmic.no.memory");
536
String stackOverflowErrorString = getText("rmic.stack.overflow");
537
538
try {
539
/** Load the classes on the command line
540
* Replace the entries in classes with the ClassDefinition for the class
541
*/
542
for (int i = classes.size()-1; i >= 0; i-- ) {
543
Identifier implClassName =
544
Identifier.lookup(classes.elementAt(i));
545
546
/*
547
* Fix bugid 4049354: support using '.' as an inner class
548
* qualifier on the command line (previously, only mangled
549
* inner class names were understood, like "pkg.Outer$Inner").
550
*
551
* The following method, also used by "javap", resolves the
552
* given unmangled inner class name to the appropriate
553
* internal identifier. For example, it translates
554
* "pkg.Outer.Inner" to "pkg.Outer. Inner".
555
*/
556
implClassName = env.resolvePackageQualifiedName(implClassName);
557
/*
558
* But if we use such an internal inner class name identifier
559
* to load the class definition, the Java compiler will notice
560
* if the impl class is a "private" inner class and then deny
561
* skeletons (needed unless "-v1.2" is used) the ability to
562
* cast to it. To work around this problem, we mangle inner
563
* class name identifiers to their binary "outer" class name:
564
* "pkg.Outer. Inner" becomes "pkg.Outer$Inner".
565
*/
566
implClassName = Names.mangleClass(implClassName);
567
568
ClassDeclaration decl = env.getClassDeclaration(implClassName);
569
try {
570
ClassDefinition def = decl.getClassDefinition(env);
571
for (int j = 0; j < generators.size(); j++) {
572
Generator gen = generators.elementAt(j);
573
gen.generate(env, def, destDir);
574
}
575
} catch (ClassNotFound ex) {
576
env.error(0, "rmic.class.not.found", implClassName);
577
}
578
579
}
580
581
// compile all classes that need compilation
582
if (!nocompile) {
583
compileAllClasses(env);
584
}
585
} catch (OutOfMemoryError ee) {
586
// The compiler has run out of memory. Use the error string
587
// which we preloaded.
588
env.output(noMemoryErrorString);
589
return false;
590
} catch (StackOverflowError ee) {
591
env.output(stackOverflowErrorString);
592
return false;
593
} catch (Error ee) {
594
// We allow the compiler to take an exception silently if a program
595
// error has previously been detected. Presumably, this makes the
596
// compiler more robust in the face of bad error recovery.
597
if (env.nerrors == 0 || env.dump()) {
598
env.error(0, "fatal.error");
599
ee.printStackTrace(out instanceof PrintStream ?
600
(PrintStream) out :
601
new PrintStream(out, true));
602
}
603
} catch (Exception ee) {
604
if (env.nerrors == 0 || env.dump()) {
605
env.error(0, "fatal.exception");
606
ee.printStackTrace(out instanceof PrintStream ?
607
(PrintStream) out :
608
new PrintStream(out, true));
609
}
610
}
611
612
env.flushErrors();
613
614
boolean status = true;
615
if (env.nerrors > 0) {
616
String msg = "";
617
if (env.nerrors > 1) {
618
msg = getText("rmic.errors", env.nerrors);
619
} else {
620
msg = getText("rmic.1error");
621
}
622
if (env.nwarnings > 0) {
623
if (env.nwarnings > 1) {
624
msg += ", " + getText("rmic.warnings", env.nwarnings);
625
} else {
626
msg += ", " + getText("rmic.1warning");
627
}
628
}
629
output(msg);
630
status = false;
631
} else {
632
if (env.nwarnings > 0) {
633
if (env.nwarnings > 1) {
634
output(getText("rmic.warnings", env.nwarnings));
635
} else {
636
output(getText("rmic.1warning"));
637
}
638
}
639
}
640
641
// last step is to delete generated source files
642
if (!keepGenerated) {
643
env.deleteGeneratedFiles();
644
}
645
646
// We're done
647
if (env.verbose()) {
648
tm = System.currentTimeMillis() - tm;
649
output(getText("rmic.done_in", Long.toString(tm)));
650
}
651
652
// Shutdown the environment object and release our resources.
653
// Note that while this is unneccessary when rmic is invoked
654
// the command line, there are environments in which rmic
655
// from is invoked within a server process, so resource
656
// reclamation is important...
657
658
env.shutdown();
659
660
sourcePathArg = null;
661
sysClassPathArg = null;
662
extDirsArg = null;
663
classPathString = null;
664
destDir = null;
665
classes = null;
666
generatorArgs = null;
667
generators = null;
668
environmentClass = null;
669
program = null;
670
out = null;
671
672
return status;
673
}
674
675
/*
676
* Compile all classes that need to be compiled.
677
*/
678
public void compileAllClasses (BatchEnvironment env)
679
throws ClassNotFound,
680
IOException,
681
InterruptedException {
682
ByteArrayOutputStream buf = new ByteArrayOutputStream(4096);
683
boolean done;
684
685
do {
686
done = true;
687
for (Enumeration<?> e = env.getClasses() ; e.hasMoreElements() ; ) {
688
ClassDeclaration c = (ClassDeclaration)e.nextElement();
689
done = compileClass(c,buf,env);
690
}
691
} while (!done);
692
}
693
694
/*
695
* Compile a single class.
696
* Fallthrough is intentional
697
*/
698
@SuppressWarnings("fallthrough")
699
public boolean compileClass (ClassDeclaration c,
700
ByteArrayOutputStream buf,
701
BatchEnvironment env)
702
throws ClassNotFound,
703
IOException,
704
InterruptedException {
705
boolean done = true;
706
env.flushErrors();
707
SourceClass src;
708
709
switch (c.getStatus()) {
710
case CS_UNDEFINED:
711
{
712
if (!env.dependencies()) {
713
break;
714
}
715
// fall through
716
}
717
718
case CS_SOURCE:
719
{
720
done = false;
721
env.loadDefinition(c);
722
if (c.getStatus() != CS_PARSED) {
723
break;
724
}
725
// fall through
726
}
727
728
case CS_PARSED:
729
{
730
if (c.getClassDefinition().isInsideLocal()) {
731
break;
732
}
733
// If we get to here, then compilation is going
734
// to occur. If the -Xnocompile switch is set
735
// then fail. Note that this check is required
736
// here because this method is called from
737
// generators, not just from within this class...
738
739
if (nocompile) {
740
throw new IOException("Compilation required, but -Xnocompile option in effect");
741
}
742
743
done = false;
744
745
src = (SourceClass)c.getClassDefinition(env);
746
src.check(env);
747
c.setDefinition(src, CS_CHECKED);
748
// fall through
749
}
750
751
case CS_CHECKED:
752
{
753
src = (SourceClass)c.getClassDefinition(env);
754
// bail out if there were any errors
755
if (src.getError()) {
756
c.setDefinition(src, CS_COMPILED);
757
break;
758
}
759
done = false;
760
buf.reset();
761
src.compile(buf);
762
c.setDefinition(src, CS_COMPILED);
763
src.cleanup(env);
764
765
if (src.getError() || nowrite) {
766
break;
767
}
768
769
String pkgName = c.getName().getQualifier().toString().replace('.', File.separatorChar);
770
String className = c.getName().getFlatName().toString().replace('.', SIGC_INNERCLASS) + ".class";
771
772
File file;
773
if (destDir != null) {
774
if (pkgName.length() > 0) {
775
file = new File(destDir, pkgName);
776
if (!file.exists()) {
777
file.mkdirs();
778
}
779
file = new File(file, className);
780
} else {
781
file = new File(destDir, className);
782
}
783
} else {
784
ClassFile classfile = (ClassFile)src.getSource();
785
if (classfile.isZipped()) {
786
env.error(0, "cant.write", classfile.getPath());
787
break;
788
}
789
file = new File(classfile.getPath());
790
file = new File(file.getParent(), className);
791
}
792
793
// Create the file
794
try {
795
FileOutputStream out = new FileOutputStream(file.getPath());
796
buf.writeTo(out);
797
out.close();
798
if (env.verbose()) {
799
output(getText("rmic.wrote", file.getPath()));
800
}
801
} catch (IOException ee) {
802
env.error(0, "cant.write", file.getPath());
803
}
804
}
805
}
806
return done;
807
}
808
809
/**
810
* Main program
811
*/
812
public static void main(String argv[]) {
813
Main compiler = new Main(System.out, "rmic");
814
System.exit(compiler.compile(argv) ? 0 : 1);
815
}
816
817
/**
818
* Return the string value of a named resource in the rmic.properties
819
* resource bundle. If the resource is not found, null is returned.
820
*/
821
public static String getString(String key) {
822
if (!resourcesInitialized) {
823
initResources();
824
}
825
826
// To enable extensions, search the 'resourcesExt'
827
// bundle first, followed by the 'resources' bundle...
828
829
if (resourcesExt != null) {
830
try {
831
return resourcesExt.getString(key);
832
} catch (MissingResourceException e) {}
833
}
834
835
try {
836
return resources.getString(key);
837
} catch (MissingResourceException ignore) {
838
}
839
return null;
840
}
841
842
private static boolean resourcesInitialized = false;
843
private static ResourceBundle resources;
844
private static ResourceBundle resourcesExt = null;
845
846
private static void initResources() {
847
try {
848
resources =
849
ResourceBundle.getBundle("sun.rmi.rmic.resources.rmic");
850
resourcesInitialized = true;
851
try {
852
resourcesExt =
853
ResourceBundle.getBundle("sun.rmi.rmic.resources.rmicext");
854
} catch (MissingResourceException e) {}
855
} catch (MissingResourceException e) {
856
throw new Error("fatal: missing resource bundle: " +
857
e.getClassName());
858
}
859
}
860
861
public static String getText(String key) {
862
String message = getString(key);
863
if (message == null) {
864
message = "no text found: \"" + key + "\"";
865
}
866
return message;
867
}
868
869
public static String getText(String key, int num) {
870
return getText(key, Integer.toString(num), null, null);
871
}
872
873
public static String getText(String key, String arg0) {
874
return getText(key, arg0, null, null);
875
}
876
877
public static String getText(String key, String arg0, String arg1) {
878
return getText(key, arg0, arg1, null);
879
}
880
881
public static String getText(String key,
882
String arg0, String arg1, String arg2)
883
{
884
String format = getString(key);
885
if (format == null) {
886
format = "no text found: key = \"" + key + "\", " +
887
"arguments = \"{0}\", \"{1}\", \"{2}\"";
888
}
889
890
String[] args = new String[3];
891
args[0] = (arg0 != null ? arg0 : "null");
892
args[1] = (arg1 != null ? arg1 : "null");
893
args[2] = (arg2 != null ? arg2 : "null");
894
895
return java.text.MessageFormat.format(format, (Object[]) args);
896
}
897
}
898
899