Class DefaultObjectHandler

  • All Implemented Interfaces:
    TagHandler
    Direct Known Subclasses:
    BeanValidatorHandler, DefaultComponentHandler, TabHandler, TabWithValidatorHandler

    public class DefaultObjectHandler
    extends Object
    implements TagHandler
    Default handler for class tags. Class tags are tags which represent instances of Java classes, such as <JButton label='Close'/>. DefaultObjectHandler provides support for attributes and events which adhere to JavaBeans naming conventions as well as basic JAXX features like the id attribute and data binding by means of curly braces.

    Throughout this class, the word "member" refers to the name of a field or method (e.g. "getDocument") and the word "property" refers to the JavaBeans-style simple name of a property (e.g. "document").

    • Method Detail

      • getJAXXBeanInfo

        public static JAXXBeanInfo getJAXXBeanInfo​(ClassDescriptor beanClass)
        Returns the JAXXBeanInfo for the specified class.
        Parameters:
        beanClass - the bean class for which to retrieve JAXXBeanInfo
        Returns:
        the class' JAXXBeanInfo
      • cleanConstructorParams

        public static String cleanConstructorParams​(String value)
      • getBeanClass

        public ClassDescriptor getBeanClass()
        Returns:
        the class which this DefaultObjectHandler supports.
      • getJAXXBeanInfo

        public JAXXBeanInfo getJAXXBeanInfo()
        Returns:
        the JAXXBeanInfo for the class which this DefaultObjectHandler supports.
      • getPropertyType

        public ClassDescriptor getPropertyType​(CompiledObject object,
                                               String propertyName,
                                               JAXXCompiler compiler)
        Returns the type of the named property. This is the return type of the property's get method; for instance JLabel's text property is a String.
        Parameters:
        object - the object being compiled
        propertyName - the simple JavaBeans-style name of the property
        compiler - the current JAXXCompiler
        Returns:
        the property's type
        Throws:
        CompilerException - if the type cannot be determined
      • isMemberBound

        public boolean isMemberBound​(String name)
                              throws UnsupportedAttributeException
        Parameters:
        name - name of the property
        Returns:
        true if the named member is bound (fires PropertyChangeEvent when modified). Members are either fields (represented by the simple name of the field) or get/is methods (represented by the simple name of the method, not the simplified JavaBeans-style name). Methods which are not actually bound in their native class, but for which proxy events have been configured (such as JTextField.getText, return true.
        Throws:
        UnsupportedAttributeException - if attribute is not supported
      • configureProxyEventInfo

        protected void configureProxyEventInfo()
        Configures the event handling for members which do not fire PropertyChangeEvent when modified. The default implementation does nothing. Subclasses should override this method to call addProxyEventInfo for each member which requires special handling.
      • addProxyEventInfo

        public void addProxyEventInfo​(String memberName,
                                      Class<?> listenerClass)
        Configures a proxy event handler which fires PropertyChangeEvents when a non-bound member is updated. This is necessary for all fields (which cannot be bound) and for methods that are not bound property get methods. The proxy event handler will attach the specified kind of listener to the class and fire a PropertyChangeEvent whenever the listener receives any kind of event.

        Even though this method can theoretically be applied to fields (in addition to methods), it would be an unusual situation in which that would actually work -- as fields cannot fire events when modified, it would be difficult to have a listener that was always notified when a field value changed.

        Parameters:
        memberName - the name of the field or method being proxied
        listenerClass - the type of listener which receives events when the field or method is updated
      • addProxyEventInfo

        public void addProxyEventInfo​(String memberName,
                                      Class<?> listenerClass,
                                      String modelName)
        Configures a proxy event handler which fires PropertyChangeEvents when a non-bound member is updated. This is necessary for all fields (which cannot be bound) and for methods that are not bound property get methods. This variant attaches a listener to a property of the object (such as model) and not the object itself, which is useful when there is a model that is the "real" container of the information. The proxy event handler will attach the specified kind of listener to the property's value (retrieved using the property's get method) and fire a PropertyChangeEvent whenever the listener receives any kind of event.

        If the property is itself bound (typically the case with models), any updates to the property's value will cause the listener to be removed from the old property value and reattached to the new property value, as well as cause a PropertyChangeEvent to be fired.

        Even though this method can theoretically be applied to fields (in addition to methods), it would be an unusual situation in which that would actually work -- as fields cannot fire events when modified, it would be difficult to have a listener that was always notified when a field value changed.

        Parameters:
        memberName - the name of the field or method being proxied
        listenerClass - the type of listener which receives events when the field or method is updated
        modelName - the JavaBeans-style name of the model property
      • addProxyEventInfo

        public void addProxyEventInfo​(String memberName,
                                      Class<?> listenerClass,
                                      String modelName,
                                      String addMethod,
                                      String removeMethod)
      • addProxyEventInfo

        public void addProxyEventInfo​(String memberName,
                                      ClassDescriptor listenerClass,
                                      String modelName,
                                      String addMethod,
                                      String removeMethod)
        Configures a proxy event handler which fires PropertyChangeEvents when a non-bound member is updated. This is necessary for all fields (which cannot be bound) and for methods that are not bound property get methods. This variant attaches a listener to a property of the object (such as model) and not the object itself, which is useful when there is a model that is the "real" container of the information. The proxy event handler will attach the specified kind of listener to the property's value (retrieved using the property's get method) and fire a PropertyChangeEvent whenever the listener receives any kind of event.

        If the property is itself bound (typically the case with models), any updates to the property's value will cause the listener to be removed from the old property value and reattached to the new property value, as well as cause a PropertyChangeEvent to be fired.

        This variant of addProxyEventInfo allows the names of the methods that add and remove the event listener to be specified, in cases where the names are not simply add<listenerClassName> and remove<listenerClassName>.

        Even though this method can theoretically be applied to fields (in addition to methods), it would be an unusual situation in which that would actually work -- as fields cannot fire events when modified, it would be difficult to have a listener that was always notified when a field value changed.

        Parameters:
        memberName - the name of the field or method being proxied
        listenerClass - the type of listener which receives events when the field or method is updated
        modelName - the JavaBeans-style name of the model property
        addMethod - add method name
        removeMethod - remove method name
      • compileFirstPass

        public void compileFirstPass​(Element tag,
                                     JAXXCompiler compiler)
                              throws CompilerException,
                                     IOException
        Description copied from interface: TagHandler
        Performs the first pass of compilation on an XML tag from a JAXX source file. TagHandler implementations affect the generated .java file by calling methods in the JAXXCompiler.
        Specified by:
        compileFirstPass in interface TagHandler
        Parameters:
        tag - the XML tag to compile
        compiler - the active JAXXCompiler
        Throws:
        CompilerException - if a compilation error occurs
        IOException - if an I/O error occurs
      • compileSecondPass

        public void compileSecondPass​(Element tag,
                                      JAXXCompiler compiler)
                               throws CompilerException,
                                      IOException
        Description copied from interface: TagHandler
        Performs the second pass of compilation on an XML tag from a JAXX source file. TagHandler implementations affect the generated .java file by calling methods in the JAXXCompiler.
        Specified by:
        compileSecondPass in interface TagHandler
        Parameters:
        tag - the XML tag to compile
        compiler - the active JAXXCompiler
        Throws:
        CompilerException - if a compilation error occurs
        IOException - if an I/O error occurs
      • registerCompiledObject

        public void registerCompiledObject​(Element tag,
                                           JAXXCompiler compiler)
      • createCompiledObject

        protected CompiledObject createCompiledObject​(String id,
                                                      JAXXCompiler compiler)
        Creates the CompiledObject which will represent the object created by this TagHandler.
        Parameters:
        id - the CompiledObject's ID.
        compiler - compiler to use
        Returns:
        the CompiledObject to use
      • setDefaults

        protected void setDefaults​(CompiledObject object,
                                   Element tag,
                                   JAXXCompiler compiler)
        Initializes the default settings of the object, prior to setting its attribute values. The default implementation does nothing.
        Parameters:
        object - the object to initialize
        tag - the tag being compiled
        compiler - the current JAXXCompiler
      • isPropertyInherited

        public boolean isPropertyInherited​(String property)
                                    throws UnsupportedAttributeException
        Parameters:
        property - property name to test
        Returns:
        true if the specified property should be inherited by child components when specified via CSS.
        Throws:
        UnsupportedAttributeException - if attribute is not supported
      • isEventHandlerName

        public boolean isEventHandlerName​(String name)
        Parameters:
        name - name of event
        Returns:
        true if the specified name has the form of an event handler attribute (e.g. "onActionPerformed").
      • scanAttributesForDependencies

        protected void scanAttributesForDependencies​(Element tag,
                                                     JAXXCompiler compiler)
        Scans all attributes for any dependency classes and adds them to the current compilation set. Called by compileFirstPass() (it is an error to add dependencies after pass 1 is complete).
        Parameters:
        tag - tag to scan
        compiler - compiler to use
      • setAttributes

        public void setAttributes​(CompiledObject object,
                                  Element tag,
                                  JAXXCompiler compiler)
        Processes the attributes of an XML tag. Four kinds of attributes are supported: simple property values (of any datatype supported by convertFromString(java.lang.String, java.lang.String, java.lang.Class<?>)), data binding expressions (attributes containing curly-brace pairs), event listeners (attributes starting with 'on', such as 'onActionPerformed'), and JAXX-defined properties such as 'id'.
        Parameters:
        object - the object to be modified
        tag - the tag from which to pull attributes
        compiler - the current JAXXCompiler
      • getAttributeComparator

        protected Comparator<Attr> getAttributeComparator()
        Returns a Comparator which defines the ordering in which the tag's attributes should be processed. The default implementation sorts the attributes according to the order defined by the getAttributeOrdering(org.w3c.dom.Attr) method.
        Returns:
        a Comparator defining the order of attribute processing
      • getAttributeOrdering

        protected int getAttributeOrdering​(Attr attr)
        Returns the priority with which a particular attribute should be processed. Lower numbers should be processed before higher numbers. This value is used by the getAttributeComparator() method to define the sort ordering.
        Parameters:
        attr - the attribute to treate
        Returns:
        the attribute's priority
      • setAttributeFromCss

        public void setAttributeFromCss​(CompiledObject object,
                                        String propertyName,
                                        String stringValue,
                                        JAXXCompiler compiler)
        Set a single property on an object. The value may be either a simple value or contain data binding expressions. Simple values are first converted to the property's type using convertFromString(String, String, Class).
        Parameters:
        object - the object on which to set the property
        propertyName - the name of the property to set
        stringValue - the raw string value of the property from the XML
        compiler - the current JAXXCompiler
      • setAttribute

        public void setAttribute​(CompiledObject object,
                                 String propertyName,
                                 String stringValue,
                                 boolean inline,
                                 JAXXCompiler compiler)
        Set a single property on an object. The value may be either a simple value or contain data binding expressions. Simple values are first converted to the property's type using convertFromString(String, String, Class).
        Parameters:
        object - the object on which to set the property
        propertyName - the name of the property to set
        stringValue - the raw string value of the property from the XML
        inline - true if the value was directly specified as an inline class tag attribute, false otherwise (a default value, specified in CSS, etc.)
        compiler - the current JAXXCompiler
      • addEventHandler

        public void addEventHandler​(CompiledObject object,
                                    String name,
                                    String value,
                                    JAXXCompiler compiler)
        Adds the necessary Java code to a CompiledObject to add an event listener at runtime.
        Parameters:
        object - the CompiledObject to which the event listener should be added
        name - the name of the event listener, such as "actionPerformed"
        value - the Java code snippet to execute when the event is fired
        compiler - the current JAXXCompiler
      • getGetPropertyCode

        public String getGetPropertyCode​(String javaCode,
                                         String name,
                                         JAXXCompiler compiler)
        Returns a snippet of Java code which will retrieve an object property at runtime. Typically the code is just a call to the property's get method, but it can be arbitrarily complex.
        Parameters:
        javaCode - Java code for the object whose property is being retrieved
        name - the name of the property to retrieve
        compiler - the current JAXXCompiler
        Returns:
        the snippet
        Throws:
        CompilerException - if a compilation error occurs
      • getSetPropertyCode

        public String getSetPropertyCode​(String javaCode,
                                         String name,
                                         String valueCode,
                                         JAXXCompiler compiler)
        Returns a snippet of Java code which will set an object property at runtime. Typically the code is just a call to the property's set method, but it can be arbitrarily complex.
        Parameters:
        javaCode - Java code for the object whose property is being set
        name - the name of the property to set
        valueCode - Java expression representing the value to set the property to
        compiler - the current JAXXCompiler
        Returns:
        the snippet
        Throws:
        CompilerException - if a compilation error occurs
      • setProperty

        public void setProperty​(CompiledObject object,
                                String name,
                                Object value,
                                JAXXCompiler compiler)
        Appends Java code to a CompiledObject in order to implement a property assignment. setProperty is invoked in response to most XML attributes (those which are not more complicated cases, like data bindings or event handlers).

        By the time it reaches this method, the value has already been converted from its XML string representation to the appropriate destination type for the property (i.e. if JLabel.foreground is being set, value will be a Color).

        Parameters:
        object - the object being modified
        name - the name of the property to set
        value - the value to set the property to
        compiler - the current JAXXCompiler
        Throws:
        CompilerException - if a compilation error occurs
      • constantValue

        protected int constantValue​(String key,
                                    String value)
        Maps string values onto integers, so that int-valued enumeration properties can be specified by strings. For example, when passed a key of 'alignment', this method should normally map the values 'left', 'center', and 'right' onto SwingConstants.LEFT, SwingConstants.CENTER, and SwingConstants.RIGHT respectively.

        You do not normally need to call this method yourself; it is invoked by convertFromString(java.lang.String, java.lang.String, java.lang.Class<?>) when an int-valued property has a value which is not a valid number. By default, this method looks at the enumerationValues value of the JAXXPropertyDescriptor.

        Parameters:
        key - the name of the int-typed property
        value - the non-numeric value that was specified for the property
        Returns:
        the constant integer value
        Throws:
        IllegalArgumentException - if the property is an enumeration, but the value is not valid
        NumberFormatException - if the property is not an enumeration
      • safeInit

        protected void safeInit()