Previous Next        Current Page: NeXtMidas User's Guide / Result Parameters / Using KeyObject
FAQs   
Release Information   
Getting Help   
Basic Concepts   
Result Parameters   
   - Data Types   
   - Tables   
   - Using KeyObject   
   + System Modeling Data   
XML Support   
Files   
System Operation   
Macros   
Applets and WebStart   
Graphics   
X-Midas Interoperability   
Third-Party Compatibility   
Installation and Customization   
Running NeXtMidas Independently   
Glossary   


Using KeyObject

The KeyObject class is used by the results table to access methods and fields of objects. This allows complex Java objects to be accessed using the same dot-syntax used to access tables.

For example:

nM> res mystr "hello world"
nM> res mystr.charAt(2)
  O: MYSTR.CHARAT(2) = l
nM> res mystr.class
  O: MYSTR.CLASS     = class java.lang.String
      

Finding the Keys

The simplified look-up of the keys is done as follows (see State Diagram for details):

  1. If the root is null, return null.
  2. If the root is a Table or KeyVector then do a normal Table lookup.
  3. If the root is an object that implements Keyable call getKey(..) or setKey(..). If null is returned continue on, otherwise return the result of calling getKey(..) or setKey(..).
  4. If the root is a Java array get the indexed value out of the array. (If the key is "SIZE" then return the array size.)
  5. Look for methods/fields to access (see details below). If no methods/fields exist continue on, otherwise return the result of invoking the method/field.
  6. If the root implements Chainable goto the next object in the chain and repeat.
  7. If the root is indexable get the indexed value.

When looking for methods to access KeyObject looks for public methods whose parameters match and whose names...

  1. Match exactly.
  2. Match when compared ignoring case.
  3. Match the method accronym (the uppercase letters in the method name, e.g. getXDelta has the accronym XD).
  4. Match the method abbreviation (the first 2-4 letters of the method name, getFrequency has the abbreviation FREQ).
Note: If a class is not public only the public methods in a public superclass or interface will be accessable.

Implementing Keyable

The Keyable interface allows a class to be accessable via a set of keys. To use Keyable simply implement the three methods in the interface:

Method Name Description
getKeys() Lists the available keys.
getKey(key) Gets a key, returns null if unable to get a key via this interface.
setKey(key,value) Sets a key, returns null if unable to get a key via this interface, otherwise returns the new value of the key.

Implementing Chainable

The Chainable interface tells KeyObject that there is another class sitting below this one that KeyObject can pass the keys on to. To use Chainable simply implement the two methods in the interface:

Method Name Description
getNextLink() Gets the next link in the chain that KeyObject should pass keys down to.
getPrevLink() Gets the previous link in the chain (or null if not applicable). KeyObject does not use this method but some of the query functions do.

State Diagram

The following is the detailed state diagram for the key lookup performed by KeyObject.
        START
          |
          v
 +---------------------+
 | Check for null      |
 +---------------------+
 | do: check to see if | [obj is null]
 |     the ojbect is   |---------------> return null
 |     null            |
 +---------------------+
          |
          | [obj is not null]
          v
 +---------------------+
 | Check for Table     |
 | or KeyVector        |
 +---------------------+
 | do: check to see if | [obj is Table, KeyVector]
 |     the object is   |----> Table/KeyVector Access
 |     a Table or a    |
 |     KeyVector       |
 +---------------------+
          |
          | [not Table, KeyVector]
          v
 +---------------------+
 | Check for Keyable   |
 +---------------------+
 | do: check to see if | [obj is Keyable]
 |     the object is   |-----------+
 |     a Keyable       |           |
 +---------------------+           v
          |               +---------------------+
          |               | Try get/set         |
          |               +---------------------+ [not null]
          |               | do: Call getKey(..) |----> return value
          |               |  or setKey(..) and  |
          |               |  and check for null | [null]
          |               |  return value.      |----+
          |               +---------------------+    |
          | [not Keyable]                            |
          v                                          |
 +---------------------+                             |
 | Check for Array     |                             |
 +---------------------+ [obj is Array]              |
 |                     |----> Array Access           |
 +---------------------+                             |
          | [not Array]                              |
          |                                          |
          |    +-------------------------------------+
          v    v
 +---------------------+
 | Find Members to     |
 | Access              |
 +---------------------+ [member found]
 | do: findMembers(..) |----> Member Access
 +---------------------+
          |
          | [no members found]
          v
 +---------------------+
 | Check for Chainable |
 +---------------------+ [obj is Chainable]
 |                     |---------> return findAndInvoke(nextLink,...)
 +---------------------+
          |
          | [not chainable]
          v
 +---------------------+
 | Check for Indexed   |
 +---------------------+ [key is index value]
 |                     |------+
 +---------------------+      |
          |                   v
          |      +---------------------+
          |      | Check get or set    |
          |      +---------------------+
          |      |                     |
          |      +---------------------+
          |             |  |
          |             |  | [args.length==0]
          |             |  +-----> return getIndexed(obj,key)
          |             |
          |             | [args.length==1]
          |             +--------> return setIndexed(obj,key,args[0])
          |
          | [key is not index value]
          v
        ERROR
    
Table/KeyVector Access
        START
          |
          v
 +---------------------+
 | Determine get or set|
 +---------------------+
 | do: determine if the|
 |  access is a get    | [get]
 |  (args.length==0 or |----> return getKey(key)
 |  searchOrder=GET)   | [set]
 |  or a set.          |----> return setKey(key,args[0])
 +---------------------+
    
Array Access
        START
          |
          v
 +---------------------+
 | Check for "getsize" |
 +---------------------+
 | do: check to see if | [getSize]
 |     key is "size"   |----> return Array.getSize(obj)
 |     or "getsize"    |
 +---------------------+
         |[not getsize]
         v
 +---------------------+
 | Check get or set    |
 +---------------------+ [args.length==0]
 |                     |----> return getIndexed(obj,key)
 |                     | [args.length==1]
 |                     |---->return setIndexed(obj,key,args[0])
 +---------------------+
    
Member Access
        START
          |
          v
  +---------------------+
  | Determine if it is  |
  | a method or a field |
  +---------------------+
  | do: Check member    |
  |     type.           |
  +---------------------+
           |
           | [field]    +---------------------+
           +----------->| Check get or set    |
           |            +---------------------+ [args.length==0]
           |            |                     |----> return field.get(..)
           |            |                     | [args.length==1]
           |            |                     |----> return field.set(..)
           |            +---------------------+
           |                
           | [method]   +---------------------+
           +----------->| Determine if it is  |
                        | an invoke then index|
                        +---------------------+
                        | do: "Invoke then get|[invoke then get]
                        |  indexed" is when   |----> getIndexed(..)
                        |  args.length==1,    |
                        |  searchOrder=GET,   |[normal]
                        |  and method matches |----> method.invoke(..)
                        +---------------------+