home *** CD-ROM | disk | FTP | other *** search
/ Symantec Visual Cafe for Java 2.5 / symantec-visual-cafe-2.5-database-dev-edition.iso / VCafe / prosrc.bin / JDBCBean.java < prev    next >
Encoding:
Java Source  |  1998-03-18  |  21.0 KB  |  563 lines

  1.  
  2. /*
  3.  * @(#)JDBCBean.java
  4.  *
  5.  * Copyright (c) 1997 Symantec Corporation. All Rights Reserved.
  6.  *
  7.  */
  8.  
  9.  
  10. //package symantec.itools.db.beans;
  11. package symantec.itools.db.beans.jdbc;
  12. import java.io.*;
  13. import java.beans.*;
  14. import java.util.*;
  15. import java.sql.SQLException ;
  16.  
  17.  
  18. /**
  19.  * <P>The base class for all Symantec JDBC Beans.
  20.  * This class may be removed as hierarchy matures. Decision to change the hierarchy
  21.  * should be made early into development cycle to avoid deserialization problems.
  22.  *
  23.  * Provides PropertyChange and VetoableChange event registration and processing,
  24.  * validateObject, versioning, serialization, localization
  25.  *
  26.  * A protected handleException  method is provided. All exceptions should be routed
  27.  * through this method. Beans should be real user friendly. Eating exceptions and taking
  28.  * appropriate behavior is ideal for users. Note: Not sure if Exception specifications
  29.  * should be removed from all methods.
  30.  *
  31.  * Since bean will be used in client GUI apps and applets now, and on application server
  32.  * (non-GUI) later, JDBCBean implements the Visibility interface. Descendents can check
  33.  * protected variable guiAvailable to see if a GUI is available to use.
  34.  *
  35.  * A ResourceBundle is loaded and stored for localized strings. Please place all strings
  36.  * in symantec.itools.db.beans.res.StringResources.properties file. This is the default
  37.  * version. Special Localized versions (StringResources_ja_JP.properties) should copy this
  38.  * default and then localized the strings with a UNICODE editor. A method to get a string
  39.  * from the resourcebundle is defined.
  40.  *
  41.  * Note: Description property could be provided by BeanInfo/BeanDescriptor class.
  42.  * Added here for ease of use.
  43.  *
  44.  * Note: Name property provided because this is an invisible bean. This property
  45.  * could be removed if JDBCBean changed to extend Component.
  46.  *
  47.  * Versioning should be check on each level of the hierarchy, allowing for maximum
  48.  * flexibility of modifying objects. Please take care when modifying all serializable
  49.  * objects to conform with java versioning guidelines.
  50.  *
  51.  * @see java.io.Serializable
  52.  * @see java.beans.VetoableChangeListener
  53.  * @see java.beans.PropertychangeListener
  54.  * @see java.io.ObjectInputValidation
  55.  * @see java.beans.Visibility
  56.  * @see java.utils.ResourceBundle
  57.  *
  58.  */
  59.  
  60. public class JDBCBean implements Serializable,
  61.                                  VetoableChangeListener,
  62.                                  PropertyChangeListener,
  63.                                  ObjectInputValidation,
  64.                                  Visibility {
  65.  
  66. //PUBLIC SECTION
  67.  
  68. //Static Declarations
  69.  
  70. //Constructors
  71.     /**
  72.      * Default constructor. Bean-aware IDE's and serialization require all beans
  73.      * have a default constructor.
  74.      */
  75.     public JDBCBean () {
  76.         name        = "" ;
  77.         description = "" ;
  78.         debug       = false ;
  79.         autoStart   = false ;
  80.     }
  81.  
  82.     /**
  83.      * Constructor. Beans should provide a constructor with commonly-used properties
  84.      * as parameters.  This allows the beans to be constructed programatically without
  85.      * having to call the properties' setter methods.
  86.      *
  87.      * @param       name.           The user-defined label for the bean.
  88.      * @param       description.    A string that provides a description of the bean
  89.      * @param       debug.          A boolean indicating whether bean is under development
  90.      * @param       autoStart.      A boolean indicating whether the bean should be
  91.      *                                  data-connected after de-serialization.
  92.      */
  93.     public JDBCBean (String name, String description,boolean debug,boolean autoStart) {
  94.         setName(name);
  95.         setDescription(description);
  96.         setDebug(debug);
  97.         setAutoStart(autoStart);
  98.     }
  99.  
  100.  
  101. //Methods
  102. //Accessors/Modifiers
  103.     /**
  104.      * Sets the name property. The property is bound, so a PropertyChangeEvent will
  105.      * be sent to registered ProperyChange listeners.
  106.      *
  107.      * @param       name. The user-defined label of the bean.
  108.      *
  109.      */
  110.     public void setName (String name) {
  111.         processPropertyChange(PROP_NAME,this.name,name);
  112.         this.name = name ;
  113.     }
  114.  
  115.     /**
  116.      * Gets the name property.
  117.      * @return      The user-defined label for the bean.
  118.      */
  119.     public String getName () {
  120.         return name;
  121.     }
  122.  
  123.     /**
  124.      * Sets the desription property. The property is bound, so a PropertyChangeEvent will
  125.      * be sent to registered ProperyChange listeners.
  126.      *
  127.      * @param       description. The user-defined description of the bean.
  128.      *
  129.      */
  130.     public void setDescription (String description) {
  131.         processPropertyChange(PROP_DESCRIPTION,this.description,description);
  132.         this.description = description ;
  133.     }
  134.  
  135.     /**
  136.      * Gets the description property.
  137.      *
  138.      * @return      The user-defined description of the bean.
  139.      */
  140.     public String getDescription () {
  141.         return description ;
  142.     }
  143.  
  144.     /**
  145.      * Sets the debug property. The property is bound, so a PropertyChangeEvent will
  146.      * be sent to registered ProperyChange listeners.
  147.      *
  148.      * @param       debug.  A flag indicating whether the bean is under development.
  149.      *                      If debug is true, special messages will be sent to system.out stream.
  150.      *                      False suppresses these messages.
  151.      *
  152.      */
  153.     public void setDebug (boolean debug) {
  154.         processPropertyChange(PROP_DEBUG,new Boolean(this.debug),new Boolean(debug));
  155.         this.debug = debug ;
  156.     }
  157.  
  158.     /**
  159.      * Gets the debug property.
  160.      *
  161.      * @return      The value of the debug property.
  162.      */
  163.     public boolean isDebug () {
  164.         return debug ;
  165.     }
  166.  
  167.     /**
  168.      * Sets the autoStart property. The property is bound, so a PropertyChangeEvent will
  169.      * be sent to registered ProperyChange listeners.
  170.      *
  171.      * @param       autoStart.  Due to the complexity of establishing database connections,
  172.      *              JDBCBeans are not 'live' by default. When the autoStart property is true,
  173.      *              JDBCBean will call doAutoStart() during the de-serialization process.
  174.      *              Descendents of JDBCBean should override the doAutoStart() method if they
  175.      *              want to be notified when to go 'live'.
  176.      *
  177.      */
  178.     public void setAutoStart (boolean autoStart) {
  179.         processPropertyChange(PROP_AUTOSTART,new Boolean(this.autoStart),new Boolean(autoStart));
  180.         this.autoStart = autoStart ;
  181.     }
  182.  
  183.     /**
  184.      * Gets the autoStart property.
  185.      * @return      The value of the autoStart property.
  186.      */
  187.     public boolean isAutoStart () {
  188.         return autoStart ;
  189.     }
  190.  
  191.  
  192. //Visibility interface implementation
  193.     /**
  194.     * Implementation of the Visibility interface. This method should return true if
  195.     * the bean absolutely needs a GUI available in order to get its work done.
  196.     *
  197.     * @return       False. We should not be dependent on a GUI to get our work done.
  198.     *               JDBCBeans on a server may not have a GUI available.
  199.     */
  200.     public boolean needsGui() {
  201.         return false ;
  202.     }
  203.  
  204.     /**
  205.     * Implementation of the Visibilty interface. This method instructs the bean
  206.     * that it should not use the Gui. This method sets the guiAvailable protected member
  207.     * to false. Descendents of JDBCBean can use the guiAvailable member
  208.     * to determine if a GUI is available.
  209.     */
  210.     public void dontUseGui() {
  211.         guiAvailable = false ;
  212.     }
  213.  
  214.     /**
  215.     * Implementation of the Visibilty interface. This method instructs the bean
  216.     * that it is OK to use the Gui.  This method sets the guiAvailable protected member
  217.     * to true. Descendents of JDBCBean can use the guiAvailable member
  218.     * to determine if a GUI is available.
  219.     */
  220.     public void okToUseGui() {
  221.         guiAvailable = true ;
  222.     }
  223.  
  224.     /**
  225.     * Implementation of the Visibilty interface.  This method returns true if the bean
  226.     * is currently avoiding use of the Gui.  e.g. due to a call on dontUseGui().
  227.     * @return       false. We should not be dependent on a GUI to get our work done.
  228.     *               JDBCBeans on a server may not have a GUI available.
  229.     */
  230.     public boolean avoidingGui() {
  231.         return false ;
  232.     }
  233.  
  234.  
  235.  
  236. //Event sources
  237.     /**
  238.      * Adds PropertyChangeListeners to internal list so that they could be sent
  239.      * PropertyChangeEvents when a bound property is changed.
  240.      *
  241.      * @param       l. An object implementing the PropertyChangeListener interface.
  242.      *
  243.      */
  244.     public void addPropertyChangeListener (PropertyChangeListener l) {
  245.         boundChanges.addPropertyChangeListener(l);
  246.     }
  247.  
  248.     /**
  249.      * Removes PropertChangeListeners from an internal list.  The object will no longer
  250.      * be sent PropertyChangeEvents when a bound property changes.
  251.      *
  252.      * @param       l. The PropertyChangeListener to remove.
  253.      *
  254.      */
  255.     public void removePropertyChangeListener (PropertyChangeListener l) {
  256.         boundChanges.removePropertyChangeListener(l);
  257.     }
  258.  
  259.     /**
  260.      * Adds a VetoableChangeListener to an internal list so that they could be sent
  261.      * VetoableChangeEvents when a constrained property is changed.
  262.      *
  263.      * @param       l. An object implementing the VetoableChangeListener interface.
  264.      *
  265.      */
  266.     public void addVetoableChangeListener (VetoableChangeListener l) {
  267.         vetoChanges.addVetoableChangeListener(l);
  268.     }
  269.  
  270.     /**
  271.      * Removes a VetoableChangeListener from an internal list. The object will no longer
  272.      * be sent VetoableChangeEvents when a constrined property is changed.
  273.      *
  274.      * @param       l. The VetoableChangeListener to remove.
  275.      *
  276.      */
  277.     public void removeVetoableChangeListener (VetoableChangeListener l) {
  278.         vetoChanges.removeVetoableChangeListener(l);
  279.     }
  280.  
  281. //Event listeners
  282.     /**
  283.      * Implementation of the VetoableChangeListener interface.  JDBCBeans can be registered
  284.      * with objects that are a source of VetoableChangeEvents. The default behavior is to
  285.      * allow the VetoableChange by not throwing a PropertyVetoException. Descendents of
  286.      * JDBCBean should override this method to respond to VetoableChangeEvents.
  287.      *
  288.      * @param       evt. The PropertyChangeEvent describing the constrained property.
  289.      *
  290.      * @exception   PropertyVetoException.
  291.      */
  292.     public void vetoableChange (PropertyChangeEvent evt) throws PropertyVetoException {
  293.  
  294.     }
  295.  
  296.     /**
  297.      * Implementation of the PropertyChangeListener interface.  JDBCBeans can be registered
  298.      * with objects that are a source of PropertyChangeEvents. The default behavior is to do
  299.      * nothing. Descendents of JDBCBean should override this method to respond to
  300.      * PropertyChangeEvents,
  301.      *
  302.      * @param       evt. The PropertyChangeEvent describing the bound property.Describe params here
  303.      *
  304.      */
  305.     public void propertyChange (PropertyChangeEvent evt) {
  306.  
  307.     }
  308.  
  309. //Serialization
  310.     /**
  311.      * Implementation of the ObjectInputValidation interface. During the de-serialization
  312.      * process, registered ObjectInputValidation objects will have the validateObject method
  313.      * called after the object and its graph are completely de-serialized. JDBCBeans
  314.      * and their descendents should verify that the de-serialized object is of a version
  315.      * that is compatible with the current implementation. Each level of the hierarchy should
  316.      * provide their own versioning information. Descendents should check their version first
  317.      * and then call their superclass's validateObject method. JDBCBean will verify its version
  318.      * and then check the state of the property autoStart. If autoStart is true,
  319.      * doAutoStart is called. Descendents can override doAutoStart() if they
  320.      * want to be notified when to go 'live'. Any lengthy processing should be done
  321.      * in a separate thread. Exceptions shouldn't be thrown back to ObjectInputStream.
  322.      * Instead, do appropriate resetting of the object, so that the de-serialization process
  323.      * can continue, allowing the user to change any properties in an IDE that may have
  324.      * caused the Exception.
  325.      *
  326.      *
  327.      * @see JDBCBean#setAutoStart
  328.      * @see JDBCBean#doAutoStart
  329.      *
  330.      *
  331.      * @exception   InvalidObjectException
  332.      */
  333.     public void validateObject () throws InvalidObjectException {
  334.         if (!version.equals(JDBCBean.CURRENTVERSION))
  335.             throw new InvalidObjectException ("Serialized version " +
  336.                             version + "is not compatible with JDBCBean version " +
  337.                             JDBCBean.CURRENTVERSION);
  338.  
  339.         //Object is completely deserialized. If autoStart, call doAutoStart method
  340.         //Eat all Exceptions so that problem can be resolved in IDE. Remember that
  341.         // validate object is called while deserializing. Don't want to crash now or
  342.         //user won't ever be able to change object.
  343.         try {
  344.             if (isAutoStart())
  345.                 doAutoStart();
  346.         }
  347.         catch (Exception e) {
  348.             printMessage ("Exception thrown during de-serialization: " + e.toString());
  349.         }
  350.     }
  351.  
  352.     /**
  353.      * Convert the bean to a string object
  354.      *
  355.      * @return      A concatenation of the JDBCBean name and description properties.
  356.      */
  357.     public synchronized String toString () {
  358.         return getName() + ":  " + getDescription();
  359.     }
  360.  
  361. //PROTECTED SECTION
  362. //Static Declarations
  363.     //Programatic names of properties -- Not localizable
  364.     protected static String PROP_NAME           = "name" ;
  365.     protected static String PROP_DESCRIPTION    = "description" ;
  366.     protected static String PROP_DEBUG          = "debug" ;
  367.     protected static String PROP_AUTOSTART      = "autoStart" ;
  368.  
  369.  
  370. //Constructors
  371.  
  372. //Methods
  373.     /**
  374.      * Exception handling method. All SQLExceptions are routed to this method to allow
  375.      * for suppression or logging of Exceptions. The default behavior is to rethrow the
  376.      * Exception. Descendents of JDBCBean can override this method to provide their own
  377.      * exception logging.
  378.      *
  379.      * @param       The SQLException that was thrown
  380.      *
  381.      * @exception   SQLException.
  382.      */
  383.     protected void handleException (SQLException e) throws SQLException {
  384.         if (isDebug()) {
  385.             printMessage("Exception thrown: " + e.toString());
  386.             printMessage("Stack Trace: " );
  387.             e.printStackTrace();
  388.         }
  389.         throw e ;
  390.     }
  391.  
  392.     /**
  393.      * Message handling method. All printable messages should be routed through
  394.      * this method. The default behavior is to send the string to system.out if
  395.      * the debug property is true.
  396.      *
  397.      * @param       The message to print.
  398.      *
  399.      */
  400.     protected void printMessage (String message ) {
  401.         if (isDebug())
  402.             System.out.println (message);
  403.     }
  404.  
  405.     /**
  406.      * This method will be called during the de-serialization process if the
  407.      * autoStart property is true. Descendents can override this method if they want
  408.      * to be notified when to go 'live'. Processing should be kept to a minimum or
  409.      * done in a separate thread. Exceptions should be suppressed to allow
  410.      * de-serialization to complete.
  411.      *
  412.      */
  413.     protected void doAutoStart() {
  414.     }
  415.  
  416.  
  417.     /**
  418.      * Retrieves a localized string from a ResourceBundle based on a key.
  419.      * There should be no hard-coded strings within JDBCBeans. All strings should
  420.      * be assigned a key and both the key and the string should be placed within
  421.      * the symantec.itools.db.beans.res.StringResources.properties file.
  422.      * This method will eat all exceptions.
  423.      *
  424.      * @param       key. A string key that is associated with desired resource string.
  425.      *
  426.      * @return      The string associated with the key.
  427.      */
  428.     protected String getResString (String key ) {
  429.         //Eat Exceptions and return
  430.         String str = "String Resource Error";
  431.         try {
  432.             str = getResourceBundle().getString(key);
  433.         }
  434.         catch (Exception e) {
  435.             printMessage("Exception caught: " + e.toString());
  436.         }
  437.  
  438.         return str ;
  439.     }
  440.  
  441.     /**
  442.      * Returns the ResourceBundle containing the localized set of strings.
  443.      * Normally, calling getResString should be used to access a localized string.
  444.      * This method is provided to get direct access to the ResourceBundle.
  445.      *
  446.      * @return      ResourceBundle
  447.      * @exception   MissingResourceException
  448.      */
  449.     protected ResourceBundle getResourceBundle () throws MissingResourceException {
  450.         //although ResourceBundle caches bundles, keep a reference for this object
  451.         //this method may be called frequently
  452.         if (stringResources == null)
  453.             stringResources = ResourceBundle.getBundle("symantec.itools.db.beans.res.StringResources");
  454.  
  455.         return stringResources ;
  456.     }
  457.  
  458. //Accessors/Modifiers
  459. //Event sources
  460.     /**
  461.      * A helper method to fire PropertyChangedEvents for bound properties. JDBCBean class
  462.      * handles the adding and removing of PropertyChangeListeners. This method is provided
  463.      * for descendents to fire PropertyChangedEvents to registered listeners.
  464.      *
  465.      * @param       propertyName.   The name of the property that was changed.
  466.      * @param       oldValue.       Object containing the old value
  467.      * @param       newValue        Object containing the new value.
  468.      *
  469.      */
  470.     protected void processPropertyChange(String propertyName, Object oldValue,Object newValue) {
  471.         printMessage ("BOUND PROPERTY " + propertyName + " CHANGED FROM " + oldValue +
  472.                       " TO " + newValue );
  473.         boundChanges.firePropertyChange(propertyName,oldValue,newValue);
  474.     }
  475.  
  476.     /**
  477.      * A helper method to fire VetoableChangedEvents for constrained properties. JDBCBean class
  478.      * handles the adding and removing of VetoableChangeListeners. This method is provided
  479.      * for descendents to fire VetoableChangedEvents to registered listeners.
  480.      *
  481.      * @param       propertyName    The name of the property that was changed.
  482.      * @param       oldValue        Object containing the old value.
  483.      * @param       newValue        Object containing the new value
  484.      *
  485.      * @exception   PropertyVetoException
  486.      */
  487.     protected void processVetoableChange(String propertyName, Object oldValue,Object newValue)
  488.                                          throws PropertyVetoException {
  489.         printMessage ("ATTEMPTING TO CHANGE CONSTRAINED PROPERTY " + propertyName + " FROM " + oldValue +
  490.                       " TO " + newValue );
  491.         try {
  492.             vetoChanges.fireVetoableChange(propertyName,oldValue,newValue);
  493.         } catch (PropertyVetoException e) {
  494.             printMessage ("ATTEMPT TO CHANGE CONSTRAINED PROPERTY " + propertyName + " FAILED");
  495.             throw e ;
  496.         }
  497.  
  498.         printMessage("ATTEMPT TO CHANGE CONSTRAINED PROPERTY " + propertyName + " SUCCEEDED");
  499.  
  500.     }
  501.  
  502.  
  503.  
  504. //Event listeners
  505. //Serialization
  506.  
  507.  
  508. //PRIVATE SECTION
  509. //Static Declarations
  510.     //The current version of JDBCBean
  511.     static private String CURRENTVERSION = "0.01" ;
  512.  
  513. //Constructors
  514. //Methods
  515. //Accessors/Modifiers
  516. //Event sources
  517. //Event listeners
  518. //Serialization
  519.     /**
  520.      * During the serialization process, ObjectOutputStream will call this method.
  521.      * By default, ObjectOutputStream.defaultWriteObject is called.
  522.      *
  523.      * @param       stream      The ObjectOutputStream controlling the serialization.
  524.      */
  525.     private void writeObject (ObjectOutputStream stream) throws IOException {
  526.         stream.defaultWriteObject();
  527.     }
  528.  
  529.     /**
  530.      * During the de-serialization process, ObjectInputStream will call this method.
  531.      * JDBCBean will register this object for ObjectInputValidation and then call
  532.      * ObjectInputStream.defaultReadObject.  When the entire object is de-serialized,
  533.      * the validateObject method will be called.
  534.      *
  535.      * @param       stream      The ObjectInputStream controlling the de-serialization.
  536.      *
  537.      * @exception   ClassNotFoundException, IOException
  538.      */
  539.     private void readObject (ObjectInputStream stream) throws ClassNotFoundException,
  540.                                                               IOException {
  541.         stream.registerValidation(this,0);
  542.         stream.defaultReadObject();
  543.     }
  544.  
  545.  
  546. //Members
  547.     private String  version     = JDBCBean.CURRENTVERSION ;
  548.     private String  name        = "";
  549.     private String  description = "" ;
  550.     private boolean debug       = false ;
  551.     private boolean autoStart   = false ;
  552.  
  553.     //Support classes
  554.     private PropertyChangeSupport boundChanges = new PropertyChangeSupport(this);
  555.     private VetoableChangeSupport vetoChanges  = new VetoableChangeSupport(this);
  556.  
  557.     //Indicates whether a GUI is available.
  558.     protected transient boolean guiAvailable  = false ;
  559.  
  560.     //Localized strings for Internationalization
  561.     protected transient ResourceBundle stringResources = null ;
  562.  
  563. }