Clover coverage report - PLT Utilities Test Coverage (plt-20120304-r5436)
Coverage timestamp: Sat Mar 3 2012 22:01:56 CST
file stats: LOC: 150   Methods: 27
NCLOC: 99   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
AppletComponent.java 0% 0% 0% 0%
coverage
 1    package edu.rice.cs.plt.swing;
 2   
 3    import java.applet.Applet;
 4    import java.applet.AppletContext;
 5    import java.applet.AppletStub;
 6    import java.applet.AudioClip;
 7    import java.awt.Graphics;
 8    import java.awt.Image;
 9    import java.awt.Toolkit;
 10    import java.io.InputStream;
 11    import java.net.MalformedURLException;
 12    import java.net.URL;
 13    import java.util.Collections;
 14    import java.util.Enumeration;
 15    import java.util.HashMap;
 16    import java.util.Iterator;
 17    import java.util.Map;
 18   
 19    import javax.swing.JComponent;
 20   
 21    import edu.rice.cs.plt.io.IOUtil;
 22    import edu.rice.cs.plt.iter.IterUtil;
 23   
 24    /**
 25    * A JComponent wrapper for an Applet, providing a lightweight context for testing or reusing
 26    * applet code. Applets wrapped here behave differently in some ways than they do in a standard
 27    * browser environment:
 28    * <ul>
 29    * <li>No special SecurityManager controls the applet's access to system resources, so certain
 30    * operations typically prohibited for applets may be permitted.</li>
 31    * <li>The {@code stop()} method is never called (by the current wrapper implementation, at least).</li>
 32    * <li>{@code showStatus()} has no effect.</li>
 33    * <li>{@code getDocumentBase()} and {@code getCodeBase()} return a root URL provided to the constructor,
 34    * or (by default) the JVM's working directory.</li>
 35    * <li>{@code getAudioClip()} returns a dummy object whose methods have no effect.</li>
 36    * <li>{@code getAppletContext().getApplet()} always returns {@code null}.</li>
 37    * <li>{@code getAppletContext().showDocument()} has no effect.</li>
 38    * <li>The InputStream map maintained by the AppletContext is unique for each instance -- it can't
 39    * be used for inter-applet communication.</li>
 40    * </ul>
 41    */
 42    public class AppletComponent extends JComponent {
 43   
 44    private enum State { FRESH, PAUSED, RUNNING };
 45   
 46    private final Applet _applet;
 47    private final Map<String, String> _params;
 48    private final URL _root;
 49    private State _state;
 50   
 51  0 public AppletComponent(Applet applet) {
 52  0 this(applet, null, Collections.<String, String>emptyMap());
 53    }
 54   
 55    /**
 56    * Constructor.
 57    * @param applet A freshly constructed applet (will be initialized and started).
 58    * @param root The code's root, or {@code null} to use the JVM's working directory. If provided, should
 59    * be a jar file or a directory (directory URLs end in '/').
 60    * @param params Any custom parameters for the applet.
 61    */
 62  0 public AppletComponent(Applet applet, URL root, Map<String, String> params) {
 63  0 _applet = applet;
 64  0 _params = params;
 65  0 if (root == null) {
 66  0 try { _root = IOUtil.WORKING_DIRECTORY.toURI().toURL(); }
 67  0 catch (MalformedURLException e) { throw new RuntimeException("Can't convert the working dir to a URL"); }
 68    }
 69  0 else { _root = root; }
 70  0 _state = State.FRESH;
 71  0 add(_applet);
 72  0 _applet.setStub(new Stub());
 73    }
 74   
 75  0 public AppletComponent(Applet applet, int width, int height) {
 76  0 this(applet, width, height, null, Collections.<String, String>emptyMap());
 77    }
 78   
 79    /**
 80    * Constructor.
 81    * @param applet A freshly constructed applet (will be initialized and started).
 82    * @param width Width for the applet and this enclosing component.
 83    * @param height Height for the applet and this enclosing component.
 84    * @param root The code's root, or {@code null} to use the JVM's working directory. If provided, should
 85    * be a jar file or a directory (directory URLs end in '/').
 86    * @param params Any custom parameters for the applet.
 87    */
 88  0 public AppletComponent(Applet applet, int width, int height, URL root, Map<String, String> params) {
 89  0 this(applet, root, params);
 90  0 _applet.setSize(width, height); // should trigger a change in this component's size, too
 91    }
 92   
 93  0 protected void paintComponent(Graphics g) {
 94  0 updateState();
 95  0 super.paintComponent(g);
 96    }
 97   
 98  0 private void updateState() {
 99  0 if (!_state.equals(State.RUNNING)) {
 100  0 if (_state.equals(State.FRESH)) {
 101  0 _state = State.PAUSED;
 102    // run Applet.init() outside teh event thread, as per bug report 3069101:
 103    // https://sourceforge.net/tracker/?func=detail&atid=438935&aid=3069101&group_id=44253
 104  0 edu.rice.cs.plt.concurrent.ConcurrentUtil.runInThread(new Runnable() {
 105  0 public void run() {
 106  0 _applet.init();
 107  0 _applet.start();
 108  0 _state = State.RUNNING;
 109  0 if (!_applet.getSize().equals(getSize())) { _applet.setSize(getSize()); }
 110  0 validate();
 111    }
 112    });
 113    }
 114    }
 115  0 if (_state.equals(State.RUNNING)) {
 116    // lazily update size rather than trying to intercept all resizing methods
 117  0 if (!_applet.getSize().equals(getSize())) { _applet.setSize(getSize()); }
 118    }
 119    }
 120   
 121    private class Stub implements AppletStub, AppletContext {
 122    private final Map<String, InputStream> _streams;
 123  0 public Stub() { _streams = new HashMap<String, InputStream>(); }
 124  0 public boolean isActive() { return _state.equals(State.RUNNING); }
 125  0 public URL getDocumentBase() { return _root; }
 126  0 public URL getCodeBase() { return _root; }
 127  0 public String getParameter(String name) { return _params.get(name); }
 128  0 public AppletContext getAppletContext() { return this; }
 129  0 public void appletResize(int width, int height) { AppletComponent.this.setSize(width, height); }
 130  0 public AudioClip getAudioClip(URL url) {
 131  0 return new AudioClip() {
 132  0 public void play() {}
 133  0 public void loop() {}
 134  0 public void stop() {}
 135    };
 136    }
 137  0 public Image getImage(URL url) { return Toolkit.getDefaultToolkit().getImage(url); }
 138  0 public Applet getApplet(String name) { return null; }
 139  0 public Enumeration<Applet> getApplets() {
 140  0 return IterUtil.asEnumeration(IterUtil.singleton(_applet).iterator());
 141    }
 142  0 public void showDocument(URL url) {}
 143  0 public void showDocument(URL url, String target) {}
 144  0 public void showStatus(String status) {}
 145  0 public void setStream(String key, InputStream stream) { _streams.put(key, stream); }
 146  0 public InputStream getStream(String key) { return _streams.get(key); }
 147  0 public Iterator<String> getStreamKeys() { return _streams.keySet().iterator(); }
 148    }
 149   
 150    }