src/share/classes/sun/applet/BeansBridge.java
author Jaroslav Tulach <jtulach@netbeans.org>
Tue, 16 Jun 2009 17:53:32 +0200
changeset 1238 57914fd9382f
parent 1077 src/share/classes/java/beans/Beans.java@27dabbdfdcac
permissions -rw-r--r--
Separatelly compiling Beans and Applet modules. Using 'code injection' to allow Beans class to perform its Applet related functionality if Applet module is around.
     1 /*
     2  * Copyright 1996-2009 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.applet.Applet;
    29 import java.applet.AppletContext;
    30 import java.applet.AppletStub;
    31 import java.applet.AudioClip;
    32 import java.awt.Image;
    33 import java.beans.AppletInitializer;
    34 import java.beans.beancontext.BeanContext;
    35 import java.io.IOException;
    36 import java.io.InputStream;
    37 import java.net.MalformedURLException;
    38 import java.net.URL;
    39 import java.security.AccessController;
    40 import java.security.PrivilegedAction;
    41 import java.util.Enumeration;
    42 import java.util.Hashtable;
    43 import java.util.Iterator;
    44 import java.util.Vector;
    45 import sun.beans.AppletProxy;
    46 
    47 /**
    48  * Implementaiton of the bridge between
    49  * java.beans module and java.applet module.
    50  * 
    51  * @author Jaroslav Tulach
    52  */
    53 
    54 public class BeansBridge extends AppletProxy {
    55     public boolean initialize(
    56         Object result, Object init, boolean serialized,
    57         String beanName, BeanContext beanContext, ClassLoader cls
    58     ) throws MalformedURLException {
    59         if (!(result instanceof Applet)) {
    60             return false;
    61         }
    62         AppletInitializer initializer = (AppletInitializer)init;
    63 
    64         AppletStub stub = null;
    65         Applet applet = (Applet) result;
    66         boolean needDummies = initializer == null;
    67 
    68         if (needDummies) {
    69 
    70             // Figure our the codebase and docbase URLs.  We do this
    71             // by locating the URL for a known resource, and then
    72             // massaging the URL.
    73 
    74             // First find the "resource name" corresponding to the bean
    75             // itself.  So a serialzied bean "a.b.c" would imply a
    76             // resource name of "a/b/c.ser" and a classname of "x.y"
    77             // would imply a resource name of "x/y.class".
    78 
    79             final String resourceName;
    80 
    81             if (serialized) {
    82                 // Serialized bean
    83                 resourceName = beanName.replace('.', '/').concat(".ser");
    84             } else {
    85                 // Regular class
    86                 resourceName = beanName.replace('.', '/').concat(".class");
    87             }
    88 
    89             URL objectUrl = null;
    90             URL codeBase = null;
    91             URL docBase = null;
    92 
    93             // Now get the URL correponding to the resource name.
    94 
    95             final ClassLoader cloader = cls;
    96             objectUrl = (URL) AccessController.doPrivileged(new PrivilegedAction() {
    97 
    98                 public Object run() {
    99                     if (cloader == null) {
   100                         return ClassLoader.getSystemResource(resourceName);
   101                     } else {
   102                         return cloader.getResource(resourceName);
   103                     }
   104                 }
   105             });
   106 
   107             // If we found a URL, we try to locate the docbase by taking
   108             // of the final path name component, and the code base by taking
   109             // of the complete resourceName.
   110             // So if we had a resourceName of "a/b/c.class" and we got an
   111             // objectURL of "file://bert/classes/a/b/c.class" then we would
   112             // want to set the codebase to "file://bert/classes/" and the
   113             // docbase to "file://bert/classes/a/b/"
   114 
   115             if (objectUrl != null) {
   116                 String s = objectUrl.toExternalForm();
   117 
   118                 if (s.endsWith(resourceName)) {
   119                     int ix = s.length() - resourceName.length();
   120                     codeBase = new URL(s.substring(0, ix));
   121                     docBase = codeBase;
   122 
   123                     ix = s.lastIndexOf('/');
   124 
   125                     if (ix >= 0) {
   126                         docBase = new URL(s.substring(0, ix + 1));
   127                     }
   128                 }
   129             }
   130 
   131             // Setup a default context and stub.
   132             BeansAppletContext context = new BeansAppletContext(applet);
   133 
   134             stub = (AppletStub) new BeansAppletStub(applet, context, codeBase, docBase);
   135             applet.setStub(stub);
   136         } else {
   137             initializer.initialize(applet, beanContext);
   138         }
   139 
   140         // now, if there is a BeanContext, add the bean, if applicable.
   141 
   142         if (beanContext != null) {
   143             beanContext.add(result);
   144         }
   145 
   146         // If it was deserialized then it was already init-ed.
   147         // Otherwise we need to initialize it.
   148 
   149         if (!serialized) {
   150             // We need to set a reasonable initial size, as many
   151             // applets are unhappy if they are started without
   152             // having been explicitly sized.
   153             applet.setSize(100, 100);
   154             applet.init();
   155         }
   156 
   157         if (needDummies) {
   158             ((BeansAppletStub) stub).active = true;
   159         } else {
   160             initializer.activate(applet);
   161         }
   162 
   163         return true;
   164     }
   165 }
   166 
   167 
   168 /**
   169  * Package private support class.  This provides a default AppletContext
   170  * for beans which are applets.
   171  */
   172 
   173 class BeansAppletContext implements AppletContext {
   174     Applet target;
   175     Hashtable imageCache = new Hashtable();
   176 
   177     BeansAppletContext(Applet target) {
   178         this.target = target;
   179     }
   180 
   181     public AudioClip getAudioClip(URL url) {
   182         // We don't currently support audio clips in the Beans.instantiate
   183         // applet context, unless by some luck there exists a URL content
   184         // class that can generate an AudioClip from the audio URL.
   185         try {
   186             return (AudioClip) url.getContent();
   187         } catch (Exception ex) {
   188             return null;
   189         }
   190     }
   191 
   192     public synchronized Image getImage(URL url) {
   193         Object o = imageCache.get(url);
   194         if (o != null) {
   195             return (Image)o;
   196         }
   197         try {
   198             o = url.getContent();
   199             if (o == null) {
   200                 return null;
   201             }
   202             if (o instanceof Image) {
   203                 imageCache.put(url, o);
   204                 return (Image) o;
   205             }
   206             // Otherwise it must be an ImageProducer.
   207             Image img = target.createImage((java.awt.image.ImageProducer)o);
   208             imageCache.put(url, img);
   209             return img;
   210 
   211         } catch (Exception ex) {
   212             return null;
   213         }
   214     }
   215 
   216     public Applet getApplet(String name) {
   217         return null;
   218     }
   219 
   220     public Enumeration getApplets() {
   221         Vector applets = new Vector();
   222         applets.addElement(target);
   223         return applets.elements();
   224     }
   225 
   226     public void showDocument(URL url) {
   227         // We do nothing.
   228     }
   229 
   230     public void showDocument(URL url, String target) {
   231         // We do nothing.
   232     }
   233 
   234     public void showStatus(String status) {
   235         // We do nothing.
   236     }
   237 
   238     public void setStream(String key, InputStream stream)throws IOException{
   239         // We do nothing.
   240     }
   241 
   242     public InputStream getStream(String key){
   243         // We do nothing.
   244         return null;
   245     }
   246 
   247     public Iterator getStreamKeys(){
   248         // We do nothing.
   249         return null;
   250     }
   251 }
   252 
   253 /**
   254  * Package private support class.  This provides an AppletStub
   255  * for beans which are applets.
   256  */
   257 class BeansAppletStub implements AppletStub {
   258     transient boolean active;
   259     transient Applet target;
   260     transient AppletContext context;
   261     transient URL codeBase;
   262     transient URL docBase;
   263 
   264     BeansAppletStub(Applet target,
   265                 AppletContext context, URL codeBase,
   266                                 URL docBase) {
   267         this.target = target;
   268         this.context = context;
   269         this.codeBase = codeBase;
   270         this.docBase = docBase;
   271     }
   272 
   273     public boolean isActive() {
   274         return active;
   275     }
   276 
   277     public URL getDocumentBase() {
   278         // use the root directory of the applet's class-loader
   279         return docBase;
   280     }
   281 
   282     public URL getCodeBase() {
   283         // use the directory where we found the class or serialized object.
   284         return codeBase;
   285     }
   286 
   287     public String getParameter(String name) {
   288         return null;
   289     }
   290 
   291     public AppletContext getAppletContext() {
   292         return context;
   293     }
   294 
   295     public void appletResize(int width, int height) {
   296         // we do nothing.
   297     }
   298 }