Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4306573

Allow class methods to be specified by interfaces

    Details

    • Type: Enhancement
    • Status: Closed
    • Priority: P4
    • Resolution: Duplicate
    • Affects Version/s: 1.3.0
    • Fix Version/s: None
    • Component/s: specification
    • Labels:
    • Subcomponent:
    • CPU:
      x86
    • OS:
      windows_98

      Description



      Name: krT82822 Date: 01/22/2000


      java version "1.3beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3beta-O)
      Java(TM) HotSpot Client VM (build 1.3beta-O, mixed mode)

      This feature would be useful for a number of reasons. In our current project
      here, we have an interface that describes the API
      certain "pluggable" classes must support. Each of these classes is a document
      class, and its instances are document objects; the classes are vended by a
      module that keeps track of installed additional document classes; the UI sees
      the resulting class objects and lists them for the user to choose from when
      making a new document -- this requires being able to get a localized name for
      the document type, so instead of theClass.getName() we would like to be able to
      get the class object cast by the interface it must follow and then invoke a
      class method like "getTypeName()" on it. Except you can't specify a class
      method in an interface. There are several other introspection-like options of a
      similar nature as well. Not to mention the need to get the class to vend a
      blank document when the new command is invoked!

      Right now we're doing this by specifying instance methods and doc commenting
      that implementations should treat them as class methods. Get name, get blank
      document, etc. We also demand that a low-cost dummy object be made by a no-
      argument constructor in order to get an instance to invoke tbese methods on.
      This is an ugly hack.

      Saving and loading is easy though, thanks to the serialization API. The
      deserialized object is cast to our interface and interface-specified methods
      are used to make it vend viewer and editor components that can be woven into
      the application's GUI to display the newly opened document. (Mainly, there's a
      getViewWindow that vends a JInternalFrame for adding to a desktop -- different
      document classes can vend view/edit internal frames specially suited to their
      specific content.)

      Yes, we have heard of beans. No, we don't want to build our app that way --
      machine-generated code such as application builders and GUI builders
      manufacture is a horrendous mess to debug or change, and builder programs cost
      a fortune anyways.

      Unless beans can be used to provide plug in functionality without using
      builders or the typical architecture builders produce, and unless beans can be
      * shipped in a jar or other package with a bunch of associated files, such as
        HelpSets, resource bundles, and icons and other media
      * installed within an application by having the app, when pointed to one and
        told to install it, installing the thing and all its satellite files
      * used to distribute only added documentation or localized resource bundles
        without new code
      * uninstalled as easily, the helpsets unmerged, the files removed, etc.
      we must stick to our current method, which will be to have the installer
      function inspect jar files for certain contents, e.g. HelpSets, .bundle files,
      and .class files containing classes that have certain properties (public
      concrete no-arg constructor and using our interface).

      (We also wound up with the issue of how an app can dynamically change its class
      path to include new jars at run time and with persistence.)

      -------------------------

      1/22/2000 in reply to a request for sample usage of such a feature, user supplied this code (and noted a workaround -- see "Workaround" section):


      public interface MyDocPluginInterface {

        // ...

        public static PluginInfo getPluginInfo (); // Currently illegal!
        public static MyDocPluginInterface getBlankDocument ();

        // ...
      }

      public abstract class PluginManager {

        // ...

        public static void showDocTypeSelectionUI (JFrame where,
           TypeSelectionCallback c) { ... }
        public static void showDocTypeSelectionUI (JInternalFrame where,
           TypeSelectionCallback c) { ... }
        public static void newDocument (JDesktopPane where) {
          if (where == null) {
            showDocTypeSelectionUI (new JFrame("New Document"), new
               PMTypeSelectionCallback(where));
            return;
          }
          JInternalFrame i = new JInternalFrame("New Document");
          where.add(i);
          showDocTypeSelectionUI (i, new PMTypeSelectionCallback(where));
        }

        private static class PMTypeSelectionCallback implements
         TypeSelectionCallback {
          private JDesktopPane where;
          PMTypeSelectionCallback (JDesktopPane where) {
            this.where = where;
          }
          public void typeSelected (Class type) {
            // Here's the kicker
            MyDocPluginInterface doc;
            try {
               doc = (MyDocPluginInterface)
                type.getDeclaredMethod("getBlankDocument",new Class[]
                {}).invoke(null, new Object[] {});
            } catch (Exception e) {
              // Can't happen because type implements MyDocPluginInterface!
            }
            if (where == null) {
              doc.showEditUI(new JFrame("Untitled"));
              return;
            }
            JInternalFrame i = new JInternalFrame("Untitled");
            where.add(i);
            doc.showEditUI(i);
          }
        }
      }


      (Review ID: 99754)
      ======================================================================

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                gbrachasunw Gilad Bracha (Inactive)
                Reporter:
                kryansunw Kevin Ryan (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: