J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright 1996-2006 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 java.beans; |
| 27 | |
| 28 | import com.sun.beans.finder.ClassFinder; |
| 29 | |
| 30 | import java.applet.*; |
| 31 | |
| 32 | import java.awt.*; |
| 33 | |
| 34 | import java.beans.AppletInitializer; |
| 35 | |
| 36 | import java.beans.beancontext.BeanContext; |
| 37 | |
| 38 | import java.io.*; |
| 39 | |
| 40 | import java.lang.reflect.Constructor; |
| 41 | |
| 42 | import java.net.URL; |
| 43 | import java.lang.reflect.Array; |
| 44 | |
| 45 | /** |
| 46 | * This class provides some general purpose beans control methods. |
| 47 | */ |
| 48 | |
| 49 | public class Beans { |
| 50 | |
| 51 | /** |
| 52 | * <p> |
| 53 | * Instantiate a JavaBean. |
| 54 | * </p> |
| 55 | * |
| 56 | * @param cls the class-loader from which we should create |
| 57 | * the bean. If this is null, then the system |
| 58 | * class-loader is used. |
| 59 | * @param beanName the name of the bean within the class-loader. |
| 60 | * For example "sun.beanbox.foobah" |
| 61 | * |
| 62 | * @exception java.lang.ClassNotFoundException if the class of a serialized |
| 63 | * object could not be found. |
| 64 | * @exception java.io.IOException if an I/O error occurs. |
| 65 | */ |
| 66 | |
| 67 | public static Object instantiate(ClassLoader cls, String beanName) throws java.io.IOException, ClassNotFoundException { |
| 68 | return Beans.instantiate(cls, beanName, null, null); |
| 69 | } |
| 70 | |
| 71 | /** |
| 72 | * <p> |
| 73 | * Instantiate a JavaBean. |
| 74 | * </p> |
| 75 | * |
| 76 | * @param cls the class-loader from which we should create |
| 77 | * the bean. If this is null, then the system |
| 78 | * class-loader is used. |
| 79 | * @param beanName the name of the bean within the class-loader. |
| 80 | * For example "sun.beanbox.foobah" |
| 81 | * @param beanContext The BeanContext in which to nest the new bean |
| 82 | * |
| 83 | * @exception java.lang.ClassNotFoundException if the class of a serialized |
| 84 | * object could not be found. |
| 85 | * @exception java.io.IOException if an I/O error occurs. |
| 86 | */ |
| 87 | |
| 88 | public static Object instantiate(ClassLoader cls, String beanName, BeanContext beanContext) throws java.io.IOException, ClassNotFoundException { |
| 89 | return Beans.instantiate(cls, beanName, beanContext, null); |
| 90 | } |
| 91 | |
| 92 | /** |
| 93 | * Instantiate a bean. |
| 94 | * <p> |
| 95 | * The bean is created based on a name relative to a class-loader. |
| 96 | * This name should be a dot-separated name such as "a.b.c". |
| 97 | * <p> |
| 98 | * In Beans 1.0 the given name can indicate either a serialized object |
| 99 | * or a class. Other mechanisms may be added in the future. In |
| 100 | * beans 1.0 we first try to treat the beanName as a serialized object |
| 101 | * name then as a class name. |
| 102 | * <p> |
| 103 | * When using the beanName as a serialized object name we convert the |
| 104 | * given beanName to a resource pathname and add a trailing ".ser" suffix. |
| 105 | * We then try to load a serialized object from that resource. |
| 106 | * <p> |
| 107 | * For example, given a beanName of "x.y", Beans.instantiate would first |
| 108 | * try to read a serialized object from the resource "x/y.ser" and if |
| 109 | * that failed it would try to load the class "x.y" and create an |
| 110 | * instance of that class. |
| 111 | * <p> |
| 112 | * If the bean is a subtype of java.applet.Applet, then it is given |
| 113 | * some special initialization. First, it is supplied with a default |
| 114 | * AppletStub and AppletContext. Second, if it was instantiated from |
| 115 | * a classname the applet's "init" method is called. (If the bean was |
| 116 | * deserialized this step is skipped.) |
| 117 | * <p> |
| 118 | * Note that for beans which are applets, it is the caller's responsiblity |
| 119 | * to call "start" on the applet. For correct behaviour, this should be done |
| 120 | * after the applet has been added into a visible AWT container. |
| 121 | * <p> |
| 122 | * Note that applets created via beans.instantiate run in a slightly |
| 123 | * different environment than applets running inside browsers. In |
| 124 | * particular, bean applets have no access to "parameters", so they may |
| 125 | * wish to provide property get/set methods to set parameter values. We |
| 126 | * advise bean-applet developers to test their bean-applets against both |
| 127 | * the JDK appletviewer (for a reference browser environment) and the |
| 128 | * BDK BeanBox (for a reference bean container). |
| 129 | * |
| 130 | * @param cls the class-loader from which we should create |
| 131 | * the bean. If this is null, then the system |
| 132 | * class-loader is used. |
| 133 | * @param beanName the name of the bean within the class-loader. |
| 134 | * For example "sun.beanbox.foobah" |
| 135 | * @param beanContext The BeanContext in which to nest the new bean |
| 136 | * @param initializer The AppletInitializer for the new bean |
| 137 | * |
| 138 | * @exception java.lang.ClassNotFoundException if the class of a serialized |
| 139 | * object could not be found. |
| 140 | * @exception java.io.IOException if an I/O error occurs. |
| 141 | */ |
| 142 | |
| 143 | public static Object instantiate(ClassLoader cls, String beanName, BeanContext beanContext, AppletInitializer initializer) |
| 144 | throws java.io.IOException, ClassNotFoundException { |
| 145 | |
| 146 | java.io.InputStream ins; |
| 147 | java.io.ObjectInputStream oins = null; |
| 148 | Object result = null; |
| 149 | boolean serialized = false; |
| 150 | java.io.IOException serex = null; |
| 151 | |
| 152 | // If the given classloader is null, we check if an |
| 153 | // system classloader is available and (if so) |
| 154 | // use that instead. |
| 155 | // Note that calls on the system class loader will |
| 156 | // look in the bootstrap class loader first. |
| 157 | if (cls == null) { |
| 158 | try { |
| 159 | cls = ClassLoader.getSystemClassLoader(); |
| 160 | } catch (SecurityException ex) { |
| 161 | // We're not allowed to access the system class loader. |
| 162 | // Drop through. |
| 163 | } |
| 164 | } |
| 165 | |
| 166 | // Try to find a serialized object with this name |
| 167 | final String serName = beanName.replace('.','/').concat(".ser"); |
| 168 | final ClassLoader loader = cls; |
| 169 | ins = (InputStream)java.security.AccessController.doPrivileged |
| 170 | (new java.security.PrivilegedAction() { |
| 171 | public Object run() { |
| 172 | if (loader == null) |
| 173 | return ClassLoader.getSystemResourceAsStream(serName); |
| 174 | else |
| 175 | return loader.getResourceAsStream(serName); |
| 176 | } |
| 177 | }); |
| 178 | if (ins != null) { |
| 179 | try { |
| 180 | if (cls == null) { |
| 181 | oins = new ObjectInputStream(ins); |
| 182 | } else { |
| 183 | oins = new ObjectInputStreamWithLoader(ins, cls); |
| 184 | } |
| 185 | result = oins.readObject(); |
| 186 | serialized = true; |
| 187 | oins.close(); |
| 188 | } catch (java.io.IOException ex) { |
| 189 | ins.close(); |
| 190 | // Drop through and try opening the class. But remember |
| 191 | // the exception in case we can't find the class either. |
| 192 | serex = ex; |
| 193 | } catch (ClassNotFoundException ex) { |
| 194 | ins.close(); |
| 195 | throw ex; |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | if (result == null) { |
| 200 | // No serialized object, try just instantiating the class |
| 201 | Class cl; |
| 202 | |
| 203 | try { |
| 204 | cl = ClassFinder.findClass(beanName, cls); |
| 205 | } catch (ClassNotFoundException ex) { |
| 206 | // There is no appropriate class. If we earlier tried to |
| 207 | // deserialize an object and got an IO exception, throw that, |
| 208 | // otherwise rethrow the ClassNotFoundException. |
| 209 | if (serex != null) { |
| 210 | throw serex; |
| 211 | } |
| 212 | throw ex; |
| 213 | } |
| 214 | |
| 215 | /* |
| 216 | * Try to instantiate the class. |
| 217 | */ |
| 218 | |
| 219 | try { |
| 220 | result = cl.newInstance(); |
| 221 | } catch (Exception ex) { |
| 222 | // We have to remap the exception to one in our signature. |
| 223 | // But we pass extra information in the detail message. |
| 224 | throw new ClassNotFoundException("" + cl + " : " + ex, ex); |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | if (result != null) { |
| 229 | |
| 230 | // Ok, if the result is an applet initialize it. |
| 231 | |
| 232 | AppletStub stub = null; |
| 233 | |
| 234 | if (result instanceof Applet) { |
| 235 | Applet applet = (Applet) result; |
| 236 | boolean needDummies = initializer == null; |
| 237 | |
| 238 | if (needDummies) { |
| 239 | |
| 240 | // Figure our the codebase and docbase URLs. We do this |
| 241 | // by locating the URL for a known resource, and then |
| 242 | // massaging the URL. |
| 243 | |
| 244 | // First find the "resource name" corresponding to the bean |
| 245 | // itself. So a serialzied bean "a.b.c" would imply a |
| 246 | // resource name of "a/b/c.ser" and a classname of "x.y" |
| 247 | // would imply a resource name of "x/y.class". |
| 248 | |
| 249 | final String resourceName; |
| 250 | |
| 251 | if (serialized) { |
| 252 | // Serialized bean |
| 253 | resourceName = beanName.replace('.','/').concat(".ser"); |
| 254 | } else { |
| 255 | // Regular class |
| 256 | resourceName = beanName.replace('.','/').concat(".class"); |
| 257 | } |
| 258 | |
| 259 | URL objectUrl = null; |
| 260 | URL codeBase = null; |
| 261 | URL docBase = null; |
| 262 | |
| 263 | // Now get the URL correponding to the resource name. |
| 264 | |
| 265 | final ClassLoader cloader = cls; |
| 266 | objectUrl = (URL) |
| 267 | java.security.AccessController.doPrivileged |
| 268 | (new java.security.PrivilegedAction() { |
| 269 | public Object run() { |
| 270 | if (cloader == null) |
| 271 | return ClassLoader.getSystemResource |
| 272 | (resourceName); |
| 273 | else |
| 274 | return cloader.getResource(resourceName); |
| 275 | } |
| 276 | }); |
| 277 | |
| 278 | // If we found a URL, we try to locate the docbase by taking |
| 279 | // of the final path name component, and the code base by taking |
| 280 | // of the complete resourceName. |
| 281 | // So if we had a resourceName of "a/b/c.class" and we got an |
| 282 | // objectURL of "file://bert/classes/a/b/c.class" then we would |
| 283 | // want to set the codebase to "file://bert/classes/" and the |
| 284 | // docbase to "file://bert/classes/a/b/" |
| 285 | |
| 286 | if (objectUrl != null) { |
| 287 | String s = objectUrl.toExternalForm(); |
| 288 | |
| 289 | if (s.endsWith(resourceName)) { |
| 290 | int ix = s.length() - resourceName.length(); |
| 291 | codeBase = new URL(s.substring(0,ix)); |
| 292 | docBase = codeBase; |
| 293 | |
| 294 | ix = s.lastIndexOf('/'); |
| 295 | |
| 296 | if (ix >= 0) { |
| 297 | docBase = new URL(s.substring(0,ix+1)); |
| 298 | } |
| 299 | } |
| 300 | } |
| 301 | |
| 302 | // Setup a default context and stub. |
| 303 | BeansAppletContext context = new BeansAppletContext(applet); |
| 304 | |
| 305 | stub = (AppletStub)new BeansAppletStub(applet, context, codeBase, docBase); |
| 306 | applet.setStub(stub); |
| 307 | } else { |
| 308 | initializer.initialize(applet, beanContext); |
| 309 | } |
| 310 | |
| 311 | // now, if there is a BeanContext, add the bean, if applicable. |
| 312 | |
| 313 | if (beanContext != null) { |
| 314 | beanContext.add(result); |
| 315 | } |
| 316 | |
| 317 | // If it was deserialized then it was already init-ed. |
| 318 | // Otherwise we need to initialize it. |
| 319 | |
| 320 | if (!serialized) { |
| 321 | // We need to set a reasonable initial size, as many |
| 322 | // applets are unhappy if they are started without |
| 323 | // having been explicitly sized. |
| 324 | applet.setSize(100,100); |
| 325 | applet.init(); |
| 326 | } |
| 327 | |
| 328 | if (needDummies) { |
| 329 | ((BeansAppletStub)stub).active = true; |
| 330 | } else initializer.activate(applet); |
| 331 | |
| 332 | } else if (beanContext != null) beanContext.add(result); |
| 333 | } |
| 334 | |
| 335 | return result; |
| 336 | } |
| 337 | |
| 338 | |
| 339 | /** |
| 340 | * From a given bean, obtain an object representing a specified |
| 341 | * type view of that source object. |
| 342 | * <p> |
| 343 | * The result may be the same object or a different object. If |
| 344 | * the requested target view isn't available then the given |
| 345 | * bean is returned. |
| 346 | * <p> |
| 347 | * This method is provided in Beans 1.0 as a hook to allow the |
| 348 | * addition of more flexible bean behaviour in the future. |
| 349 | * |
| 350 | * @param bean Object from which we want to obtain a view. |
| 351 | * @param targetType The type of view we'd like to get. |
| 352 | * |
| 353 | */ |
| 354 | public static Object getInstanceOf(Object bean, Class<?> targetType) { |
| 355 | return bean; |
| 356 | } |
| 357 | |
| 358 | /** |
| 359 | * Check if a bean can be viewed as a given target type. |
| 360 | * The result will be true if the Beans.getInstanceof method |
| 361 | * can be used on the given bean to obtain an object that |
| 362 | * represents the specified targetType type view. |
| 363 | * |
| 364 | * @param bean Bean from which we want to obtain a view. |
| 365 | * @param targetType The type of view we'd like to get. |
| 366 | * @return "true" if the given bean supports the given targetType. |
| 367 | * |
| 368 | */ |
| 369 | public static boolean isInstanceOf(Object bean, Class<?> targetType) { |
| 370 | return Introspector.isSubclass(bean.getClass(), targetType); |
| 371 | } |
| 372 | |
| 373 | |
| 374 | /** |
| 375 | * Test if we are in design-mode. |
| 376 | * |
| 377 | * @return True if we are running in an application construction |
| 378 | * environment. |
| 379 | * |
| 380 | * @see java.beans.DesignMode |
| 381 | */ |
| 382 | public static boolean isDesignTime() { |
| 383 | return designTime; |
| 384 | } |
| 385 | |
| 386 | /** |
| 387 | * Determines whether beans can assume a GUI is available. |
| 388 | * |
| 389 | * @return True if we are running in an environment where beans |
| 390 | * can assume that an interactive GUI is available, so they |
| 391 | * can pop up dialog boxes, etc. This will normally return |
| 392 | * true in a windowing environment, and will normally return |
| 393 | * false in a server environment or if an application is |
| 394 | * running as part of a batch job. |
| 395 | * |
| 396 | * @see java.beans.Visibility |
| 397 | * |
| 398 | */ |
| 399 | public static boolean isGuiAvailable() { |
| 400 | return guiAvailable; |
| 401 | } |
| 402 | |
| 403 | /** |
| 404 | * Used to indicate whether of not we are running in an application |
| 405 | * builder environment. |
| 406 | * |
| 407 | * <p>Note that this method is security checked |
| 408 | * and is not available to (for example) untrusted applets. |
| 409 | * More specifically, if there is a security manager, |
| 410 | * its <code>checkPropertiesAccess</code> |
| 411 | * method is called. This could result in a SecurityException. |
| 412 | * |
| 413 | * @param isDesignTime True if we're in an application builder tool. |
| 414 | * @exception SecurityException if a security manager exists and its |
| 415 | * <code>checkPropertiesAccess</code> method doesn't allow setting |
| 416 | * of system properties. |
| 417 | * @see SecurityManager#checkPropertiesAccess |
| 418 | */ |
| 419 | |
| 420 | public static void setDesignTime(boolean isDesignTime) |
| 421 | throws SecurityException { |
| 422 | SecurityManager sm = System.getSecurityManager(); |
| 423 | if (sm != null) { |
| 424 | sm.checkPropertiesAccess(); |
| 425 | } |
| 426 | designTime = isDesignTime; |
| 427 | } |
| 428 | |
| 429 | /** |
| 430 | * Used to indicate whether of not we are running in an environment |
| 431 | * where GUI interaction is available. |
| 432 | * |
| 433 | * <p>Note that this method is security checked |
| 434 | * and is not available to (for example) untrusted applets. |
| 435 | * More specifically, if there is a security manager, |
| 436 | * its <code>checkPropertiesAccess</code> |
| 437 | * method is called. This could result in a SecurityException. |
| 438 | * |
| 439 | * @param isGuiAvailable True if GUI interaction is available. |
| 440 | * @exception SecurityException if a security manager exists and its |
| 441 | * <code>checkPropertiesAccess</code> method doesn't allow setting |
| 442 | * of system properties. |
| 443 | * @see SecurityManager#checkPropertiesAccess |
| 444 | */ |
| 445 | |
| 446 | public static void setGuiAvailable(boolean isGuiAvailable) |
| 447 | throws SecurityException { |
| 448 | SecurityManager sm = System.getSecurityManager(); |
| 449 | if (sm != null) { |
| 450 | sm.checkPropertiesAccess(); |
| 451 | } |
| 452 | guiAvailable = isGuiAvailable; |
| 453 | } |
| 454 | |
| 455 | |
| 456 | private static boolean designTime; |
| 457 | private static boolean guiAvailable; |
| 458 | static { |
| 459 | guiAvailable = !GraphicsEnvironment.isHeadless(); |
| 460 | } |
| 461 | } |
| 462 | |
| 463 | /** |
| 464 | * This subclass of ObjectInputStream delegates loading of classes to |
| 465 | * an existing ClassLoader. |
| 466 | */ |
| 467 | |
| 468 | class ObjectInputStreamWithLoader extends ObjectInputStream |
| 469 | { |
| 470 | private ClassLoader loader; |
| 471 | |
| 472 | /** |
| 473 | * Loader must be non-null; |
| 474 | */ |
| 475 | |
| 476 | public ObjectInputStreamWithLoader(InputStream in, ClassLoader loader) |
| 477 | throws IOException, StreamCorruptedException { |
| 478 | |
| 479 | super(in); |
| 480 | if (loader == null) { |
| 481 | throw new IllegalArgumentException("Illegal null argument to ObjectInputStreamWithLoader"); |
| 482 | } |
| 483 | this.loader = loader; |
| 484 | } |
| 485 | |
| 486 | /** |
| 487 | * Use the given ClassLoader rather than using the system class |
| 488 | */ |
| 489 | protected Class resolveClass(ObjectStreamClass classDesc) |
| 490 | throws IOException, ClassNotFoundException { |
| 491 | |
| 492 | String cname = classDesc.getName(); |
| 493 | return ClassFinder.resolveClass(cname, this.loader); |
| 494 | } |
| 495 | } |
| 496 | |
| 497 | /** |
| 498 | * Package private support class. This provides a default AppletContext |
| 499 | * for beans which are applets. |
| 500 | */ |
| 501 | |
| 502 | class BeansAppletContext implements AppletContext { |
| 503 | Applet target; |
| 504 | java.util.Hashtable imageCache = new java.util.Hashtable(); |
| 505 | |
| 506 | BeansAppletContext(Applet target) { |
| 507 | this.target = target; |
| 508 | } |
| 509 | |
| 510 | public AudioClip getAudioClip(URL url) { |
| 511 | // We don't currently support audio clips in the Beans.instantiate |
| 512 | // applet context, unless by some luck there exists a URL content |
| 513 | // class that can generate an AudioClip from the audio URL. |
| 514 | try { |
| 515 | return (AudioClip) url.getContent(); |
| 516 | } catch (Exception ex) { |
| 517 | return null; |
| 518 | } |
| 519 | } |
| 520 | |
| 521 | public synchronized Image getImage(URL url) { |
| 522 | Object o = imageCache.get(url); |
| 523 | if (o != null) { |
| 524 | return (Image)o; |
| 525 | } |
| 526 | try { |
| 527 | o = url.getContent(); |
| 528 | if (o == null) { |
| 529 | return null; |
| 530 | } |
| 531 | if (o instanceof Image) { |
| 532 | imageCache.put(url, o); |
| 533 | return (Image) o; |
| 534 | } |
| 535 | // Otherwise it must be an ImageProducer. |
| 536 | Image img = target.createImage((java.awt.image.ImageProducer)o); |
| 537 | imageCache.put(url, img); |
| 538 | return img; |
| 539 | |
| 540 | } catch (Exception ex) { |
| 541 | return null; |
| 542 | } |
| 543 | } |
| 544 | |
| 545 | public Applet getApplet(String name) { |
| 546 | return null; |
| 547 | } |
| 548 | |
| 549 | public java.util.Enumeration getApplets() { |
| 550 | java.util.Vector applets = new java.util.Vector(); |
| 551 | applets.addElement(target); |
| 552 | return applets.elements(); |
| 553 | } |
| 554 | |
| 555 | public void showDocument(URL url) { |
| 556 | // We do nothing. |
| 557 | } |
| 558 | |
| 559 | public void showDocument(URL url, String target) { |
| 560 | // We do nothing. |
| 561 | } |
| 562 | |
| 563 | public void showStatus(String status) { |
| 564 | // We do nothing. |
| 565 | } |
| 566 | |
| 567 | public void setStream(String key, InputStream stream)throws IOException{ |
| 568 | // We do nothing. |
| 569 | } |
| 570 | |
| 571 | public InputStream getStream(String key){ |
| 572 | // We do nothing. |
| 573 | return null; |
| 574 | } |
| 575 | |
| 576 | public java.util.Iterator getStreamKeys(){ |
| 577 | // We do nothing. |
| 578 | return null; |
| 579 | } |
| 580 | } |
| 581 | |
| 582 | /** |
| 583 | * Package private support class. This provides an AppletStub |
| 584 | * for beans which are applets. |
| 585 | */ |
| 586 | class BeansAppletStub implements AppletStub { |
| 587 | transient boolean active; |
| 588 | transient Applet target; |
| 589 | transient AppletContext context; |
| 590 | transient URL codeBase; |
| 591 | transient URL docBase; |
| 592 | |
| 593 | BeansAppletStub(Applet target, |
| 594 | AppletContext context, URL codeBase, |
| 595 | URL docBase) { |
| 596 | this.target = target; |
| 597 | this.context = context; |
| 598 | this.codeBase = codeBase; |
| 599 | this.docBase = docBase; |
| 600 | } |
| 601 | |
| 602 | public boolean isActive() { |
| 603 | return active; |
| 604 | } |
| 605 | |
| 606 | public URL getDocumentBase() { |
| 607 | // use the root directory of the applet's class-loader |
| 608 | return docBase; |
| 609 | } |
| 610 | |
| 611 | public URL getCodeBase() { |
| 612 | // use the directory where we found the class or serialized object. |
| 613 | return codeBase; |
| 614 | } |
| 615 | |
| 616 | public String getParameter(String name) { |
| 617 | return null; |
| 618 | } |
| 619 | |
| 620 | public AppletContext getAppletContext() { |
| 621 | return context; |
| 622 | } |
| 623 | |
| 624 | public void appletResize(int width, int height) { |
| 625 | // we do nothing. |
| 626 | } |
| 627 | } |