<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
p.tablecaption, li.tablecaption, div.tablecaption
        {mso-style-name:tablecaption;
        mso-margin-top-alt:auto;
        margin-right:0cm;
        mso-margin-bottom-alt:auto;
        margin-left:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
.MsoChpDefault
        {mso-style-type:export-only;
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=EN-GB link="#0563C1" vlink="#954F72"><div class=WordSection1><p class=MsoNormal>Hi,<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>So today we will take a break from defining new stuff, and instead look at what we have got, and the implications for language bindings. I want to look in particular at one language binding, namely Java. The Java language has object oriented capabilities, so we should be able to map to it without too many issues.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Let’s start by listing all the definitions.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>enum SAIFieldAccess {<o:p></o:p></p><p class=MsoNormal>    initializeOnly,<o:p></o:p></p><p class=MsoNormal>    inputOnly,<o:p></o:p></p><p class=MsoNormal>    outputOnly,<o:p></o:p></p><p class=MsoNormal>    inputOutput<o:p></o:p></p><p class=MsoNormal>};<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>enum SAIFieldType {<o:p></o:p></p><p class=MsoNormal>    SFBool,<o:p></o:p></p><p class=MsoNormal>    MFBool,<o:p></o:p></p><p class=MsoNormal>    SFColor,<o:p></o:p></p><p class=MsoNormal>   …<o:p></o:p></p><p class=MsoNormal>};<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>X3DField {<o:p></o:p></p><p class=MsoNormal>    enum SAIFieldType type;<o:p></o:p></p><p class=MsoNormal>    enum SAIFieldAccess accessType;<o:p></o:p></p><p class=MsoNormal>    SAIFieldName name;<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>    enum SAIFieldAccess getAccessType (void) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    enum SAIFieldType getType (void) throws SAI_CONNECTION_ERROR, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    SAIFieldName getName (void) throws SAI_CONNECTION_ERROR, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    void addInterest (SAIRequester requester) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_INSUFFICIENT_CAPABILITIES, SAI_NODE_IN_USE, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    void removeInterest (SAIRequester requester) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_INSUFFICIENT_CAPABILITIES, SAI_NODE_IN_USE, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    void dispose void) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING;<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>    X3DField (SAIFieldName fieldName, enum SAIFieldAccess accessType);<o:p></o:p></p><p class=MsoNormal>};<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>SFInt32 : X3DField {<o:p></o:p></p><p class=MsoNormal>    int32 value = 0;<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>    int32 getValue (void) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    void setValue (int32 newValue) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_IMPORTED_NODE, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>    SFInt32 (SAIFieldName fieldName, enum SAIFieldAccess accessType, int32 defaultValue);<o:p></o:p></p><p class=MsoNormal>};<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>SFNode : X3DField {<o:p></o:p></p><p class=MsoNormal>    SAINode value = NULL;<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>    SAINode getValue (void) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    void setValue (SAINode newValue) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_IMPORTED_NODE, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>    SFNode (SAIFieldName fieldName, enum SAIFieldAccess accessType, SAINode defaultValue);<o:p></o:p></p><p class=MsoNormal>};<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>SFString : X3DField {<o:p></o:p></p><p class=MsoNormal>    SAIString value = “”;<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>    SAIString getValue (void) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    void setValue (SAIString newValue) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_IMPORTED_NODE, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>    SFString (SAIFieldName fieldName, enum SAIFieldAccess accessType, SAIString defaultValue);<o:p></o:p></p><p class=MsoNormal>};<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>X3DArrayField : X3DField {<o:p></o:p></p><p class=MsoNormal>    int getNum (void) throws throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    void removeAllValues (void) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_IMPORTED_NODE, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    void removeValue (int index) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_IMPORTED_NODE, SAI_INVALID_ARRAY_INDEX, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>    X3DArrayField (void);<o:p></o:p></p><p class=MsoNormal>};<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>MFInt32 : X3DArrayField {<o:p></o:p></p><p class=MsoNormal>    int32 value[];<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>    int32[] getValue (void) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    int32 get1Value (int index) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_INVALID_ARRAY_INDEX, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    void appendValue (int32 newValue) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_IMPORTED_NODE, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    void insertValue (int index, int32 newValue) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_INVALID_ARRAY_INDEX, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    void setValue (int32 newValue[]) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_IMPORTED_NODE, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    void set1Value (int index, int32 newValue) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_ACCESS_TYPE, SAI_INVALID_ARRAY_INDEX, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>    MFInt32 (SAIFieldName fieldName, enum SAIFieldAccess accessType, int32 defaultValue[]);<o:p></o:p></p><p class=MsoNormal>};<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>enum SAINodeType {<o:p></o:p></p><p class=MsoNormal>    Anchor,<o:p></o:p></p><p class=MsoNormal>    Appearance,<o:p></o:p></p><p class=MsoNormal>    Arc2D,<o:p></o:p></p><p class=MsoNormal>    ….<o:p></o:p></p><p class=MsoNormal>};<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>X3DNode {<o:p></o:p></p><p class=MsoNormal>    enum SAINodeType  type;<o:p></o:p></p><p class=MsoNormal>    SAIString DEFname;<o:p></o:p></p><p class=MsoNormal>    SAIString typeName;<o:p></o:p></p><p class=MsoNormal>    SFNode metadata (“metadata”, inputOutput, NULL);<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>    SAIString getTypeName (void) throws SAI_CONNECTION_ERROR, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    enum SAINodeType getType (void) throws SAI_CONNECTION_ERROR, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    SAIField getField (SAIFieldName fieldname) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_NAME, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    static SAIField[] getFieldDefinitions (enum SAINodeType nodeType) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING, SAI_INVALID_NAME, SAI_DISPOSED;<o:p></o:p></p><p class=MsoNormal>    void dispose (void) throws SAI_CONNECTION_ERROR, SAI_INVALID_OPERATION_TIMING;<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>    protected X3DNode (void);<o:p></o:p></p><p class=MsoNormal>};<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>X3DMetadataObject {<o:p></o:p></p><p class=MsoNormal>    SFString name (“name”, inputOutput, “”);<o:p></o:p></p><p class=MsoNormal>    SFString reference (“reference”, inputOutput, “”);<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>    protected X3DMetadataObject (void);<o:p></o:p></p><p class=MsoNormal>};<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>MetadataInteger : X3DNode, X3DMetadataObject {<o:p></o:p></p><p class=MsoNormal>    MFInt32 value (“value, inputOutput, int32[]);<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>    MetadataInteger (void);<o:p></o:p></p><p class=MsoNormal>};<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Now, the Java language binding is specified at ISO/IEC 19777-2:2006. However, this is for version 3.0 of X3D. There is a draft of version 3.3, but this is not yet publicly shared. However, there is the X3D Java Scene Access Interface Library (X3DJSAIL) which is publicly available. In particular, we can look at the Javadoc for this library.<o:p></o:p></p><p class=MsoNormal>Reference: <a href="http://www.web3d.org/specifications/java/X3dJavaSceneAuthoringInterface.html">http://www.web3d.org/specifications/java/X3dJavaSceneAuthoringInterface.html</a><o:p></o:p></p><p class=MsoNormal>Reference: <a href="http://www.web3d.org/specifications/java/javadoc/index.html">http://www.web3d.org/specifications/java/javadoc/index.html</a><o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Referring to our list of definitions presented above, the first two are the enumerations SAIFieldAccess and SAIFieldType. What do we have in the Java library. We have X3DFieldTypes. This interface definition merges the two enumerations we defined into a single set. That’s OK. X3D does not define the implementation, only that a mapping be provided. So a good start.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>The next item on our list is X3DField, the abstract interface which is inherited by all field objects. In the Java library we also have an X3DField interface. I’ve reproduced the definition below (in blue, to highlight that this is the Java language, and not the Object Model).<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><span style='color:#0070C0'>public interface X3DField<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>{<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>X3DFieldDefinition getDefinition();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>boolean isReadable();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>boolean isWritable();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>void addX3DEventListener(X3DFieldEventListener listener);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>void removeX3DEventListener(X3DFieldEventListener listener);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>}<o:p></o:p></span></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Does it have the required services? At first glance, it seems not. There are no methods corresponding to the services getAccessType, getType, getName, or dispose. The methods addX3DEventListener and removeX3DEventListener map to the addInterest and removeInterest services that we defined, so that’s OK. However, there are two additional methods, isReadable and isWritable, which are a substitute for the getAccessType service. There is also an additional method getDefinition, which is not formally specified by the SAI. So getType, getName, and dispose are missing. Let’s not report this yet, since they might be in the inherited definitions.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Let’s move on to the first field object SFInt32. Here is the Java library definition:<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><span style='color:#0070C0'>public interface SFInt32 extends X3DField<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>{<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public int getValue();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public void setValue(int newValue);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>}<o:p></o:p></span></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>This looks great. We have the getValue and setValue methods. Although we note we still don’t have methods corresponding to the getType, getName, or dispose services. In view of this let’s see what the V3.3 draft has to say about the mappings to the SAI. These are listed in Table 4.9 for Field services. I’ve reproduced the table next.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><table class=MsoNormalTable border=1 cellpadding=0 style='border:solid windowtext 1.0pt'><tr><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal align=center style='text-align:center'><b><span style='mso-fareast-language:EN-GB'>Abstract name<o:p></o:p></span></b></p></td><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal align=center style='text-align:center'><b><span style='mso-fareast-language:EN-GB'>Java bound name<o:p></o:p></span></b></p></td></tr><tr><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>getName<o:p></o:p></span></p></td><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>String getName()<o:p></o:p></span></p></td></tr><tr><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>getType<o:p></o:p></span></p></td><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>int getType()<o:p></o:p></span></p></td></tr><tr><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>getAccessType<o:p></o:p></span></p></td><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>boolean isWritable()<br>boolean isReadable() <o:p></o:p></span></p></td></tr><tr><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>getValue<o:p></o:p></span></p></td><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><i><span style='mso-fareast-language:EN-GB'>type</span></i><span style='mso-fareast-language:EN-GB'> getValue()<br>void getValue(<i>type</i>)<br><i>type</i> get1Value(int)<o:p></o:p></span></p></td></tr><tr><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>setValue<o:p></o:p></span></p></td><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>void setValue(<i>type</i>)<br>void get1Value(int, <i>type</i>)<o:p></o:p></span></p></td></tr><tr><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>registerFieldInterest<o:p></o:p></span></p></td><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>void addFieldEventListener(X3DFieldEventListener)<br>void removeFieldEventListener(X3DFieldEventListener)<o:p></o:p></span></p></td></tr><tr><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>dispose<o:p></o:p></span></p></td><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>void dispose()<o:p></o:p></span></p></td></tr></table><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>So the Java library has agrees with the draft Java language binding, but has missing functionality. Now we can report this. But there is one other point to notice. What about the exceptions list. So far we haven’t seen any. Let’s also report this.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><b>Problem 7</b>: The X3DJSAIL library is missing functions for the field services getName, getType, and dispose.<o:p></o:p></p><p class=MsoNormal><b>Problem 8</b>: The X3DJSAIL library is missing exceptions on the interface definitions.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Let’s also check the SFNode and SFString definitions in the X3DJSAIL library.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><span style='color:#0070C0'>public interface SFNode extends X3DField<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>{<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public X3DNode getValue();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public void setValue(X3DNode newValue) throws InvalidNodeException;<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>}<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'><o:p> </o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public interface SFString extends X3DField<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>{<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public String getValue();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public void setValue(String newValue);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>}<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'><o:p> </o:p></span></p><p class=MsoNormal>There are no additional issues, so let’s move on to the multivalued field definitions. The first is the abstract X3DArrayField definition. We find that the corresponding interface in X3DJSAIL is called MField. Here is the definition:<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><span style='color:#0070C0'>public interface MField extends X3DField<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>{<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public int size();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public void clear();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public void remove(int index);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>}<o:p></o:p></span></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>We have the methods here that map  directly to our Object Model methods. The method “size” maps to “getNum”. The method “clear” maps to “removeAll”, and the method “remove” maps to “remove”. Great. Now we can look at the MFInt32 interface. The X3DJSAIL interface is:<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><span style='color:#0070C0'>public interface MFInt32 extends MField<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>{<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public void getValue(int[] valueDestination);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public int get1Value(int index) throws ArrayIndexOutOfBoundsException;<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public void setValue(int size, int[] newValue);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public void set1Value(int imageIndex, int newValue) throws ArrayIndexOutOfBoundsException;<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public void append(int newValue);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public void insertValue(int index, int newValue);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>}<o:p></o:p></span></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Comparing with our Object Model definition, the six methods in the X3DJSAIL interface map directly to the  Object Model, although we still note the lack of exceptions, except that an ArrayIndexOutOfBoundsException has been defined to correspond to the SAI_INVALID_ARRAY_INDEX error that we defined previously.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>That completes the review of fields. Now let’s turn our attention to nodes. The X3DNode definition is the abstract definition that all node interfaces are derived from. We find it in the X3DJSAIL library with that name. Here is the X3DNode interface definition.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><span style='color:#0070C0'>public interface X3DNode<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>{<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>                public X3DMetadataObject getMetadata(); // acceptable node types: X3DMetadataObject<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>                public X3DNode setMetadata(X3DMetadataObject newValue); // acceptable node types: X3DMetadataObject<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>                public X3DNode setDEF(String newValue);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>                public X3DNode setUSE(String newValue);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>                public X3DNode setCssClass(String newValue);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>}<o:p></o:p></span></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>How does this correspond to our Object Model? It doesn’t look anything like it. So, let’s look at what is defined for node services in the draft X3D Java language binding. This is in Table 4.8. I’ve reproduced it below.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><table class=MsoNormalTable border=1 cellpadding=0 style='border:solid windowtext 1.0pt'><tr><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal align=center style='text-align:center'><b><span style='mso-fareast-language:EN-GB'>Abstract name<o:p></o:p></span></b></p></td><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal align=center style='text-align:center'><b><span style='mso-fareast-language:EN-GB'>Java bound name<o:p></o:p></span></b></p></td></tr><tr><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>getTypeName<o:p></o:p></span></p></td><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>String getName()<o:p></o:p></span></p></td></tr><tr><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>getType<o:p></o:p></span></p></td><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>int[] getType()<o:p></o:p></span></p></td></tr><tr><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>getField<o:p></o:p></span></p></td><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>X3DField getField(java.lang.String)<o:p></o:p></span></p></td></tr><tr><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>getFieldDefinitions<o:p></o:p></span></p></td><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>X3DFieldDefinition getFieldDefinitions()<o:p></o:p></span></p></td></tr><tr><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>dispose<o:p></o:p></span></p></td><td style='border:solid windowtext 1.0pt;padding:.75pt .75pt .75pt .75pt'><p class=MsoNormal><span style='mso-fareast-language:EN-GB'>void dispose()<o:p></o:p></span></p></td></tr></table><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>No, X3DJSAIL doesn’t match. What is going on? X3DJSAIL is missing all the services defined by the SAI and the draft Java language binding specification. We’ll report that in a moment. Let’s just review what is there, though. There are methods “getMetadata” and “setMetadata”. These relate to getting/setting the value of the metadata field. In our Object Model we defined the SFNode field metadata as a property of the interface. X3DJSAIL has not done that. Instead, it has get and set methods defined on a field by field basis. Obviously there is nothing inherently wrong about this. However, it doesn’t match the draft Java language binding specification, or the SAI. We’ll report that in a moment.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>The X3DJSAIL library has some additional methods. The “setDEF” and “setUSE” methods relate to namedNodeHandling. We didn’t address that yet in our Object Model. The “setCssClass” method relates to the planned integration of X3D into HTML, to be specified in V4.0 of X3D.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><b>Problem 9</b>: The X3DJSAIL library does not have the required node services.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Its time to move on to the concrete node type. But we need one more abstract object first. That is X3DMetadataObject. Here is the X3DJSAIL library definition.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><span style='color:#0070C0'>public interface X3DMetadataObject<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>{<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public String getName();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public X3DMetadataObject setName(String newValue);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public String getReference();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public X3DMetadataObject setReference(String newValue);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>}<o:p></o:p></span></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>It has the same issues as X3DNode. All field oriented operations are implemented on a field by field basis. Note that the “getName” method, which here refers to getting the value of the “name” field, would be confused with the node service “getName”, which returns the name of the node.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Finally, we look at the MetadataInteger node definition in X3DJSAIL.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><span style='color:#0070C0'>public interface MetadataInteger extends X3DMetadataObject, X3DNode<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>{<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public X3DMetadataObject getMetadata(); // acceptable node types: X3DMetadataObject<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public MetadataInteger setMetadata(X3DMetadataObject newValue); // acceptable node types: X3DMetadataObject<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public String getName();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public MetadataInteger setName(String newValue);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public String getReference();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public MetadataInteger setReference(String newValue);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public int[] getValue();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public MetadataInteger setValue(int[] newValue);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public MetadataInteger setDEF(String newValue);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public MetadataInteger setUSE(String newValue);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>public MetadataInteger setCssClass(String newValue);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#0070C0'>}<o:p></o:p></span></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Ahh, this is even worse. Why are the methods inherited from the X3DMetadataObject and X3DNode definitions redefined? And what about all those methods for setting multivalued fields that were defined in the MField class? Since this library is implementing methods within a node on a field by field basis, these methods also need to be added. And even then there is no set1Value method or append methods, which the SAI requires.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><b><span style='color:red'>Problem 10</span></b><span style='color:red'>: The X3DJSAIL library fails to provide all the correct functionality as  required by a) the abstract SAI specification and b) the draft Java language binding for version 3.3.</span><o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Finally, let’s review what is in Appendix C of the draft Java language binding, for the MetadataInteger node. This is at clause C.3.128 MetadataInteger. I’ve reproduced it below, in green to highlight it is from the draft specification.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>public interface MetadataInteger extends X3DMetadataObject<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>{<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  /** Return MFInt32 result [] from MFInt32 inputOutput field named "value" */<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  public MFInt32 getValue ();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'><o:p> </o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  /** Return number of primitive values in "value" array */<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  public int getNumValue ();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'><o:p> </o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  /** Assign MFInt32 value [] to MFInt32 inputOutput field named "value" */<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  public void setValue (MFInt32 values) throws InvalidFieldValueException;<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'><o:p> </o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  /** Assign single SFInt32 value [] as the MFInt32 array for inputOutput field named "value" */<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  public void setValue (SFInt32 value) throws InvalidFieldValueException;<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'><o:p> </o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  // ===== methods for fields inherited from parent interfaces =====<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'><o:p> </o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  /** Return String result [] from SFString inputOutput field named "name" */<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  public String getName ();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'><o:p> </o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  /** Assign String value [] to SFString inputOutput field named "name" */<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  public void setName (String value);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'><o:p> </o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  /** Return String result [] from SFString inputOutput field named "reference" */<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  public String getReference ();<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'><o:p> </o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  /** Assign String value [] to SFString inputOutput field named "reference" */<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  public void setReference (String value);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'><o:p> </o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  /** Return X3DMetadataObject result (using a properly typed node or X3DPrototypeInstance) from SFNode inputOutput field named "metadata" */<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  public void getMetadata (X3DNode result);<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'><o:p> </o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  /** Assign X3DMetadataObject value (using a properly typed node) to SFNode inputOutput field named "metadata" */<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  public void setMetadata (X3DMetadataObject node) throws InvalidFieldValueException;<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'><o:p> </o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  /** Assign X3DMetadataObject value (using a properly typed protoInstance) */<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>  public void setMetadata (X3DPrototypeInstance protoInstance) throws InvalidFieldValueException;<o:p></o:p></span></p><p class=MsoNormal><span style='color:#548235;mso-style-textfill-fill-color:#548235;mso-style-textfill-fill-alpha:100.0%'>}<o:p></o:p></span></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Here we see similar problems. There are the same missing node services that we have noted for X3DJSAIL. And there is also a completely different method for handling individual fields that is not described in the Concepts clause of the draft specification.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><b><span style='color:red'>Problem 11</span></b><span style='color:red'>: In the draft Java language binding specification for X3D V3.3 the node definitions in Annex C do not meet the requirements described in clauses 3 to 6, in turn failing to meet the requirements of the abstract SAI specification ISO/IEC 19775-2:2015.<o:p></o:p></span></p><p class=MsoNormal><span style='color:red'><o:p> </o:p></span></p><p class=MsoNormal>Well, we appear to have uncovered some serious failings. So let’s pause and wait for comment. Perhaps we have misunderstood things. Anyway, let’s get other opinions before we move on to filling in some of the gaps we intentionally set aside, and then generalizing our approach to all the other nodes.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>All the best,<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Roy<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p></div></body></html>