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

Save This Page
Home » openjdk-7 » sun » applet » [javadoc | source]