Using the ValueContext on a multivalued complex type.

Using the ValueContext on a multivalued complex type.

book

Article ID: KB0075792

calendar_today

Updated On:

Products Versions
TIBCO EBX All supported versions.

Description

When trying to get or set values of a multivalued complex type (multivalued group), the method ValueContext.getValue() returns a list of complex elements of GenericComplexObject type. 

But this class not being part of the public API, it is not possible to use it in custom Java extensions.

Issue/Introduction

Using the ValueContext on a multivalued complex type.

Resolution

Warning

Ajax pre-validation and synchronization are not supported on multivalued complex fields. Thereby the following solution will not work if the form was not submitted (values need to be persisted in the database).

Solution

In order to retrieve or set the values which are under a multivalued complex type, it is necessary to define a Value container class (JavaBean) on the complex type node in your data model.

Value container class (JavaBean)

Specifies a Java class to hold the values of the children of this group. The Java class must conform to the JavaBean standard protocol. That is, each child of the group must correspond to a JavaBean property in the class, and all properties must have getter and setter accessors defined.

 

Example

Let's suppose we have a table with the following definition:

DataModel.xsd
<xs:element name="Collection" minOccurs="0" maxOccurs="unbounded">
                    <xs:annotation>
                        <xs:appinfo>
                            <osd:table>
                                <primaryKeys>/id </primaryKeys>
                            </osd:table>
                        </xs:appinfo>
                    </xs:annotation>
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="id" type="xs:string" minOccurs="1" maxOccurs="1"/>
                            <xs:element name="Product" maxOccurs="unbounded">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="Name" type="xs:string" minOccurs="0" maxOccurs="1"/>
                                        <xs:element name="Description" type="xs:string" minOccurs="0" maxOccurs="1"/>
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>

 

Here is how you can implement the JavaBean for the Product field: 

ProductJavaBean.java
public class ProductJavaBean {
 
    private String Name;
    private String Description;
 
    public String getName() {
        return Name;
    }
    public void setName(String name) {
        Name = name;
    }
    public String getDescription() {
        return Description;
    }
    public void setDescription(String description) {
        Description = description;
    }
}

 

You then have to add the class in your data model, in the advanced properties of the complex type node, or in the .xsd like the following:

DataModel.xsd
<xs:element name="Product" minOccurs="0" maxOccurs="unbounded" osd:class="com.orchestranetworks.support.confluence.ProductJavaBean">

 

You can then perform this kind of operations:

myCode.java
List <ProductJavaBean> productsList = (List<ProductJavaBean>) valueContext.getValue(Path.parse("./Product")); // List of products
ProductJavaBean firstProduct = productsList.get(0); // First product of the list
String firstProductName = firstProduct.getName(); // Name of the first product
 
 
//Creating a product and adding it to the list
ProductJavaBean newProduct = new ProductJavaBean();
newProduct.setName("myname");
productsList.add(newProduct);
 
 
// Setting the new value
valueContext.setValue(productsList,PATH.SELF);

Additional Information

https://docs.tibco.com/pub/ebx/5.9.8/doc/html/en/user_datamodel/userdatamodel_elementproperties.html#id2s4