My favorites | Sign in
Project Home Downloads Wiki Issues Source
READ-ONLY: This project has been archived. For more information see this post.
Search
for
Samples2x  
Examples for FlexXB 2.x
Updated May 26, 2011 by alex.id....@gmail.com

Annotation samples

To get an idea about the features FlexXB provides please take a look on the Features in detailed explanation page. You'll find detailed explanations for all capabilities FlexXB offers.

1. Basic sample using xml annotations

This is a simple example on using xml annotations. Only fields that have been decorated with an annotation will be taken into account in the (de)serialization process. Notice the idField attribute. It specifies that this object supports a compact method of defining it in xml, by only specifying the id. The id will be rendered as element or attribute in the owner xml.

        [XmlClass(alias="MOck2Replacement", idField="id")]
	public class Mock3
	{
		[XmlAttribute]
		public var id : Number = 3;
		[XmlAttribute]
		public var attribute : Boolean;
		[XmlElement(alias="objectVersion")]
		public var version : Number;
		
		public function Mock3()
		{
			super();
		}
	}

The object has been built as:

        var target : Mock3 = new Mock3();
	target.attribute = true;
	target.id = 5;
	target.version = 33;

The resulting XML is:

<MOck2Replacement attribute="true" id="5">
  <objectVersion>
    33
  </objectVersion>
</MOck2Replacement>

The alias field is versatile in which it can accept the wildcard character, star (*). This instructs the engine to determine at runtime the name of the element/attribute based on the values that is provided, regardless of the field name. It is useful when using a base type for the field and providing values of types extended from that type which may have different names. Also, not setting an alias will tell the engine to use as name the field's name (id your field names match the necessary names in the xml, then there is no need to specify the alias).

2. Namespacing objects

The object defines its own namespace under which it is serialized. Notice the serializePartialElement attribute in the XmlElement annotations. It specifies that the value will be serialized in a compact manner, that is, by only specifying the id of an object. For this, the object must have defined an id field as seen in the first sample

        [Bindable]
	[XmlClass(alias="MyClass", prefix="test", uri="http://www.yourcompany.com/xmlns/yourNs")]
	public class Mock
	{
		[XmlAttribute(alias="stuff")]
		public var aField : String = "a";
		[XmlAttribute(ignoreOn="serialize")]
		public var date : Date;
		[XmlElement(alias="objVersion")]
		public var version : Number = 4;
		[XmlElement(alias="mock3", serializePartialElement="true")]
		public var link : Mock3;
		[XmlElement(serializePartialElement="true")]
		public var reference : Object;
		[XmlArray(alias="data", type="com.googlecode.testData.Mock")]
		public var result : Array;
		[XmlElement]
		public var xmlData : XML; 
		
		public var someExcludedField  : Boolean;
		
		public function Mock(){
			//TODO: implement function
		}
	}

The object to be serialized has been built as

        var target : Mock = new Mock();
	target.link = new Mock3();
	target.aField = "test1";
	target.date = new Date();
	target.version = 6;
	target.result = [];
	var mk : Mock = new Mock();
	mk.date = new Date();
	mk.aField = "mocktestfield";
	target.result.push(mk);
	target.xmlData = <test id="1"><element>retw</element></test>

The resulting XML is:

<test:MyClass test:stuff="test1" xmlns:test="http://www.yourcompany.com/xmlns/yourNs">
  <test:data>
    <test:MyClass test:stuff="mocktestfield">
      <test:objVersion>
        4
      </test:objVersion>
    </test:MyClass>
  </test:data>
  <test:objVersion>
    6
  </test:objVersion>
  <test:xmlData>
    <test id="1">
      <element>
        retw
      </element>
    </test>
  </test:xmlData>
  <test:mock3 id="3"/>
</test:MyClass>

3. Using virtual paths

A member's alias can define "virtual paths". Virtual paths allow definition of complex xml structures for a field without complicating the model design. Thus, structures can be present in the xml just by adding virtual paths in the alias definition of a member.

Let's assume the xml representation looks like:

<myPathTester>
  <anotherSub attTest="Thu Mar 19 15:49:32 GMT+0200 2009"/>
  This is Default!!!
  <subObject>
    <id>
      2
    </id>
    <subSubObj>
      <ref>
        ReferenceTo
      </ref>
    </subSubObj>
  </subObject>
</myPathTester>

This would normally translate itself in about 4 model classes. Using virtual paths, one can describe it in just one model class:

[XmlClass(alias="myPathTester", defaultValueField="defaultTest")]
public class XmlPathObject
{
	[XmlElement(alias="subObject/id")]
	public var identity : Number = 2;
	[XmlElement(alias="subObject/subSubObj/ref")]
	public var reference : String = "ReferenceTo"; 
	[XmlArray(alias="subObject/list")]
	public var list : Array;
	[XmlAttribute(alias="anotherSub/attTest")]
	public var test : Date = new Date();
	[XmlElement()]
	public var defaultTest : String = "This is Default!!!"
	
	public function XmlPathObject()
	{
	}
}

