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.
duke@0
     1
/*
malenkov@1077
     2
 * Copyright 1996-2009 Sun Microsystems, Inc.  All Rights Reserved.
duke@0
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@0
     4
 *
duke@0
     5
 * This code is free software; you can redistribute it and/or modify it
duke@0
     6
 * under the terms of the GNU General Public License version 2 only, as
duke@0
     7
 * published by the Free Software Foundation.  Sun designates this
duke@0
     8
 * particular file as subject to the "Classpath" exception as provided
duke@0
     9
 * by Sun in the LICENSE file that accompanied this code.
duke@0
    10
 *
duke@0
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@0
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@0
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
duke@0
    14
 * version 2 for more details (a copy is included in the LICENSE file that
duke@0
    15
 * accompanied this code).
duke@0
    16
 *
duke@0
    17
 * You should have received a copy of the GNU General Public License version
duke@0
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
duke@0
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@0
    20
 *
duke@0
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
duke@0
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
duke@0
    23
 * have any questions.
duke@0
    24
 */
duke@0
    25
jtulach@1238
    26
package sun.applet;
duke@0
    27
malenkov@1077
    28
import java.applet.Applet;
malenkov@1077
    29
import java.applet.AppletContext;
malenkov@1077
    30
import java.applet.AppletStub;
malenkov@1077
    31
import java.applet.AudioClip;
malenkov@1077
    32
import java.awt.Image;
jtulach@1238
    33
import java.beans.AppletInitializer;
duke@0
    34
import java.beans.beancontext.BeanContext;
malenkov@1077
    35
import java.io.IOException;
malenkov@1077
    36
import java.io.InputStream;
jtulach@1238
    37
import java.net.MalformedURLException;
duke@0
    38
import java.net.URL;
malenkov@1077
    39
import java.security.AccessController;
malenkov@1077
    40
import java.security.PrivilegedAction;
malenkov@1077
    41
import java.util.Enumeration;
malenkov@1077
    42
import java.util.Hashtable;
malenkov@1077
    43
import java.util.Iterator;
malenkov@1077
    44
import java.util.Vector;
jtulach@1238
    45
import sun.beans.AppletProxy;
duke@0
    46
duke@0
    47
/**
jtulach@1238
    48
 * Implementaiton of the bridge between
jtulach@1238
    49
 * java.beans module and java.applet module.
jtulach@1238
    50
 * 
jtulach@1238
    51
 * @author Jaroslav Tulach
duke@0
    52
 */
duke@0
    53
jtulach@1238
    54
