# HG changeset patch # User Jaroslav Tulach # Date 1245167612 -7200 # Node ID 57914fd9382f41f55662d317420bb5350973bdb9 # Parent 3021779e58a1706f63730dced34a862d85d477e4 Separatelly compiling Beans and Applet modules. Using 'code injection' to allow Beans class to perform its Applet related functionality if Applet module is around. diff -r 3021779e58a1 -r 57914fd9382f build.xml --- a/build.xml Tue Jun 16 15:37:17 2009 +0200 +++ b/build.xml Tue Jun 16 17:53:32 2009 +0200 @@ -3,7 +3,7 @@ Scripts to build JDK Java sources in modularized way - + @@ -20,16 +20,23 @@ --> + + - - - - - + + + + + + + + + + @@ -52,6 +59,7 @@ + @@ -65,7 +73,7 @@ the modularization by extracting the base module from an existing classes --> - + @@ -73,7 +81,7 @@ - + @@ -83,11 +91,37 @@ - + + + + + - + + + + + + + + + + + + diff -r 3021779e58a1 -r 57914fd9382f src/share/classes/META-INF/services/sun.beans.AppletProxy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/META-INF/services/sun.beans.AppletProxy Tue Jun 16 17:53:32 2009 +0200 @@ -0,0 +1,1 @@ +sun.applet.BeansBridge diff -r 3021779e58a1 -r 57914fd9382f src/share/classes/java/beans/Beans.java --- a/src/share/classes/java/beans/Beans.java Tue Jun 16 15:37:17 2009 +0200 +++ b/src/share/classes/java/beans/Beans.java Tue Jun 16 17:53:32 2009 +0200 @@ -27,13 +27,7 @@ import com.sun.beans.finder.ClassFinder; -import java.applet.Applet; -import java.applet.AppletContext; -import java.applet.AppletStub; -import java.applet.AudioClip; - import java.awt.GraphicsEnvironment; -import java.awt.Image; import java.beans.beancontext.BeanContext; @@ -43,17 +37,15 @@ import java.io.ObjectStreamClass; import java.io.StreamCorruptedException; -import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; -import java.util.Enumeration; -import java.util.Hashtable; import java.util.Iterator; -import java.util.Vector; +import java.util.ServiceLoader; import sun.awt.AppContext; +import sun.beans.AppletProxy; /** * This class provides some general purpose beans control methods. @@ -155,8 +147,14 @@ * @exception IOException if an I/O error occurs. */ - public static Object instantiate(ClassLoader cls, String beanName, BeanContext beanContext, AppletInitializer initializer) - throws IOException, ClassNotFoundException { + public static Object instantiate(ClassLoader cls, String beanName, BeanContext beanContext, + /** TBD: Oops , this is bad. The AppletInitializer is used from + * public API. I have not noticed that sooner. Opps. + AppletInitializer initializer + * meanwhile turning into object, but this cannot be final solution: + */ + Object initializer + ) throws IOException, ClassNotFoundException { InputStream ins; ObjectInputStream oins = null; @@ -231,7 +229,7 @@ * Try to instantiate the class. */ - try { + try { result = cl.newInstance(); } catch (Exception ex) { // We have to remap the exception to one in our signature. @@ -243,108 +241,13 @@ if (result != null) { // Ok, if the result is an applet initialize it. - - AppletStub stub = null; - - if (result instanceof Applet) { - Applet applet = (Applet) result; - boolean needDummies = initializer == null; - - if (needDummies) { - - // Figure our the codebase and docbase URLs. We do this - // by locating the URL for a known resource, and then - // massaging the URL. - - // First find the "resource name" corresponding to the bean - // itself. So a serialzied bean "a.b.c" would imply a - // resource name of "a/b/c.ser" and a classname of "x.y" - // would imply a resource name of "x/y.class". - - final String resourceName; - - if (serialized) { - // Serialized bean - resourceName = beanName.replace('.','/').concat(".ser"); - } else { - // Regular class - resourceName = beanName.replace('.','/').concat(".class"); - } - - URL objectUrl = null; - URL codeBase = null; - URL docBase = null; - - // Now get the URL correponding to the resource name. - - final ClassLoader cloader = cls; - objectUrl = (URL) - AccessController.doPrivileged - (new PrivilegedAction() { - public Object run() { - if (cloader == null) - return ClassLoader.getSystemResource - (resourceName); - else - return cloader.getResource(resourceName); - } - }); - - // If we found a URL, we try to locate the docbase by taking - // of the final path name component, and the code base by taking - // of the complete resourceName. - // So if we had a resourceName of "a/b/c.class" and we got an - // objectURL of "file://bert/classes/a/b/c.class" then we would - // want to set the codebase to "file://bert/classes/" and the - // docbase to "file://bert/classes/a/b/" - - if (objectUrl != null) { - String s = objectUrl.toExternalForm(); - - if (s.endsWith(resourceName)) { - int ix = s.length() - resourceName.length(); - codeBase = new URL(s.substring(0,ix)); - docBase = codeBase; - - ix = s.lastIndexOf('/'); - - if (ix >= 0) { - docBase = new URL(s.substring(0,ix+1)); - } - } - } - - // Setup a default context and stub. - BeansAppletContext context = new BeansAppletContext(applet); - - stub = (AppletStub)new BeansAppletStub(applet, context, codeBase, docBase); - applet.setStub(stub); - } else { - initializer.initialize(applet, beanContext); - } - - // now, if there is a BeanContext, add the bean, if applicable. - - if (beanContext != null) { - beanContext.add(result); - } - - // If it was deserialized then it was already init-ed. - // Otherwise we need to initialize it. - - if (!serialized) { - // We need to set a reasonable initial size, as many - // applets are unhappy if they are started without - // having been explicitly sized. - applet.setSize(100,100); - applet.init(); - } - - if (needDummies) { - ((BeansAppletStub)stub).active = true; - } else initializer.activate(applet); - - } else if (beanContext != null) beanContext.add(result); + Iterator it = ServiceLoader.load(AppletProxy.class).iterator(); + AppletProxy ap = it.hasNext() ? it.next() : null; + if (ap != null || !ap.initialize( + result, initializer, serialized, beanName, beanContext, cls + )) { + if (beanContext != null) beanContext.add(result); + } } return result; @@ -504,134 +407,3 @@ } } -/** - * Package private support class. This provides a default AppletContext - * for beans which are applets. - */ - -class BeansAppletContext implements AppletContext { - Applet target; - Hashtable imageCache = new Hashtable(); - - BeansAppletContext(Applet target) { - this.target = target; - } - - public AudioClip getAudioClip(URL url) { - // We don't currently support audio clips in the Beans.instantiate - // applet context, unless by some luck there exists a URL content - // class that can generate an AudioClip from the audio URL. - try { - return (AudioClip) url.getContent(); - } catch (Exception ex) { - return null; - } - } - - public synchronized Image getImage(URL url) { - Object o = imageCache.get(url); - if (o != null) { - return (Image)o; - } - try { - o = url.getContent(); - if (o == null) { - return null; - } - if (o instanceof Image) { - imageCache.put(url, o); - return (Image) o; - } - // Otherwise it must be an ImageProducer. - Image img = target.createImage((java.awt.image.ImageProducer)o); - imageCache.put(url, img); - return img; - - } catch (Exception ex) { - return null; - } - } - - public Applet getApplet(String name) { - return null; - } - - public Enumeration getApplets() { - Vector applets = new Vector(); - applets.addElement(target); - return applets.elements(); - } - - public void showDocument(URL url) { - // We do nothing. - } - - public void showDocument(URL url, String target) { - // We do nothing. - } - - public void showStatus(String status) { - // We do nothing. - } - - public void setStream(String key, InputStream stream)throws IOException{ - // We do nothing. - } - - public InputStream getStream(String key){ - // We do nothing. - return null; - } - - public Iterator getStreamKeys(){ - // We do nothing. - return null; - } -} - -/** - * Package private support class. This provides an AppletStub - * for beans which are applets. - */ -class BeansAppletStub implements AppletStub { - transient boolean active; - transient Applet target; - transient AppletContext context; - transient URL codeBase; - transient URL docBase; - - BeansAppletStub(Applet target, - AppletContext context, URL codeBase, - URL docBase) { - this.target = target; - this.context = context; - this.codeBase = codeBase; - this.docBase = docBase; - } - - public boolean isActive() { - return active; - } - - public URL getDocumentBase() { - // use the root directory of the applet's class-loader - return docBase; - } - - public URL getCodeBase() { - // use the directory where we found the class or serialized object. - return codeBase; - } - - public String getParameter(String name) { - return null; - } - - public AppletContext getAppletContext() { - return context; - } - - public void appletResize(int width, int height) { - // we do nothing. - } -} diff -r 3021779e58a1 -r 57914fd9382f src/share/classes/java/beans/beancontext/BeanContextSupport.java --- a/src/share/classes/java/beans/beancontext/BeanContextSupport.java Tue Jun 16 15:37:17 2009 +0200 +++ b/src/share/classes/java/beans/beancontext/BeanContextSupport.java Tue Jun 16 17:53:32 2009 +0200 @@ -29,16 +29,12 @@ import java.awt.Container; import java.beans.Beans; -import java.beans.AppletInitializer; -import java.beans.DesignMode; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; import java.beans.VetoableChangeListener; -import java.beans.VetoableChangeSupport; import java.beans.PropertyVetoException; import java.beans.Visibility; diff -r 3021779e58a1 -r 57914fd9382f src/share/classes/sun/applet/BeansBridge.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/applet/BeansBridge.java Tue Jun 16 17:53:32 2009 +0200 @@ -0,0 +1,298 @@ +/* + * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.applet; + +import java.applet.Applet; +import java.applet.AppletContext; +import java.applet.AppletStub; +import java.applet.AudioClip; +import java.awt.Image; +import java.beans.AppletInitializer; +import java.beans.beancontext.BeanContext; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Vector; +import sun.beans.AppletProxy; + +/** + * Implementaiton of the bridge between + * java.beans module and java.applet module. + * + * @author Jaroslav Tulach + */ + +public class BeansBridge extends AppletProxy { + public boolean initialize( + Object result, Object init, boolean serialized, + String beanName, BeanContext beanContext, ClassLoader cls + ) throws MalformedURLException { + if (!(result instanceof Applet)) { + return false; + } + AppletInitializer initializer = (AppletInitializer)init; + + AppletStub stub = null; + Applet applet = (Applet) result; + boolean needDummies = initializer == null; + + if (needDummies) { + + // Figure our the codebase and docbase URLs. We do this + // by locating the URL for a known resource, and then + // massaging the URL. + + // First find the "resource name" corresponding to the bean + // itself. So a serialzied bean "a.b.c" would imply a + // resource name of "a/b/c.ser" and a classname of "x.y" + // would imply a resource name of "x/y.class". + + final String resourceName; + + if (serialized) { + // Serialized bean + resourceName = beanName.replace('.', '/').concat(".ser"); + } else { + // Regular class + resourceName = beanName.replace('.', '/').concat(".class"); + } + + URL objectUrl = null; + URL codeBase = null; + URL docBase = null; + + // Now get the URL correponding to the resource name. + + final ClassLoader cloader = cls; + objectUrl = (URL) AccessController.doPrivileged(new PrivilegedAction() { + + public Object run() { + if (cloader == null) { + return ClassLoader.getSystemResource(resourceName); + } else { + return cloader.getResource(resourceName); + } + } + }); + + // If we found a URL, we try to locate the docbase by taking + // of the final path name component, and the code base by taking + // of the complete resourceName. + // So if we had a resourceName of "a/b/c.class" and we got an + // objectURL of "file://bert/classes/a/b/c.class" then we would + // want to set the codebase to "file://bert/classes/" and the + // docbase to "file://bert/classes/a/b/" + + if (objectUrl != null) { + String s = objectUrl.toExternalForm(); + + if (s.endsWith(resourceName)) { + int ix = s.length() - resourceName.length(); + codeBase = new URL(s.substring(0, ix)); + docBase = codeBase; + + ix = s.lastIndexOf('/'); + + if (ix >= 0) { + docBase = new URL(s.substring(0, ix + 1)); + } + } + } + + // Setup a default context and stub. + BeansAppletContext context = new BeansAppletContext(applet); + + stub = (AppletStub) new BeansAppletStub(applet, context, codeBase, docBase); + applet.setStub(stub); + } else { + initializer.initialize(applet, beanContext); + } + + // now, if there is a BeanContext, add the bean, if applicable. + + if (beanContext != null) { + beanContext.add(result); + } + + // If it was deserialized then it was already init-ed. + // Otherwise we need to initialize it. + + if (!serialized) { + // We need to set a reasonable initial size, as many + // applets are unhappy if they are started without + // having been explicitly sized. + applet.setSize(100, 100); + applet.init(); + } + + if (needDummies) { + ((BeansAppletStub) stub).active = true; + } else { + initializer.activate(applet); + } + + return true; + } +} + + +/** + * Package private support class. This provides a default AppletContext + * for beans which are applets. + */ + +class BeansAppletContext implements AppletContext { + Applet target; + Hashtable imageCache = new Hashtable(); + + BeansAppletContext(Applet target) { + this.target = target; + } + + public AudioClip getAudioClip(URL url) { + // We don't currently support audio clips in the Beans.instantiate + // applet context, unless by some luck there exists a URL content + // class that can generate an AudioClip from the audio URL. + try { + return (AudioClip) url.getContent(); + } catch (Exception ex) { + return null; + } + } + + public synchronized Image getImage(URL url) { + Object o = imageCache.get(url); + if (o != null) { + return (Image)o; + } + try { + o = url.getContent(); + if (o == null) { + return null; + } + if (o instanceof Image) { + imageCache.put(url, o); + return (Image) o; + } + // Otherwise it must be an ImageProducer. + Image img = target.createImage((java.awt.image.ImageProducer)o); + imageCache.put(url, img); + return img; + + } catch (Exception ex) { + return null; + } + } + + public Applet getApplet(String name) { + return null; + } + + public Enumeration getApplets() { + Vector applets = new Vector(); + applets.addElement(target); + return applets.elements(); + } + + public void showDocument(URL url) { + // We do nothing. + } + + public void showDocument(URL url, String target) { + // We do nothing. + } + + public void showStatus(String status) { + // We do nothing. + } + + public void setStream(String key, InputStream stream)throws IOException{ + // We do nothing. + } + + public InputStream getStream(String key){ + // We do nothing. + return null; + } + + public Iterator getStreamKeys(){ + // We do nothing. + return null; + } +} + +/** + * Package private support class. This provides an AppletStub + * for beans which are applets. + */ +class BeansAppletStub implements AppletStub { + transient boolean active; + transient Applet target; + transient AppletContext context; + transient URL codeBase; + transient URL docBase; + + BeansAppletStub(Applet target, + AppletContext context, URL codeBase, + URL docBase) { + this.target = target; + this.context = context; + this.codeBase = codeBase; + this.docBase = docBase; + } + + public boolean isActive() { + return active; + } + + public URL getDocumentBase() { + // use the root directory of the applet's class-loader + return docBase; + } + + public URL getCodeBase() { + // use the directory where we found the class or serialized object. + return codeBase; + } + + public String getParameter(String name) { + return null; + } + + public AppletContext getAppletContext() { + return context; + } + + public void appletResize(int width, int height) { + // we do nothing. + } +} diff -r 3021779e58a1 -r 57914fd9382f src/share/classes/sun/beans/AppletProxy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/beans/AppletProxy.java Tue Jun 16 17:53:32 2009 +0200 @@ -0,0 +1,42 @@ +/* + * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.beans; + +import java.beans.beancontext.BeanContext; +import java.net.MalformedURLException; + + +/** + * Bridge between java.beans module and java.applet module. + * @author Jaroslav Tulach + */ + +public abstract class AppletProxy { + public abstract boolean initialize( + Object result, Object init, boolean serialized, + String beanName, BeanContext beanContext, ClassLoader cls + ) throws MalformedURLException; +}