Notice the defaultValueField attribute. It specifies that the target field will be rendered in xml as a simple text element. Still, the field marked as default will still have to be decorated by an annotation to be taken into account by the serializer.

More on Virtual paths...

4. Ordering the xml sequence

FlexXB supports ordering the fields of an object in the rendered xml either by order index or by field alias both defined in the annotation decorating the field. For ordering to be activated, the ordered attribute must be set to true.

	[XmlClass(name="OrderTest", ordered="true")]
	public class Persist extends PersistableObject
	{
		[XmlElement(order="1")]
		public var isOK : Boolean = false;
		[XmlElement(order="3")]
		public var test1 : int;
		[XmlElement(order="2")]
		public var test2 : String;		
		
		public function Persist(){
			super();
		}		
	}

The resulting xml looks like:

<Persist>
  <isOK>
    false
  </isOK>
  <test2>
    valoare
  </test2>
  <test1>
    3
  </test1>
</Persist>

API Samples

The FlexXB API allows developers to specify the way classes should be processed without decorating them with annotations. This is particularly usefull is cases when using an external library whose sources are not available or when you can't modify existing sources for one reason or another. There are two ways of using the API:

  • Programatically: you can define in code the fields of a specific type that can be processed and how.
  • Via xml config file: you can define an xml file containing all the information FlexXB engine needs to process the specified types. This file must oblige to the api schema file located in FLEXXB_BINARIES_DIR/api-schema/FlexXB-api.xsd.
The main access point for the api is com.googlecode.serializer.flexxb.FlexXBEngine.instance.api.

1. Programatically building descriptor

Let's assume we have the following object(annotations are set just to demonstrate how the api should be configured):

package model
{
	import com.googlecode.flexxb.IIdentifiable;

	[XmlClass(alias="Person")]
	[ConstructorArg(reference="firstName")]
	[ConstructorArg(reference="lastName")]
	[Bindable]
	public class Person implements IIdentifiable
	{
		[XmlElement(alias="ID")]
		public var id : String = "1";
		[XmlAttribute(alias="FirstName")]
		public var firstName : String;
		[XmlAttribute(alias="LastName")]
		public var lastName : String;
		[XmlAttribute(alias="Age")]
		public var age : int;
		[XmlElement(alias="Position")]
		public var position : String;
		
		public function Person(firstName : String, lastName : String)
		{
			super();
			this.firstName = firstName;
			this.lastName = lastName;
		}
		
		public function get thisType():Class
		{
			return Person;
		}		
	}
}

Building the api descriptor should look like:

        var apiClass : XmlApiClass = new XmlApiClass(Person, "Person");				
        //Add class members descriptors
	apiClass.addElement("id", String, AccessorType.READ_WRITE, "ID");
	apiClass.addAttribute("firstName", String, AccessorType.READ_WRITE, "FirstName");
	apiClass.addAttribute("lastName", String, AccessorType.READ_WRITE, "LastName");
	apiClass.addAttribute("age", String, AccessorType.READ_WRITE, "Age");
	apiClass.addElement("position", String, AccessorType.READ_WRITE, "Position");
	//Set the constructor arguments, if any
	apiClass.addArgument("firstName");
	apiClass.addArgument("lastName");
	//Register the api descriptor class in the FlexXB engine
	FlexXBEngine.instance.api.processTypeDescriptor(apiClass);

Another example: let's assume we now have a department class (annotations are set just to demonstrate how the api should be configured):

package model
{
	import com.googlecode.flexxb.IIdentifiable;
	
	[XmlClass(alias="CompanyDepartment", prefix="dept", uri="http://myCompanyUrl.com")]
	[ConstructorArg(reference="id")]
	[ConstructorArg(reference="name")]
	[Bindable]
	public class Department implements IIdentifiable
	{
		[XmlAttribute(alias="ID")]
		public var id : String;
		
		[XmlElement(alias="DepartmentName")]
		public var name : String;
		
		[XmlElement(alias="Leader")]
		public var departmentHead : Person;
		
		public function Department(id : String, name : String)
		{
			super();
			this.id = id;
			this.name = name;
		}
		
		public function get thisType():Class
		{
			return Department;
		}
		
	}
}

The api descriptor is built like:

        var apiClass : XmlApiClass = new XmlApiClass(Department);
	apiClass.alias = "CompanyDepartment";
	apiClass.defaultNameSpace = new Namespace("dept", "http://myCompanyUrl.com");
	//Add clas members descriptors
	apiClass.addAttribute("id", String, AccessorType.READ_WRITE, "ID");
	apiClass.addElement("name", String, AccessorType.READ_WRITE, "DepartmentName");
	apiClass.addElement("departmentHead", Person, AccessorType.READ_WRITE, "Leader");
	//Set the constructor arguments, if any
	apiClass.addArgument("id");
	apiClass.addArgument("name");
	//Register the api descriptor class in the FlexXB engine
	FlexXBEngine.instance.api.processTypeDescriptor(apiClass);
Powered by Google Project Hosting