public class BeansBridge extends AppletProxy {
jtulach@1238
    55
    public boolean initialize(
jtulach@1238
    56
        Object result, Object init, boolean serialized,
jtulach@1238
    57
        String beanName, BeanContext beanContext, ClassLoader cls
jtulach@1238
    58
    ) throws MalformedURLException {
jtulach@1238
    59
        if (!(result instanceof Applet)) {
jtulach@1238
    60
            return false;
jtulach@1238
    61
        }
jtulach@1238
    62
        AppletInitializer initializer = (AppletInitializer)init;
duke@0
    63
jtulach@1238
    64
        AppletStub stub = null;
jtulach@1238
    65
        Applet applet = (Applet) result;
jtulach@1238
    66
        boolean needDummies = initializer == null;
duke@0
    67
jtulach@1238
    68
        if (needDummies) {
duke@0
    69
jtulach@1238
    70
            // Figure our the codebase and docbase URLs.  We do this
jtulach@1238
    71
            // by locating the URL for a known resource, and then
jtulach@1238
    72
            // massaging the URL.
duke@0
    73
jtulach@1238
    74
            // First find the "resource name" corresponding to the bean
jtulach@1238
    75
            // itself.  So a serialzied bean "a.b.c" would imply a
jtulach@1238
    76
            // resource name of "a/b/c.ser" and a classname of "x.y"
jtulach@1238
    77
            // would imply a resource name of "x/y.class".
duke@0
    78
jtulach@1238
    79
            final String resourceName;
duke@0
    80
jtulach@1238
    81
            if (serialized) {
jtulach@1238
    82
                // Serialized bean
jtulach@1238
    83
                resourceName = beanName.replace('.', '/').concat(".ser");
jtulach@1238
    84
            } else {
jtulach@1238
    85
                // Regular class
jtulach@1238
    86
                resourceName = beanName.replace('.', '/').concat(".class");
jtulach@1238
    87
            }
duke@0
    88
jtulach@1238
    89
            URL objectUrl = null;
jtulach@1238
    90
            URL codeBase = null;
jtulach@1238
    91
            URL docBase = null;
duke@0
    92
jtulach@1238
    93
            // Now get the URL correponding to the resource name.
jtulach@1238
    94
jtulach@1238
    95
            final ClassLoader cloader = cls;
jtulach@1238
    96
            objectUrl = (URL) AccessController.doPrivileged(new PrivilegedAction() {
jtulach@1238
    97
jtulach@1238
    98
                public Object run() {
jtulach@1238
    99
                    if (cloader == null) {
jtulach@1238
   100
                        return ClassLoader.getSystemResource(resourceName);
jtulach@1238
   101
                    } else {
jtulach@1238
   102
                        return cloader.getResource(resourceName);
jtulach@1238
   103
                    }
jtulach@1238
   104
                }
jtulach@1238
   105
            });
jtulach@1238
   106
jtulach@1238
   107
            // If we found a URL, we try to locate the docbase by taking
jtulach@1238
   108
            // of the final path name component, and the code base by taking
jtulach@1238
   109
            // of the complete resourceName.
jtulach@1238
   110
            // So if we had a resourceName of "a/b/c.class" and we got an
jtulach@1238
   111
            // objectURL of "file://bert/classes/a/b/c.class" then we would
jtulach@1238
   112
            // want to set the codebase to "file://bert/classes/" and the
jtulach@1238
   113
            // docbase to "file://bert/classes/a/b/"
jtulach@1238
   114
jtulach@1238
   115
            if (objectUrl != null) {
jtulach@1238
   116
                String s = objectUrl.toExternalForm();
jtulach@1238
   117
jtulach@1238
   118
                if (s.endsWith(resourceName)) {
jtulach@1238
   119
                    int ix = s.length() - resourceName.length();
jtulach@1238
   120
                    codeBase = new URL(s.substring(0, ix));
jtulach@1238
   121
                    docBase = codeBase;
jtulach@1238
   122
jtulach@1238
   123
                    ix = s.lastIndexOf('/');
jtulach@1238
   124
jtulach@1238
   125
                    if (ix >= 0) {
jtulach@1238
   126
                        docBase = new URL(s.substring(0, ix + 1));
jtulach@1238
   127
                    }
jtulach@1238
   128
                }
duke@0
   129
            }
jtulach@1238
   130
jtulach@1238
   131
            // Setup a default context and stub.
jtulach@1238
   132
            BeansAppletContext context = new BeansAppletContext(applet);
jtulach@1238
   133
jtulach@1238
   134
            stub = (AppletStub) new BeansAppletStub(applet, context, codeBase, docBase);
jtulach@1238
   135
            applet.setStub(stub);
jtulach@1238
   136
        } else {
jtulach@1238
   137
            initializer.initialize(applet, beanContext);
duke@0
   138
        }
duke@0
   139
jtulach@1238
   140
        // now, if there is a BeanContext, add the bean, if applicable.
jtulach@1238
   141
jtulach@1238
   142
        if (beanContext != null) {
jtulach@1238
   143
            beanContext.add(result);
duke@0
   144
        }
duke@0
   145
jtulach@1238
   146
        // If it was deserialized then it was already init-ed.
jtulach@1238
   147
        // Otherwise we need to initialize it.
duke@0
   148
jtulach@1238
   149
        if (!serialized) {
jtulach@1238
   150
            // We need to set a reasonable initial size, as many
jtulach@1238
   151
            // applets are unhappy if they are started without
jtulach@1238
   152
            // having been explicitly sized.
jtulach@1238
   153
            applet.setSize(100, 100);
jtulach@1238
   154
            applet.init();
duke@0
   155
        }
duke@0
   156
jtulach@1238
   157
        if (needDummies) {
jtulach@1238
   158
            ((BeansAppletStub) stub).active = true;
jtulach@1238
   159
        } else {
jtulach@1238
   160
            initializer.activate(applet);
duke@0
   161
        }
duke@0
   162
jtulach@1238
   163
        return true;
duke@0
   164
    }
duke@0
   165
}
duke@0
   166
duke@0
   167
duke@0
   168
/**
duke@0
   169
 * Package private support class.  This provides a default AppletContext
duke@0
   170
 * for beans which are applets.
duke@0
   171
 */
duke@0
   172
duke@0
   173
