src/share/classes/sun/applet/AppletViewer.java

Print this page
rev 10175 : 8042872: Fix raw and unchecked warnings in sun.applet
Reviewed-by:


  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.)


 139      */
 140 
 141     PrintStream statusMsgStream;
 142 
 143     /**
 144      * For cloning
 145      */
 146     AppletViewerFactory factory;
 147 
 148 
 149     private final class UserActionListener implements ActionListener {
 150         @Override
 151         public void actionPerformed(ActionEvent evt) {
 152             processUserAction(evt);
 153         }
 154     }
 155 
 156     /**
 157      * Create the applet viewer.
 158      */
 159     public AppletViewer(int x, int y, URL doc, Hashtable atts,
 160                         PrintStream statusMsgStream, AppletViewerFactory factory) {
 161         this.factory = factory;
 162         this.statusMsgStream = statusMsgStream;
 163         setTitle(amh.getMessage("tool.title", atts.get("code")));
 164 
 165         MenuBar mb = factory.getBaseMenuBar();
 166 
 167         Menu m = new Menu(amh.getMessage("menu.applet"));
 168 
 169         addMenuItem(m, "menuitem.restart");
 170         addMenuItem(m, "menuitem.reload");
 171         addMenuItem(m, "menuitem.stop");
 172         addMenuItem(m, "menuitem.save");
 173         addMenuItem(m, "menuitem.start");
 174         addMenuItem(m, "menuitem.clone");
 175         m.add(new MenuItem("-"));
 176         addMenuItem(m, "menuitem.tag");
 177         addMenuItem(m, "menuitem.info");
 178         addMenuItem(m, "menuitem.edit").disable();
 179         addMenuItem(m, "menuitem.encoding");


 333             while (!panel.emptyEventQueue()) ;
 334             appletSystemExit();
 335         }
 336     }
 337 
 338     /**
 339      * Split a string based on the presence of a specified separator.  Returns
 340      * an array of arbitrary length.  The end of each element in the array is
 341      * indicated by the separator of the end of the string.  If there is a
 342      * separator immediately before the end of the string, the final element
 343      * will be empty.  None of the strings will contain the separator.  Useful
 344      * when separating strings such as "foo/bar/bas" using separator "/".
 345      *
 346      * @param sep  The separator.
 347      * @param s    The string to split.
 348      * @return     An array of strings.  Each string in the array is determined
 349      *             by the location of the provided sep in the original string,
 350      *             s.  Whitespace not stripped.
 351      */
 352     private String [] splitSeparator(String sep, String s) {
 353         Vector v = new Vector();
 354         int tokenStart = 0;
 355         int tokenEnd   = 0;
 356 
 357         while ((tokenEnd = s.indexOf(sep, tokenStart)) != -1) {
 358             v.addElement(s.substring(tokenStart, tokenEnd));
 359             tokenStart = tokenEnd+1;
 360         }
 361         // Add the final element.
 362         v.addElement(s.substring(tokenStart));
 363 
 364         String [] retVal = new String[v.size()];
 365         v.copyInto(retVal);
 366         return retVal;
 367     }
 368 
 369     /*
 370      * Methods for java.applet.AppletContext
 371      */
 372 
 373     private static Map audioClips = new HashMap();
 374 
 375     /**
 376      * Get an audio clip.
 377      */
 378     @Override
 379     public AudioClip getAudioClip(URL url) {
 380         checkConnect(url);
 381         synchronized (audioClips) {
 382             AudioClip clip = (AudioClip)audioClips.get(url);
 383             if (clip == null) {
 384                 audioClips.put(url, clip = new AppletAudioClip(url));
 385             }
 386             return clip;
 387         }
 388     }
 389 
 390     private static Map imageRefs = new HashMap();
 391 
 392     /**
 393      * Get an image.
 394      */
 395     @Override
 396     public Image getImage(URL url) {
 397         return getCachedImage(url);
 398     }
 399 
 400     /**
 401      * Get an image.
 402      */
 403     static Image getCachedImage(URL url) {
 404         // System.getSecurityManager().checkConnection(url.getHost(), url.getPort());
 405         synchronized (imageRefs) {
 406             AppletImageRef ref = (AppletImageRef)imageRefs.get(url);
 407             if (ref == null) {
 408                 ref = new AppletImageRef(url);
 409                 imageRefs.put(url, ref);
 410             }
 411             return ref.get();
 412         }
 413     }
 414 
 415     /**
 416      * Flush the image cache.
 417      */
 418     static void flushImageCache() {
 419         imageRefs.clear();
 420     }
 421 
 422     static Vector appletPanels = new Vector();
 423 
 424     /**
 425      * Get an applet by name.
 426      */
 427     @Override
 428     public Applet getApplet(String name) {
 429         AppletSecurity security = (AppletSecurity)System.getSecurityManager();
 430         name = name.toLowerCase();
 431         SocketPermission panelSp =
 432             new SocketPermission(panel.getCodeBase().getHost(), "connect");
 433         for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) {
 434             AppletPanel p = (AppletPanel)e.nextElement();
 435             String param = p.getParameter("name");
 436             if (param != null) {
 437                 param = param.toLowerCase();
 438             }
 439             if (name.equals(param) &&
 440                 p.getDocumentBase().equals(panel.getDocumentBase())) {
 441 
 442                 SocketPermission sp =
 443                     new SocketPermission(p.getCodeBase().getHost(), "connect");
 444 
 445                 if (panelSp.implies(sp)) {
 446                     return p.applet;
 447                 }
 448             }
 449         }
 450         return null;
 451     }
 452 
 453     /**
 454      * Return an enumeration of all the accessible
 455      * applets on this page.
 456      */
 457     @Override
 458     public Enumeration getApplets() {
 459         AppletSecurity security = (AppletSecurity)System.getSecurityManager();
 460         Vector v = new Vector();
 461         SocketPermission panelSp =
 462             new SocketPermission(panel.getCodeBase().getHost(), "connect");
 463 
 464         for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) {
 465             AppletPanel p = (AppletPanel)e.nextElement();
 466             if (p.getDocumentBase().equals(panel.getDocumentBase())) {
 467 
 468                 SocketPermission sp =
 469                     new SocketPermission(p.getCodeBase().getHost(), "connect");
 470                 if (panelSp.implies(sp)) {
 471                     v.addElement(p.applet);
 472                 }
 473             }
 474         }
 475         return v.elements();
 476     }
 477 
 478     /**
 479      * Ignore.
 480      */
 481     @Override
 482     public void showDocument(URL url) {
 483     }
 484 
 485     /**


 492     /**
 493      * Show status.
 494      */
 495     @Override
 496     public void showStatus(String status) {
 497         label.setText(status);
 498     }
 499 
 500     @Override
 501     public void setStream(String key, InputStream stream)throws IOException{
 502         // We do nothing.
 503     }
 504 
 505     @Override
 506     public InputStream getStream(String key){
 507         // We do nothing.
 508         return null;
 509     }
 510 
 511     @Override
 512     public Iterator getStreamKeys(){
 513         // We do nothing.
 514         return null;
 515     }
 516 
 517     /**
 518      * System parameters.
 519      */
 520     static Hashtable systemParam = new Hashtable();
 521 
 522     static {
 523         systemParam.put("codebase", "codebase");
 524         systemParam.put("code", "code");
 525         systemParam.put("alt", "alt");
 526         systemParam.put("width", "width");
 527         systemParam.put("height", "height");
 528         systemParam.put("align", "align");
 529         systemParam.put("vspace", "vspace");
 530         systemParam.put("hspace", "hspace");
 531     }
 532 
 533     /**
 534      * Print the HTML tag.
 535      */
 536     public static void printTag(PrintStream out, Hashtable atts) {
 537         out.print("<applet");
 538 
 539         String v = (String)atts.get("codebase");
 540         if (v != null) {
 541             out.print(" codebase=\"" + v + "\"");
 542         }
 543 
 544         v = (String)atts.get("code");
 545         if (v == null) {
 546             v = "applet.class";
 547         }
 548         out.print(" code=\"" + v + "\"");
 549         v = (String)atts.get("width");
 550         if (v == null) {
 551             v = "150";
 552         }
 553         out.print(" width=" + v);
 554 
 555         v = (String)atts.get("height");
 556         if (v == null) {
 557             v = "100";
 558         }
 559         out.print(" height=" + v);
 560 
 561         v = (String)atts.get("name");
 562         if (v != null) {
 563             out.print(" name=\"" + v + "\"");
 564         }
 565         out.println(">");
 566 
 567         // A very slow sorting algorithm
 568         int len = atts.size();
 569         String params[] = new String[len];
 570         len = 0;
 571         for (Enumeration e = atts.keys() ; e.hasMoreElements() ;) {
 572             String param = (String)e.nextElement();
 573             int i = 0;
 574             for (; i < len ; i++) {
 575                 if (params[i].compareTo(param) >= 0) {
 576                     break;
 577                 }
 578             }
 579             System.arraycopy(params, i, params, i + 1, len - i);
 580             params[i] = param;
 581             len++;
 582         }
 583 
 584         for (int i = 0 ; i < len ; i++) {
 585             String param = params[i];
 586             if (systemParam.get(param) == null) {
 587                 out.println("<param name=" + param +
 588                             " value=\"" + atts.get(param) + "\">");
 589             }
 590         }
 591         out.println("</applet>");
 592     }


 632          * Make sure we don't have two threads running through the event queue
 633          * at the same time.
 634          */
 635         try {
 636             panel.joinAppletThread();
 637             panel.release();
 638         } catch (InterruptedException e) {
 639             return;   // abort the reload
 640         }
 641 
 642         panel.createAppletThread();
 643         panel.sendEvent(AppletPanel.APPLET_LOAD);
 644         panel.sendEvent(AppletPanel.APPLET_INIT);
 645         panel.sendEvent(AppletPanel.APPLET_START);
 646     }
 647 
 648     /**
 649      * Save the applet to a well known file (for now) as a serialized object
 650      */
 651     void appletSave() {
 652         AccessController.doPrivileged(new PrivilegedAction() {
 653 
 654             @Override
 655             public Object run() {
 656                 // XXX: this privileged block should be made smaller
 657                 // by initializing a private static variable with "user.dir"
 658 
 659                 // Applet needs to be stopped for serialization to succeed.
 660                 // Since panel.sendEvent only queues the event, there is a
 661                 // chance that the event will not be processed before
 662                 // serialization begins.  However, by sending the event before
 663                 // FileDialog is created, enough time is given such that this
 664                 // situation is unlikely to ever occur.
 665 
 666                 panel.sendEvent(AppletPanel.APPLET_STOP);
 667                 FileDialog fd = new FileDialog(AppletViewer.this,
 668                                                amh.getMessage("appletsave.filedialogtitle"),
 669                                                FileDialog.SAVE);
 670                 // needed for a bug under Solaris...
 671                 fd.setDirectory(System.getProperty("user.dir"));
 672                 fd.setFile(defaultSaveFile);


 685                      ObjectOutputStream os = new ObjectOutputStream(bos)) {
 686 
 687                     showStatus(amh.getMessage("appletsave.err1", panel.applet.toString(), file.toString()));
 688                     os.writeObject(panel.applet);
 689                 } catch (IOException ex) {
 690                     System.err.println(amh.getMessage("appletsave.err2", ex));
 691                 } finally {
 692                     panel.sendEvent(AppletPanel.APPLET_START);
 693                 }
 694                 return null;
 695             }
 696         });
 697     }
 698 
 699     /**
 700      * Clone the viewer and the applet.
 701      */
 702     void appletClone() {
 703         Point p = location();
 704         updateAtts();


 705         factory.createAppletViewer(p.x + XDELTA, p.y + YDELTA,
 706                                    panel.documentURL, (Hashtable)panel.atts.clone());
 707     }
 708 
 709     /**
 710      * Show the applet tag.
 711      */
 712     void appletTag() {
 713         ByteArrayOutputStream out = new ByteArrayOutputStream();
 714         updateAtts();
 715         printTag(new PrintStream(out), panel.atts);
 716         showStatus(amh.getMessage("applettag"));
 717 
 718         Point p = location();
 719         new TextFrame(p.x + XDELTA, p.y + YDELTA, amh.getMessage("applettag.textframe"), out.toString());
 720     }
 721 
 722     /**
 723      * Show the applet info.
 724      */
 725     void appletInfo() {
 726         String str = panel.applet.getAppletInfo();


 867         if (factory.isStandalone())
 868             System.exit(0);
 869     }
 870 
 871     /**
 872      * Quit all viewers.
 873      * Shutdown all viewers properly then
 874      * exit from the program (if not stand alone)
 875      */
 876     protected void appletQuit()
 877     {
 878         // The caller thread is event dispatch thread, so
 879         // spawn a new thread to avoid blocking the event queue
 880         // when calling appletShutdown.
 881         //
 882         new Thread(new Runnable()
 883         {
 884             @Override
 885             public void run()
 886             {
 887                 for (Enumeration e = appletPanels.elements() ; e.hasMoreElements() ;) {
 888                     AppletPanel p = (AppletPanel)e.nextElement();
 889                     appletShutdown(p);
 890                 }
 891                 appletSystemExit();
 892             }
 893         }).start();
 894     }
 895 
 896     /**
 897      * Handle events.
 898      */
 899     public void processUserAction(ActionEvent evt) {
 900 
 901         String label = ((MenuItem)evt.getSource()).getLabel();
 902 
 903         if (amh.getMessage("menuitem.restart").equals(label)) {
 904             appletRestart();
 905             return;
 906         }
 907 
 908         if (amh.getMessage("menuitem.reload").equals(label)) {


 999     /**
1000      * Scan identifier
1001      */
1002     public static String scanIdentifier(Reader in) throws IOException {
1003         StringBuilder sb = new StringBuilder();
1004         while (true) {
1005             if (((c >= 'a') && (c <= 'z')) ||
1006                 ((c >= 'A') && (c <= 'Z')) ||
1007                 ((c >= '0') && (c <= '9')) || (c == '_')) {
1008                 sb.append((char) c);
1009                 c = in.read();
1010             } else {
1011                 return sb.toString();
1012             }
1013         }
1014     }
1015 
1016     /**
1017      * Scan tag
1018      */
1019     public static Hashtable scanTag(Reader in) throws IOException {
1020         Hashtable atts = new Hashtable();
1021         skipSpace(in);
1022         while (c >= 0 && c != '>') {
1023             String att = scanIdentifier(in);
1024             String val = "";
1025             skipSpace(in);
1026             if (c == '=') {
1027                 int quote = -1;
1028                 c = in.read();
1029                 skipSpace(in);
1030                 if ((c == '\'') || (c == '\"')) {
1031                     quote = c;
1032                     c = in.read();
1033                 }
1034                 StringBuilder sb = new StringBuilder();
1035                 while ((c > 0) &&
1036                        (((quote < 0) && (c != ' ') && (c != '\t') &&
1037                          (c != '\n') && (c != '\r') && (c != '>'))
1038                         || ((quote >= 0) && (c != quote)))) {
1039                     sb.append((char) c);
1040                     c = in.read();


1105         String paramOutsideWarning = amh.getMessage("parse.warning.paramoutside");
1106         String appletRequiresCodeWarning = amh.getMessage("parse.warning.applet.requirescode");
1107         String appletRequiresHeightWarning = amh.getMessage("parse.warning.applet.requiresheight");
1108         String appletRequiresWidthWarning = amh.getMessage("parse.warning.applet.requireswidth");
1109         String objectRequiresCodeWarning = amh.getMessage("parse.warning.object.requirescode");
1110         String objectRequiresHeightWarning = amh.getMessage("parse.warning.object.requiresheight");
1111         String objectRequiresWidthWarning = amh.getMessage("parse.warning.object.requireswidth");
1112         String embedRequiresCodeWarning = amh.getMessage("parse.warning.embed.requirescode");
1113         String embedRequiresHeightWarning = amh.getMessage("parse.warning.embed.requiresheight");
1114         String embedRequiresWidthWarning = amh.getMessage("parse.warning.embed.requireswidth");
1115         String appNotLongerSupportedWarning = amh.getMessage("parse.warning.appnotLongersupported");
1116 
1117         java.net.URLConnection conn = url.openConnection();
1118         Reader in = makeReader(conn.getInputStream());
1119         /* The original URL may have been redirected - this
1120          * sets it to whatever URL/codebase we ended up getting
1121          */
1122         url = conn.getURL();
1123 
1124         int ydisp = 1;
1125         Hashtable atts = null;
1126 
1127         while(true) {
1128             c = in.read();
1129             if (c == -1)
1130                 break;
1131 
1132             if (c == '<') {
1133                 c = in.read();
1134                 if (c == '/') {
1135                     c = in.read();
1136                     String nm = scanIdentifier(in);
1137                     if (nm.equalsIgnoreCase("applet") ||
1138                         nm.equalsIgnoreCase("object") ||
1139                         nm.equalsIgnoreCase("embed")) {
1140 
1141                         // We can't test for a code tag until </OBJECT>
1142                         // because it is a parameter, not an attribute.
1143                         if(isObjectTag) {
1144                             if (atts.get("code") == null && atts.get("object") == null) {
1145                                 statusMsgStream.println(objectRequiresCodeWarning);


1155                             factory.createAppletViewer(x, y, url, atts);
1156                             x += XDELTA;
1157                             y += YDELTA;
1158                             // make sure we don't go too far!
1159                             Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
1160                             if ((x > d.width - 300) || (y > d.height - 300)) {
1161                                 x = 0;
1162                                 y = 2 * ydisp * YDELTA;
1163                                 ydisp++;
1164                             }
1165                         }
1166                         atts = null;
1167                         isAppletTag = false;
1168                         isObjectTag = false;
1169                         isEmbedTag = false;
1170                     }
1171                 }
1172                 else {
1173                     String nm = scanIdentifier(in);
1174                     if (nm.equalsIgnoreCase("param")) {
1175                         Hashtable t = scanTag(in);
1176                         String att = (String)t.get("name");
1177                         if (att == null) {
1178                             statusMsgStream.println(requiresNameWarning);
1179                         } else {
1180                             String val = (String)t.get("value");
1181                             if (val == null) {
1182                                 statusMsgStream.println(requiresNameWarning);
1183                             } else if (atts != null) {
1184                                 atts.put(att.toLowerCase(), val);
1185                             } else {
1186                                 statusMsgStream.println(paramOutsideWarning);
1187                             }
1188                         }
1189                     }
1190                     else if (nm.equalsIgnoreCase("applet")) {
1191                         isAppletTag = true;
1192                         atts = scanTag(in);
1193                         if (atts.get("code") == null && atts.get("object") == null) {
1194                             statusMsgStream.println(appletRequiresCodeWarning);
1195                             atts = null;
1196                         } else if (atts.get("width") == null) {
1197                             statusMsgStream.println(appletRequiresWidthWarning);
1198                             atts = null;
1199                         } else if (atts.get("height") == null) {
1200                             statusMsgStream.println(appletRequiresHeightWarning);


1218                             atts = null;
1219                         }
1220                     }
1221                     else if (nm.equalsIgnoreCase("embed")) {
1222                         isEmbedTag = true;
1223                         atts = scanTag(in);
1224 
1225                         if (atts.get("code") == null && atts.get("object") == null) {
1226                             statusMsgStream.println(embedRequiresCodeWarning);
1227                             atts = null;
1228                         } else if (atts.get("width") == null) {
1229                             statusMsgStream.println(embedRequiresWidthWarning);
1230                             atts = null;
1231                         } else if (atts.get("height") == null) {
1232                             statusMsgStream.println(embedRequiresHeightWarning);
1233                             atts = null;
1234                         }
1235                     }
1236                     else if (nm.equalsIgnoreCase("app")) {
1237                         statusMsgStream.println(appNotLongerSupportedWarning);
1238                         Hashtable atts2 = scanTag(in);
1239                         nm = (String)atts2.get("class");
1240                         if (nm != null) {
1241                             atts2.remove("class");
1242                             atts2.put("code", nm + ".class");
1243                         }
1244                         nm = (String)atts2.get("src");
1245                         if (nm != null) {
1246                             atts2.remove("src");
1247                             atts2.put("codebase", nm);
1248                         }
1249                         if (atts2.get("width") == null) {
1250                             atts2.put("width", "100");
1251                         }
1252                         if (atts2.get("height") == null) {
1253                             atts2.put("height", "100");
1254                         }
1255                         printTag(statusMsgStream, atts2);
1256                         statusMsgStream.println();
1257                     }
1258                 }
1259             }
1260         }
1261         in.close();
1262     }
1263 
1264     /**




  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<String, String> 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.)


 139      */
 140 
 141     PrintStream statusMsgStream;
 142 
 143     /**
 144      * For cloning
 145      */
 146     AppletViewerFactory factory;
 147 
 148 
 149     private final class UserActionListener implements ActionListener {
 150         @Override
 151         public void actionPerformed(ActionEvent evt) {
 152             processUserAction(evt);
 153         }
 154     }
 155 
 156     /**
 157      * Create the applet viewer.
 158      */
 159     public AppletViewer(int x, int y, URL doc, Hashtable<String, String> atts,
 160                         PrintStream statusMsgStream, AppletViewerFactory factory) {
 161         this.factory = factory;
 162         this.statusMsgStream = statusMsgStream;
 163         setTitle(amh.getMessage("tool.title", atts.get("code")));
 164 
 165         MenuBar mb = factory.getBaseMenuBar();
 166 
 167         Menu m = new Menu(amh.getMessage("menu.applet"));
 168 
 169         addMenuItem(m, "menuitem.restart");
 170         addMenuItem(m, "menuitem.reload");
 171         addMenuItem(m, "menuitem.stop");
 172         addMenuItem(m, "menuitem.save");
 173         addMenuItem(m, "menuitem.start");
 174         addMenuItem(m, "menuitem.clone");
 175         m.add(new MenuItem("-"));
 176         addMenuItem(m, "menuitem.tag");
 177         addMenuItem(m, "menuitem.info");
 178         addMenuItem(m, "menuitem.edit").disable();
 179         addMenuItem(m, "menuitem.encoding");


 333             while (!panel.emptyEventQueue()) ;
 334             appletSystemExit();
 335         }
 336     }
 337 
 338     /**
 339      * Split a string based on the presence of a specified separator.  Returns
 340      * an array of arbitrary length.  The end of each element in the array is
 341      * indicated by the separator of the end of the string.  If there is a
 342      * separator immediately before the end of the string, the final element
 343      * will be empty.  None of the strings will contain the separator.  Useful
 344      * when separating strings such as "foo/bar/bas" using separator "/".
 345      *
 346      * @param sep  The separator.
 347      * @param s    The string to split.
 348      * @return     An array of strings.  Each string in the array is determined
 349      *             by the location of the provided sep in the original string,
 350      *             s.  Whitespace not stripped.
 351      */
 352     private String [] splitSeparator(String sep, String s) {
 353         Vector<String> v = new Vector<>();
 354         int tokenStart = 0;
 355         int tokenEnd   = 0;
 356 
 357         while ((tokenEnd = s.indexOf(sep, tokenStart)) != -1) {
 358             v.addElement(s.substring(tokenStart, tokenEnd));
 359             tokenStart = tokenEnd+1;
 360         }
 361         // Add the final element.
 362         v.addElement(s.substring(tokenStart));
 363 
 364         String [] retVal = new String[v.size()];
 365         v.copyInto(retVal);
 366         return retVal;
 367     }
 368 
 369     /*
 370      * Methods for java.applet.AppletContext
 371      */
 372 
 373     private static Map<URL, AudioClip> audioClips = new HashMap<>();
 374 
 375     /**
 376      * Get an audio clip.
 377      */
 378     @Override
 379     public AudioClip getAudioClip(URL url) {
 380         checkConnect(url);
 381         synchronized (audioClips) {
 382             AudioClip clip = audioClips.get(url);
 383             if (clip == null) {
 384                 audioClips.put(url, clip = new AppletAudioClip(url));
 385             }
 386             return clip;
 387         }
 388     }
 389 
 390     private static Map<URL, AppletImageRef> imageRefs = new HashMap<>();
 391 
 392     /**
 393      * Get an image.
 394      */
 395     @Override
 396     public Image getImage(URL url) {
 397         return getCachedImage(url);
 398     }
 399 
 400     /**
 401      * Get an image.
 402      */
 403     static Image getCachedImage(URL url) {
 404         // System.getSecurityManager().checkConnection(url.getHost(), url.getPort());
 405         synchronized (imageRefs) {
 406             AppletImageRef ref = imageRefs.get(url);
 407             if (ref == null) {
 408                 ref = new AppletImageRef(url);
 409                 imageRefs.put(url, ref);
 410             }
 411             return ref.get();
 412         }
 413     }
 414 
 415     /**
 416      * Flush the image cache.
 417      */
 418     static void flushImageCache() {
 419         imageRefs.clear();
 420     }
 421 
 422     static Vector<AppletPanel> appletPanels = new Vector<>();
 423 
 424     /**
 425      * Get an applet by name.
 426      */
 427     @Override
 428     public Applet getApplet(String name) {
 429         AppletSecurity security = (AppletSecurity)System.getSecurityManager();
 430         name = name.toLowerCase();
 431         SocketPermission panelSp =
 432             new SocketPermission(panel.getCodeBase().getHost(), "connect");
 433         for (Enumeration<AppletPanel> e = appletPanels.elements() ; e.hasMoreElements() ;) {
 434             AppletPanel p = e.nextElement();
 435             String param = p.getParameter("name");
 436             if (param != null) {
 437                 param = param.toLowerCase();
 438             }
 439             if (name.equals(param) &&
 440                 p.getDocumentBase().equals(panel.getDocumentBase())) {
 441 
 442                 SocketPermission sp =
 443                     new SocketPermission(p.getCodeBase().getHost(), "connect");
 444 
 445                 if (panelSp.implies(sp)) {
 446                     return p.applet;
 447                 }
 448             }
 449         }
 450         return null;
 451     }
 452 
 453     /**
 454      * Return an enumeration of all the accessible
 455      * applets on this page.
 456      */
 457     @Override
 458     public Enumeration<Applet> getApplets() {
 459         AppletSecurity security = (AppletSecurity)System.getSecurityManager();
 460         Vector<Applet> v = new Vector<>();
 461         SocketPermission panelSp =
 462             new SocketPermission(panel.getCodeBase().getHost(), "connect");
 463 
 464         for (Enumeration<AppletPanel> e = appletPanels.elements() ; e.hasMoreElements() ;) {
 465             AppletPanel p = e.nextElement();
 466             if (p.getDocumentBase().equals(panel.getDocumentBase())) {
 467 
 468                 SocketPermission sp =
 469                     new SocketPermission(p.getCodeBase().getHost(), "connect");
 470                 if (panelSp.implies(sp)) {
 471                     v.addElement(p.applet);
 472                 }
 473             }
 474         }
 475         return v.elements();
 476     }
 477 
 478     /**
 479      * Ignore.
 480      */
 481     @Override
 482     public void showDocument(URL url) {
 483     }
 484 
 485     /**


 492     /**
 493      * Show status.
 494      */
 495     @Override
 496     public void showStatus(String status) {
 497         label.setText(status);
 498     }
 499 
 500     @Override
 501     public void setStream(String key, InputStream stream)throws IOException{
 502         // We do nothing.
 503     }
 504 
 505     @Override
 506     public InputStream getStream(String key){
 507         // We do nothing.
 508         return null;
 509     }
 510 
 511     @Override
 512     public Iterator<String> getStreamKeys(){
 513         // We do nothing.
 514         return null;
 515     }
 516 
 517     /**
 518      * System parameters.
 519      */
 520     static Hashtable<String, String> systemParam = new Hashtable<>();
 521 
 522     static {
 523         systemParam.put("codebase", "codebase");
 524         systemParam.put("code", "code");
 525         systemParam.put("alt", "alt");
 526         systemParam.put("width", "width");
 527         systemParam.put("height", "height");
 528         systemParam.put("align", "align");
 529         systemParam.put("vspace", "vspace");
 530         systemParam.put("hspace", "hspace");
 531     }
 532 
 533     /**
 534      * Print the HTML tag.
 535      */
 536     public static void printTag(PrintStream out, Hashtable<String, String> atts) {
 537         out.print("<applet");
 538 
 539         String v = atts.get("codebase");
 540         if (v != null) {
 541             out.print(" codebase=\"" + v + "\"");
 542         }
 543 
 544         v = atts.get("code");
 545         if (v == null) {
 546             v = "applet.class";
 547         }
 548         out.print(" code=\"" + v + "\"");
 549         v = atts.get("width");
 550         if (v == null) {
 551             v = "150";
 552         }
 553         out.print(" width=" + v);
 554 
 555         v = atts.get("height");
 556         if (v == null) {
 557             v = "100";
 558         }
 559         out.print(" height=" + v);
 560 
 561         v = atts.get("name");
 562         if (v != null) {
 563             out.print(" name=\"" + v + "\"");
 564         }
 565         out.println(">");
 566 
 567         // A very slow sorting algorithm
 568         int len = atts.size();
 569         String params[] = new String[len];
 570         len = 0;
 571         for (Enumeration<String> e = atts.keys() ; e.hasMoreElements() ;) {
 572             String param = e.nextElement();
 573             int i = 0;
 574             for (; i < len ; i++) {
 575                 if (params[i].compareTo(param) >= 0) {
 576                     break;
 577                 }
 578             }
 579             System.arraycopy(params, i, params, i + 1, len - i);
 580             params[i] = param;
 581             len++;
 582         }
 583 
 584         for (int i = 0 ; i < len ; i++) {
 585             String param = params[i];
 586             if (systemParam.get(param) == null) {
 587                 out.println("<param name=" + param +
 588                             " value=\"" + atts.get(param) + "\">");
 589             }
 590         }
 591         out.println("</applet>");
 592     }


 632          * Make sure we don't have two threads running through the event queue
 633          * at the same time.
 634          */
 635         try {
 636             panel.joinAppletThread();
 637             panel.release();
 638         } catch (InterruptedException e) {
 639             return;   // abort the reload
 640         }
 641 
 642         panel.createAppletThread();
 643         panel.sendEvent(AppletPanel.APPLET_LOAD);
 644         panel.sendEvent(AppletPanel.APPLET_INIT);
 645         panel.sendEvent(AppletPanel.APPLET_START);
 646     }
 647 
 648     /**
 649      * Save the applet to a well known file (for now) as a serialized object
 650      */
 651     void appletSave() {
 652         AccessController.doPrivileged(new PrivilegedAction<Object>() {
 653 
 654             @Override
 655             public Object run() {
 656                 // XXX: this privileged block should be made smaller
 657                 // by initializing a private static variable with "user.dir"
 658 
 659                 // Applet needs to be stopped for serialization to succeed.
 660                 // Since panel.sendEvent only queues the event, there is a
 661                 // chance that the event will not be processed before
 662                 // serialization begins.  However, by sending the event before
 663                 // FileDialog is created, enough time is given such that this
 664                 // situation is unlikely to ever occur.
 665 
 666                 panel.sendEvent(AppletPanel.APPLET_STOP);
 667                 FileDialog fd = new FileDialog(AppletViewer.this,
 668                                                amh.getMessage("appletsave.filedialogtitle"),
 669                                                FileDialog.SAVE);
 670                 // needed for a bug under Solaris...
 671                 fd.setDirectory(System.getProperty("user.dir"));
 672                 fd.setFile(defaultSaveFile);


 685                      ObjectOutputStream os = new ObjectOutputStream(bos)) {
 686 
 687                     showStatus(amh.getMessage("appletsave.err1", panel.applet.toString(), file.toString()));
 688                     os.writeObject(panel.applet);
 689                 } catch (IOException ex) {
 690                     System.err.println(amh.getMessage("appletsave.err2", ex));
 691                 } finally {
 692                     panel.sendEvent(AppletPanel.APPLET_START);
 693                 }
 694                 return null;
 695             }
 696         });
 697     }
 698 
 699     /**
 700      * Clone the viewer and the applet.
 701      */
 702     void appletClone() {
 703         Point p = location();
 704         updateAtts();
 705         @SuppressWarnings("unchecked")
 706         Hashtable<String, String> tmp = (Hashtable<String, String>) panel.atts.clone();
 707         factory.createAppletViewer(p.x + XDELTA, p.y + YDELTA,
 708                                    panel.documentURL, tmp);
 709     }
 710 
 711     /**
 712      * Show the applet tag.
 713      */
 714     void appletTag() {
 715         ByteArrayOutputStream out = new ByteArrayOutputStream();
 716         updateAtts();
 717         printTag(new PrintStream(out), panel.atts);
 718         showStatus(amh.getMessage("applettag"));
 719 
 720         Point p = location();
 721         new TextFrame(p.x + XDELTA, p.y + YDELTA, amh.getMessage("applettag.textframe"), out.toString());
 722     }
 723 
 724     /**
 725      * Show the applet info.
 726      */
 727     void appletInfo() {
 728         String str = panel.applet.getAppletInfo();


 869         if (factory.isStandalone())
 870             System.exit(0);
 871     }
 872 
 873     /**
 874      * Quit all viewers.
 875      * Shutdown all viewers properly then
 876      * exit from the program (if not stand alone)
 877      */
 878     protected void appletQuit()
 879     {
 880         // The caller thread is event dispatch thread, so
 881         // spawn a new thread to avoid blocking the event queue
 882         // when calling appletShutdown.
 883         //
 884         new Thread(new Runnable()
 885         {
 886             @Override
 887             public void run()
 888             {
 889                 for (Enumeration<AppletPanel> e = appletPanels.elements() ; e.hasMoreElements() ;) {
 890                     AppletPanel p = e.nextElement();
 891                     appletShutdown(p);
 892                 }
 893                 appletSystemExit();
 894             }
 895         }).start();
 896     }
 897 
 898     /**
 899      * Handle events.
 900      */
 901     public void processUserAction(ActionEvent evt) {
 902 
 903         String label = ((MenuItem)evt.getSource()).getLabel();
 904 
 905         if (amh.getMessage("menuitem.restart").equals(label)) {
 906             appletRestart();
 907             return;
 908         }
 909 
 910         if (amh.getMessage("menuitem.reload").equals(label)) {


1001     /**
1002      * Scan identifier
1003      */
1004     public static String scanIdentifier(Reader in) throws IOException {
1005         StringBuilder sb = new StringBuilder();
1006         while (true) {
1007             if (((c >= 'a') && (c <= 'z')) ||
1008                 ((c >= 'A') && (c <= 'Z')) ||
1009                 ((c >= '0') && (c <= '9')) || (c == '_')) {
1010                 sb.append((char) c);
1011                 c = in.read();
1012             } else {
1013                 return sb.toString();
1014             }
1015         }
1016     }
1017 
1018     /**
1019      * Scan tag
1020      */
1021     public static Hashtable<String, String> scanTag(Reader in) throws IOException {
1022         Hashtable<String, String> atts = new Hashtable<>();
1023         skipSpace(in);
1024         while (c >= 0 && c != '>') {
1025             String att = scanIdentifier(in);
1026             String val = "";
1027             skipSpace(in);
1028             if (c == '=') {
1029                 int quote = -1;
1030                 c = in.read();
1031                 skipSpace(in);
1032                 if ((c == '\'') || (c == '\"')) {
1033                     quote = c;
1034                     c = in.read();
1035                 }
1036                 StringBuilder sb = new StringBuilder();
1037                 while ((c > 0) &&
1038                        (((quote < 0) && (c != ' ') && (c != '\t') &&
1039                          (c != '\n') && (c != '\r') && (c != '>'))
1040                         || ((quote >= 0) && (c != quote)))) {
1041                     sb.append((char) c);
1042                     c = in.read();


1107         String paramOutsideWarning = amh.getMessage("parse.warning.paramoutside");
1108         String appletRequiresCodeWarning = amh.getMessage("parse.warning.applet.requirescode");
1109         String appletRequiresHeightWarning = amh.getMessage("parse.warning.applet.requiresheight");
1110         String appletRequiresWidthWarning = amh.getMessage("parse.warning.applet.requireswidth");
1111         String objectRequiresCodeWarning = amh.getMessage("parse.warning.object.requirescode");
1112         String objectRequiresHeightWarning = amh.getMessage("parse.warning.object.requiresheight");
1113         String objectRequiresWidthWarning = amh.getMessage("parse.warning.object.requireswidth");
1114         String embedRequiresCodeWarning = amh.getMessage("parse.warning.embed.requirescode");
1115         String embedRequiresHeightWarning = amh.getMessage("parse.warning.embed.requiresheight");
1116         String embedRequiresWidthWarning = amh.getMessage("parse.warning.embed.requireswidth");
1117         String appNotLongerSupportedWarning = amh.getMessage("parse.warning.appnotLongersupported");
1118 
1119         java.net.URLConnection conn = url.openConnection();
1120         Reader in = makeReader(conn.getInputStream());
1121         /* The original URL may have been redirected - this
1122          * sets it to whatever URL/codebase we ended up getting
1123          */
1124         url = conn.getURL();
1125 
1126         int ydisp = 1;
1127         Hashtable<String, String> atts = null;
1128 
1129         while(true) {
1130             c = in.read();
1131             if (c == -1)
1132                 break;
1133 
1134             if (c == '<') {
1135                 c = in.read();
1136                 if (c == '/') {
1137                     c = in.read();
1138                     String nm = scanIdentifier(in);
1139                     if (nm.equalsIgnoreCase("applet") ||
1140                         nm.equalsIgnoreCase("object") ||
1141                         nm.equalsIgnoreCase("embed")) {
1142 
1143                         // We can't test for a code tag until </OBJECT>
1144                         // because it is a parameter, not an attribute.
1145                         if(isObjectTag) {
1146                             if (atts.get("code") == null && atts.get("object") == null) {
1147                                 statusMsgStream.println(objectRequiresCodeWarning);


1157                             factory.createAppletViewer(x, y, url, atts);
1158                             x += XDELTA;
1159                             y += YDELTA;
1160                             // make sure we don't go too far!
1161                             Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
1162                             if ((x > d.width - 300) || (y > d.height - 300)) {
1163                                 x = 0;
1164                                 y = 2 * ydisp * YDELTA;
1165                                 ydisp++;
1166                             }
1167                         }
1168                         atts = null;
1169                         isAppletTag = false;
1170                         isObjectTag = false;
1171                         isEmbedTag = false;
1172                     }
1173                 }
1174                 else {
1175                     String nm = scanIdentifier(in);
1176                     if (nm.equalsIgnoreCase("param")) {
1177                         Hashtable<String, String> t = scanTag(in);
1178                         String att = t.get("name");
1179                         if (att == null) {
1180                             statusMsgStream.println(requiresNameWarning);
1181                         } else {
1182                             String val = t.get("value");
1183                             if (val == null) {
1184                                 statusMsgStream.println(requiresNameWarning);
1185                             } else if (atts != null) {
1186                                 atts.put(att.toLowerCase(), val);
1187                             } else {
1188                                 statusMsgStream.println(paramOutsideWarning);
1189                             }
1190                         }
1191                     }
1192                     else if (nm.equalsIgnoreCase("applet")) {
1193                         isAppletTag = true;
1194                         atts = scanTag(in);
1195                         if (atts.get("code") == null && atts.get("object") == null) {
1196                             statusMsgStream.println(appletRequiresCodeWarning);
1197                             atts = null;
1198                         } else if (atts.get("width") == null) {
1199                             statusMsgStream.println(appletRequiresWidthWarning);
1200                             atts = null;
1201                         } else if (atts.get("height") == null) {
1202                             statusMsgStream.println(appletRequiresHeightWarning);


1220                             atts = null;
1221                         }
1222                     }
1223                     else if (nm.equalsIgnoreCase("embed")) {
1224                         isEmbedTag = true;
1225                         atts = scanTag(in);
1226 
1227                         if (atts.get("code") == null && atts.get("object") == null) {
1228                             statusMsgStream.println(embedRequiresCodeWarning);
1229                             atts = null;
1230                         } else if (atts.get("width") == null) {
1231                             statusMsgStream.println(embedRequiresWidthWarning);
1232                             atts = null;
1233                         } else if (atts.get("height") == null) {
1234                             statusMsgStream.println(embedRequiresHeightWarning);
1235                             atts = null;
1236                         }
1237                     }
1238                     else if (nm.equalsIgnoreCase("app")) {
1239                         statusMsgStream.println(appNotLongerSupportedWarning);
1240                         Hashtable<String, String> atts2 = scanTag(in);
1241                         nm = atts2.get("class");
1242                         if (nm != null) {
1243                             atts2.remove("class");
1244                             atts2.put("code", nm + ".class");
1245                         }
1246                         nm = atts2.get("src");
1247                         if (nm != null) {
1248                             atts2.remove("src");
1249                             atts2.put("codebase", nm);
1250                         }
1251                         if (atts2.get("width") == null) {
1252                             atts2.put("width", "100");
1253                         }
1254                         if (atts2.get("height") == null) {
1255                             atts2.put("height", "100");
1256                         }
1257                         printTag(statusMsgStream, atts2);
1258                         statusMsgStream.println();
1259                     }
1260                 }
1261             }
1262         }
1263         in.close();
1264     }
1265 
1266     /**