class BeansAppletContext implements AppletContext {
duke@0
   174
    Applet target;
malenkov@1077
   175
    Hashtable imageCache = new Hashtable();
duke@0
   176
duke@0
   177
    BeansAppletContext(Applet target) {
duke@0
   178
        this.target = target;
duke@0
   179
    }
duke@0
   180
duke@0
   181
    public AudioClip getAudioClip(URL url) {
duke@0
   182
        // We don't currently support audio clips in the Beans.instantiate
duke@0
   183
        // applet context, unless by some luck there exists a URL content
duke@0
   184
        // class that can generate an AudioClip from the audio URL.
duke@0
   185
        try {
duke@0
   186
            return (AudioClip) url.getContent();
duke@0
   187
        } catch (Exception ex) {
duke@0
   188
            return null;
duke@0
   189
        }
duke@0
   190
    }
duke@0
   191
duke@0
   192
    public synchronized Image getImage(URL url) {
duke@0
   193
        Object o = imageCache.get(url);
duke@0
   194
        if (o != null) {
duke@0
   195
            return (Image)o;
duke@0
   196
        }
duke@0
   197
        try {
duke@0
   198
            o = url.getContent();
duke@0
   199
            if (o == null) {
duke@0
   200
                return null;
duke@0
   201
            }
duke@0
   202
            if (o instanceof Image) {
duke@0
   203
                imageCache.put(url, o);
duke@0
   204
                return (Image) o;
duke@0
   205
            }
duke@0
   206
            // Otherwise it must be an ImageProducer.
duke@0
   207
            Image img = target.createImage((java.awt.image.ImageProducer)o);
duke@0
   208
            imageCache.put(url, img);
duke@0
   209
            return img;
duke@0
   210
duke@0
   211
        } catch (Exception ex) {
duke@0
   212
            return null;
duke@0
   213
        }
duke@0
   214
    }
duke@0
   215
duke@0
   216
    public Applet getApplet(String name) {
duke@0
   217
        return null;
duke@0
   218
    }
duke@0
   219
malenkov@1077
   220
    public Enumeration getApplets() {
malenkov@1077
   221
        Vector applets = new Vector();
duke@0
   222
        applets.addElement(target);
duke@0
   223
        return applets.elements();
duke@0
   224
    }
duke@0
   225
duke@0
   226
    public void showDocument(URL url) {
duke@0
   227
        // We do nothing.
duke@0
   228
    }
duke@0
   229
duke@0
   230
    public void showDocument(URL url, String target) {
duke@0
   231
        // We do nothing.
duke@0
   232
    }
duke@0
   233
duke@0
   234
    public void showStatus(String status) {
duke@0
   235
        // We do nothing.
duke@0
   236
    }
duke@0
   237
duke@0
   238
    public void setStream(String key, InputStream stream)throws IOException{
duke@0
   239
        // We do nothing.
duke@0
   240
    }
duke@0
   241
duke@0
   242
    public InputStream getStream(String key){
duke@0
   243
        // We do nothing.
duke@0
   244
        return null;
duke@0
   245
    }
duke@0
   246
malenkov@1077
   247
    public Iterator getStreamKeys(){
duke@0
   248
        // We do nothing.
duke@0
   249
        return null;
duke@0
   250
    }
duke@0
   251
}
duke@0
   252
duke@0
   253
/**
duke@0
   254
 * Package private support class.  This provides an AppletStub
duke@0
   255
 * for beans which are applets.
duke@0
   256
 */
duke@0
   257
class BeansAppletStub implements AppletStub {
duke@0
   258
    transient boolean active;
duke@0
   259
    transient Applet target;
duke@0
   260
    transient AppletContext context;
duke@0
   261
    transient URL codeBase;
duke@0
   262
    transient URL docBase;
duke@0
   263
duke@0
   264
    BeansAppletStub(Applet target,
duke@0
   265
                AppletContext context, URL codeBase,
duke@0
   266
                                URL docBase) {
duke@0
   267
        this.target = target;
duke@0
   268
        this.context = context;
duke@0
   269
        this.codeBase = codeBase;
duke@0
   270
        this.docBase = docBase;
duke@0
   271
    }
duke@0
   272
duke@0
   273
    public boolean isActive() {
duke@0
   274
        return active;
duke@0
   275
    }
duke@0
   276
duke@0
   277
    public URL getDocumentBase() {
duke@0
   278
        // use the root directory of the applet's class-loader
duke@0
   279
        return docBase;
duke@0
   280
    }
duke@0
   281
duke@0
   282
    public URL getCodeBase() {
duke@0
   283
        // use the directory where we found the class or serialized object.
duke@0
   284
        return codeBase;
duke@0
   285
    }
duke@0
   286
duke@0
   287
    public String getParameter(String name) {
duke@0
   288
        return null;
duke@0
   289
    }
duke@0
   290
duke@0
   291
    public AppletContext getAppletContext() {
duke@0
   292
        return context;
duke@0
   293
    }
duke@0
   294
duke@0
   295
    public void appletResize(int width, int height) {
duke@0
   296
        // we do nothing.
duke@0
   297
    }
duke@0
   298
}