Subscribe to Mailing List
Submit requests and bugs
Follow Astroboa on Twitter
Installation Guide
Maven Repository
Get Source code at GITHUB
Building from Sources
API Documentation
Submit a Bug or Request

Creating new object types in Astroboa

Astroboa comes with a rich model set of various ready made object types that model persons, organizations, file resources, geo tags, embedded multimedia resources, contact data, etc. However, your needs may not be addressed by these ready-made object types. In order to address your own particular modeling requirements you will need to create your own object types either by extending-reusing a ready-made object type or by creating your own from scratch. Creating or extending a new object type requires that you write some XML; in particular creating a new XML Schema (XSD) for the new object type.

In Astroboa you may create two kinds of types, concrete object types and re-usable object types. Concrete types are used to create object instances in Astroboa. However they cannot be extended and re-used so as to create new types. In this case, you need to create a re-usable type. Both kinds of types however must extend the contentObjectType which is provided by Astroboa. Types not extending the contentObjectType will not be recognized by Astroboa. The contentObjectType is a re-usable type and all object types that extend it obtain special properties like the system name, Dublin Core metadata and accessibility properties.

Object type definition preamble

When you create a new object type you actually create a new XML schema. All XML schemas share a common preamble presented in the code listing below:

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:bccmsmodel="http://www.betaconceptframework.org/schema/astroboa/model"
    xmlns:tns="http://www.myAstroboaObjects.org/schema/myNewObject"
    targetNamespace="http://www.myAstroboaObjects.org/schema/myNewObject"
    version="1.0">

    <xs:import namespace="http://www.betaconceptframework.org/schema/astroboa/model"
           schemaLocation="astroboa-model-3.0.0-SNAPSHOT.xsd"/>

    <-- Object Definition goes here -->
</xs:schema>

This XML schema uses tags from the Astroboa model (bccmsmodel) namespace (line 5). A namespace is nothing more than a bucket where xml tags reside and it is identified by a URL which is not necessary to exist. We need namespaces to avoid name clashing issues. What if you have defined a type named 'orderObject' and I did the same thing? How do you tell which is which? You put the type definition in a namespace and you give it a URL. I do the same thing for my 'orderObjec't but my URL is different than yours, so we can distinguish our 'orderObject' types.

The Astroboa model namespace is identified by the http://www.betaconceptframework.org/schema/astroboa/model URL. Now, how do your refer to the type that you have created in a namespace ? You use an alias to the namespace. The alias to the Astroboa model namespace is 'bccmsmodel'. This is defined in the 'xmlns' attribute (line 5). So, to use a tag from the Astroboa model namespace, you say bccmsmodel:<tag-name>, thus to use the displayName tag you shoud write bccmsmodel:displayName.

The object type that you define has to be placed inside a namespace. You define the namespace in the targetNamespace attribute by replacing the placeholder <YOUR-NAMESPACE-GOES-HERE> with your own URL, for example http://www.acme.org/schema/acme/myNewObject. Note that the same URL should be set for the xmlns:tns attribute ('tns' stands for: this namespace). So, 'tns' is an alias for the namespace we define.

The <xs:import> tag imports the Astroboa model namespace which is placed in file astroboa-model-3.0.0-SNAPSHOT.xsd file. The naming convention is astroboa-model-<Astroboa_Version>.xsd. So, keep this in mind when you create your own XML schema files. This file exists in the Astroboa engine.

One last thing before we continue on is that we prefer to define an object type in its own XML schema file. This helps up to keep track of which type is defined in which file.

Creating concrete types

We will define the myNewObject type as a demonstration vehicle to present almost all valid properties that can be used in Astroboa. To do so, log-in to the Astroboa Demo (Username: demo, Password: astroboa-demo) and choose "Add New... > XML Schema". In the file text field, enter myNewObject.xsd and add the following code listing in the editor. Save the type.

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema     
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:bccmsmodel="http://www.betaconceptframework.org/schema/astroboa/model"          
    xmlns:tns="http://www.myAstroboaObjects.org/schema/myNewObject"     
    targetNamespace="http://www.myAstroboaObjects.org/schema/myNewObject"     
    version="1.0">

  <xs:import namespace="http://www.betaconceptframework.org/schema/astroboa/model"
         schemaLocation="astroboa-model-3.0.0-SNAPSHOT.xsd"/>      
  
  <xs:element name="myNewObject">

    <xs:annotation>
      <xs:documentation xml:lang="en">
        <bccmsmodel:displayName>My New Object</bccmsmodel:displayName>
      </xs:documentation>
    </xs:annotation>
    
    <xs:complexType>

      <xs:complexContent>  

        <xs:extension base="bccmsmodel:contentObjectType">
          
          <xs:sequence>
            
            <xs:element name="myStringProperty" type="xs:string">

              <xs:annotation>
                <xs:documentation xml:lang="en">
                  <bccmsmodel:displayName>       
                    My First String Property
                  </bccmsmodel:displayName>
                  
                  <bccmsmodel:description>
                    That's my first string property. Enter text here
                  </bccmsmodel:description>   
                </xs:documentation>
              </xs:annotation>      

            </xs:element>

          </xs:sequence>

        </xs:extension>

      </xs:complexContent>

    </xs:complexType>
  </xs:element>
</xs:schema>    

And that is all, you have just created a new concrete object type named 'myNewObject' which has one property, the myStringProperty which is a string. We define this new type in a new namespace identified by the http://www.myAstroboaObjects.org/schema/myNewObject URL (lines 6-7).

The element tag defines a new concrete object type, the myNewObject type (line 13). In the documentation tag, we use bccmsmodel:displayName (line 17) to provide a label about our type. Astroboa will use this label for display purposes. It's better to display "My New Object" rather than "myNewObject". We also use the bccmsmodel:description to describe this property, what its purpose is and how it is intended to be used. To reserve some space in the code listings below, we will not include the bccmsmodel:description tags.

In a few lines below, the extension tag (line 25) says that our new object type extends the contentObjectType. So, our type gets all the properties of contentObjectType like systemName, Dublin Core metadata properties for free. Remember that every object type should extend the contentObjectType.

Right after the extension tag, comes the sequence tag (line 27), where we define the properties of our object type. It's called sequence because a new type is a sequence of properties. Here, we define our first property, myStringProperty, whose type is string (line 29). By default, a property is defined as required/mandatory. Once again, there is a combination of documentation, displayName tags to define the display name of our property.

Optional Properties

We have defined the myStringProperty as a mandatory property which means that you cannot create a new object without setting a value for myStringProperty. In order to make a property optional, you need to add minOccurs="0" and maxOccurs="1" attributes in its definition. Here is the definition for the optional myStringProperty (to keep things short, we only show the property definition and not the rest of the object type definition):

<xs:element name="myStringProperty" type="xs:string"
        minOccurs="0" maxOccurs="1">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>My First Optional String Property
      </bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
</xs:element>

String Property

We have already seen how to create a string property. We just need to set the element type to xs:string. Moreover, we may further enhance a string property to allow only string values that satisfy a regular expression, or which are of a specific length, or accept string values that are part of an enumeration.

Let's start with restricting a string property to accept strings that can be only numbers and up to only 8 numbers.

<xs:element name="stringRestrictedToAcceptNumberValues">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:pattern value="[0-9]{8}" />
    </xs:restriction>
  </xs:simpleType>
</xs:element>

We may restrict a string value to be between 10 and 100 characters. This is handy when you want a description property that should be at least a minimum number of characters but no more than a maximum number of characters.

<xs:element name="description">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:minLength value="10"/>
      <xs:maxLength value="100"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

We can even define a string property like the "hugetext" property that may have an unlimited length.

<xs:element name="hugetext">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:minLength value="0"/>                                    
      <xs:maxLength value="0"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

We may create an enumeration string property like the "grade" property shown below which may accept values A, B, or C.

<xs:element name="grade">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:enumeration value="A" />
      <xs:enumeration value="B" />
      <xs:enumeration value="C" />
    </xs:restriction>
  </xs:simpleType>
</xs:element> 

We may define an enumeration which is a union of one or more simple types as defined by the XML schema UnionTypes. In the following example, colorVariationType is a simple type whose value range is the union of the values of the RedColorVariationType, the GreenColorVariationType and the BlueColorVariationType. This type can be defined directly as the type of an element, such as the colorVariation property or can de defined globally and thus may be used or extended by more than one properties, like the alternativeColorVariationType and the alternativeColorVaration property.

<xs:element name="colorVariation">
   <xs:simpleType name="colorVariationType">

     <xs:union memberTypes="tns:RedColorVariationType
                            tns:GreenColorVariationType
                            tns:BlueColorVariationType"/>
   </xs:simpleType>
</xs:element>


<xs:simpleType name="RedColorVariationType">
    
     <xs:restriction base="xs:string">
         <xs:enumeration value="Pink"/>
         <xs:enumeration value="Crimson red"/>
     </xs:restriction>

</xs:simpleType>
  
<xs:simpleType name="GreenColorVariationType">

     <xs:restriction base="xs:string">
         <xs:enumeration value="Asparagus"/>
         <xs:enumeration value="Mantis"/>
     </xs:restriction>
</xs:simpleType>
  
<xs:simpleType name="BlueColorVariationType">

     <xs:restriction base="xs:string">
         <xs:enumeration value="Powder blue"/>
         <xs:enumeration value="Light blue"/>
         <xs:enumeration value="Baby blue"/>
     </xs:restriction>
</xs:simpleType> 


<xs:element name="alternativeColorVariation" 
            type="tns:alternativeColorVariationType">
</xs:element>

 <xs:simpleType name="alternativeColorVariationType">

    <xs:union memberTypes="tns:RedColorVariationType
                           tns:GreenColorVariationType
                           tns:BlueColorVariationType"/>
 </xs:simpleType>

We can define a String property using an XML attribute

<xs:attribute name="productId" use="optional" type="xs:string">
     <xs:annotation>
         <xs:documentation xml:lang="en">
             <bccmsmodel:displayName>Product Identifier</bccmsmodel:displayName>
             <bccmsmodel:description><![CDATA[String <b>Property</b> defined by Attribute]]></bccmsmodel:description>
         </xs:documentation>
     </xs:annotation>
</xs:attribute>
 

Finally, a String property represents any element whose type is the XML Schema derived datatype 'language' as described in http://www.w3.org/TR/xmlschema-2/#language. In this case, the value(s) of this property should follow the pattern which is defined in the XML Schema schema (http://www.w3.org/2001/XMLSchema.xsd) in the "language" simple type: [a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*

<xs:element name="motherLanguage" type="xs:language"/>
 

RichText property

String properties are nice but rich-text ones are even nicer, because we can format text as we like. Here is how to define a rich-text string property called myRichTextStringProperty:

<xs:element name="myRichTextProperty" type="xs:string"
        bccmsmodel:stringFormat="RichText">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>My Rich-Text Property</bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
</xs:element> 

Note that myRichTextProperty is a string property and it is tranformed to rich-text by adding the bccmsmodel:stringFormat="RichText" attribute. This attribute is an Astroboa specific attribute and it is not defined by the XML standard, however it is perfectly valid. Note that we prefix the string Format attribute with bccmsmodel (the alias) as it is defined in the Astroboa model namespace.

Boolean property

A boolean property is a YES or NO property, just like answering a question "Are you experienced?", yes or no. You may define a boolean property as shown below:

<xs:element name="myBooleanProperty" type="xs:boolean">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>My Boolean Property</bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
</xs:element>

We can define a Boolean property using an XML attribute as well

<xs:attribute name="myBooleanProperty" use="required" type="xs:boolean"/>

Numerical property

Numerical properties are about numbers, either integer e.g -1, 0, 1, 2, 3, ..., or floating point e.g 3.14159, 2.718, etc. You define an integer property as follows:

<xs:element name="myLongProperty" type="xs:long">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>
    My Integer (Long) Property
      </bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
</xs:element> 

You may even restrict a numeric property to accept values only from a specific range or a specific set of values like an enumeration. The "score" property below may accept integer values between 10 and 100 inclusive.

<xs:element name="score">
  <xs:simpleType>
    <xs:restriction base="xs:integer">
      <xs:minInclusive value="10"/>
      <xs:maxInclusive value="100"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

The "discountRate" property below may accept a value from 10, 20 or 30.

<xs:element name="discountRate">
  <xs:simpleType>
    <xs:restriction base="xs:integer">
      <xs:enumeration value="10"/>
      <xs:enumeration value="20"/>
      <xs:enumeration value="30"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

A long integer can hold values ranging from -2^63..2^63-1, or -9223372036854775808..9223372036854775807. If you need larger values than these, then you should define a double precision floating point number as shown below:

<xs:element name="myDoubleProperty" type="xs:double">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>
    My Floating-Point (Double) Property
      </bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
</xs:element>

 

We can define a Numerical property using an XML attribute as well

	<xs:attribute name="myIntProperty" use="required" type="xs:integer"/>

Date and DateTime property

A "date" property holds a date value that does not include time information. If you need time information you need a date time property. Here is how to define a date property.

<xs:element name="myDateProperty" type="xs:date">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>My Date Property</bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
</xs:element>

and here is how to define a date time property:

<xs:element name="myDateTimeProperty" type="xs:dateTime">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>
    My DateTime Property
      </bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
</xs:element>

You may even use the special XmlSchema primitive data types gYear, gMonth, gYearMonth, gDay and gMonthDay whose properties and definition are fully described in http://www.w3.org/TR/xmlschema-2/#isoformats. Following their definition, these types are mapped to a String property in contrary to the representation of the date and dateTime data types.

We can define a Date property using an XML attribute as well

	<xs:attribute name="myDateProperty" use="required" type="xs:date"/>

Binary property

A binary property is handy when you need to store binary data, like an image, an audio file or a pdf file, etc. You may define a binary property as follows:

<xs:element name="myBinaryProperty"
        type="bccmsmodel:binaryChannelType">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>My Binary Property</bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
</xs:element>

Note that the type of this property is bccmsmodel:binaryChannelType, which is an Astroboa defined model type. This is the recommended way to define a property whose value is a binary data, however this is not the only way to go. You may define a binary property using either of the following expressions:

<xs:element name="simpleBinary" type="xs:base64Binary"/>

or

<xs:element name="alternativeBinaryChannel" type="tns:binaryChannelAlternativeType"/>

<xs:complexType name="binaryChannelAlternativeType">
  <xs:simpleContent>
    <xs:extension base="xs:base64Binary">
        <xs:attribute name="mimeType" type="xsd:string" 
                           use="required" fixed="image/jpeg"/>
    </xs:extension>
  </xs:simpleContent>
</xs:complexType>  

Topic Property

A topic property is designed to hold topic values, that is topics of a taxonomy. In its simplest form it accepts values from a single taxonomy as shown below:

<xs:element name="myTopicProperty" type="bccmsmodel:topicType"
        bccmsmodel:acceptedTaxonomies="nationality">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>
        My Topic Property (accepts values from nationality taxonomy)
      </bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
</xs:element>   

Note that in the bccmsmodel:acceptedTaxonomies attribute we specify the system name of the nationality taxonomy.

A topic property may accept values from one or more taxonomies by specifying taxonomy names separated with commas, as follows:

<xs:element name="myTopicProperty" type="bccmsmodel:topicType"
        bcmsmodel:acceptedTaxonomies="typeOfProblem, typeOfIssue">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>
    My Topic Property (accepts values from taxonomies typeOfProblem,
    typeOfIssue)
    </bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
</xs:element>   

You may even define a topic property that accepts any topic value from any taxonomy. This kind of topic property is useful when you use the topic property as a tag (a tag may accept topic values from any taxonomy). Here is the definition of such a topic property:

<xs:element name="myTopicProperty" type="bccmsmodel:topicType">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>
    My Topic Property (accepts values from any taxonomy)
      </bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
</xs:element>   

Object Reference Property

An object reference property is necessary when you wish to associate one object with another, for example to associate a person with an organization, to associate Joe with Greenpeace. When you create an object reference property you need to specify which object type you refer to. Here is an example of an object reference property that points/refers to a person object.

<xs:element name="myObjectReferenceProperty"
        type="bccmsmodel:contentObjectReferenceType"
        bccmsmodel:acceptedContentTypes="bccmsmodel:personObject">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>
    My Object Reference Property (points to personObject)
      </bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
</xs:element>   

Note that the type of the property is bccmsmodel:contentObjectRefefenceType, a type defined by Astroboa. In addition, the attribute bccmsmodel:acceptedContentTypes specifies which object types the reference property is allowed to point to. In the previous example, myObjectReferenceProperty is allowed to refer to an object whose type is personObject. 

You are not restricted in providing a single object type in the the bccmsmodel:acceptedContentTypes attribute. The example below shows how to define a reference property which may point to objects whose type is personObject or cinemaPersonObject or theatrePersonObject.

<xs:element name="myObjectReferenceProperty"
        type="bccmsmodel:contentObjectReferenceType"
        bccmsmodel:acceptedContentTypes="bccmsmodel:personObject,
                         cinema:cinemaPersonObject,
                         theatre:theatrePersonObject">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>
    My Object Reference Property
    (points to personObject or cinemaPersonObject or
    theatrePersonObject )
      </bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
</xs:element>   

Here the cinema:cinemaPersonObject and theatre:threatrePersonObject are types provided by the cinema and theatre namespaces, respectively. Someone else has defined the cinemaPersonObject in the cinema namespace. Similarly, for the theatrePersonObject.

It is even possible to relax the restriction to the referenced type and allow references to any object type. The example below shows how to do:

<xs:element name="myObjectReferenceProperty"
        type="bccmsmodel:contentObjectReferenceType">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>
    My Object Reference Property
    (may point to any object - accepts all object types)
      </bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
</xs:element>  

Note that we have ommited the bccmsmodel:acceptedContentTypes attribute. Thus, our reference property may point to any object.

Complex properties

A complex property is an aggregation of properties whose type may be string, rich-text, numerical, boolean, date, dateTime, topic, object reference or another complex type. This way you can build richer properties, like the address property which may contain the streetName (string) property, streetNumber (numeric) property, poBox (string) property, and typeOfAddress (topic) property. You may define a complexType in two ways, the in-place and non-reusable way and the re-usable way. Here is the in-place definition of a complex property. You can add as many properties as you like.

<xs:element name="myNewObject">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>My New Object</bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
 
  <xs:complexType>
    <xs:complexContent>
      <xs:extension base="bccmsmodel:contentObjectType">
        <xs:sequence>

          <xs:element name="myStringProperty" type="xs:string">
            <xs:annotation>
              <xs:documentation xml:lang="en">
                <bccmsmodel:displayName>
                  My First String Property
                </bccmsmodel:displayName>
              </xs:documentation>
            </xs:annotation>
          </xs:element>

          <!-- Other properties here -->

          <xs:element name="myComplexProperty">
            
            <xs:annotation>
              <xs:documentation xml:lang="en">
                <bccmsmodel:displayName>
                  My Complex Property
                </bccmsmodel:displayName>
              </xs:documentation>
            </xs:annotation>

            <xs:complexType>
              <xs:sequence>

                <xs:element name="myStringProperty" type="xs:string">
                  <xs:annotation>
                    <xs:documentation xml:lang="en">
                      <bccmsmodel:displayName>My String Property</bccmsmodel:displayName>
                    </xs:documentation>
                  </xs:annotation>
                </xs:element>

                <xs:element name="myNumericProperty" type="xs:long">
                  <xs:annotation>
                    <xs:documentation xml:lang="en">
                      <bccmsmodel:displayName>My Numeric Property</bccmsmodel:displayName>
                    </xs:documentation>
                  </xs:annotation>
                </xs:element>

                <xs:element name="myTopicProperty" type="bccmsmodel:topicType"
                            bccmsmodel:acceptedTaxonomies="a-taxonomy-system-name">
                  <xs:annotation>
                    <xs:documentation xml:lang="en">
                      <bccmsmodel:displayName>My Topic Property</bccmsmodel:displayName>
                    </xs:documentation>
                  </xs:annotation>
                </xs:element>

                <xs:element name="myObjectReferenceProperty"
                            type="bccmsmodel:contentObjectType"
                            bccmsmodel:acceptedContentTypes="concrete/abstract content type">
                  <xs:annotation>
                    <xs:documentation xml:lang="en">
                      <bccmsmodel:displayName>My Reference Property</bccmsmodel:displayName>
                    </xs:documentation>
                  </xs:annotation>
                </xs:element>
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:element>    

We have defined a new property named myComplexProperty, in line 25, but we said nothing about its type, there is no "type" attribute here. We define a new in-line type between the <xs:complexType>...</complexType> tags in lines 35-73.

The myComplexProperty element is mandatory. In order to make it optional, add the minOccurs="0" maxOccurs="1" as shown below.

<xs:element name="myComplexProperty" minOccurs="0" maxOccurs="1">
  <!-- In-line type definition as above -->
</xs:element>   

Note that this does not affect the inner properties in the complex type declaration which remain mandatory.

Astroboa supports complex types which may contain only text. i.e. their content is simple content. In the following example, the complex type will be represented as a complex property with two child properties

  1. A property named 'color' which represents the attribute color
  2. A property named 'value' which represents the actual value of the complex property. The name 'value' is reserved in this context, therefore the complex type cannot define an attribute with that name.

 

<xs:complexType name="ComplexWithSimpleContentType">
   <xs:simpleContent>
      <xs:extension base="xs:string">
          <xs:attribute name="color" type="xs:string" />
      </xs:extension>
   </xs:simpleContent>
</xs:complexType>  

 

Creating properties that hold many values

All the properties we have defined so far accept a single value. There are two ways in which you make a property multi-value. The first way is to set the maxOccurs attribute when you define a property without making any further changes. We have two options, either specifying the upper bound of possible values e.g. setting maxOccurs="10" or leaving maxOccurs to unlimited values e.g. setting maxOccurs="unbounded". Here is how to define a string property that accepts at most 10 values.

<xs:element name="myMultipleValueStringProperty" type="xs:string" minOccurs="1" maxOccurs="10">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>A multiple value String Property - holds 10 values at most
      </bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
</xs:element>  

If you need to change the property to hold infinite number of values just set the "maxOccurs" to "unbounded" as shown below:

<xs:element name="myMultipleValueStringProperty" type="xs:string" minOccurs="1" maxOccurs="unbounded">
   <xs:annotation>
     <xs:documentation xml:lang="en">
       <bccmsmodel:displayName>
     A multiple value String Property - holds infinite values
       </bccmsmodel:displayName>
     </xs:documentation>
   </xs:annotation>
</xs:element>  

You can do the same thing for complex properties. In the following example the myMultivalueComplexProperty may hold unlimited number of values:

<xs:element name="myMultipleValueComplexProperty" minOccurs="1" maxOccurs="unbounded">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>My Complex Property</bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
  <xs:complexType>
    <xs:sequence>
      <xs:element name="myStringProperty" type="xs:string">
    <xs:annotation>
      <xs:documentation xml:lang="en">
        <bccmsmodel:displayName>
          My String Property
        </bccmsmodel:displayName>
      </xs:documentation>
    </xs:annotation>
      </xs:element>
      <xs:element name="myNumericProperty" type="xs:long">
    <xs:annotation>
      <xs:documentation xml:lang="en">
        <bccmsmodel:displayName>My Numeric Property</bccmsmodel:displayName>
      </xs:documentation>
    </xs:annotation>
      </xs:element>
      <xs:element name="myTopicProperty" type="bccmsmodel:topicType"
          bccmsmodel:acceptedTaxonomies="a-taxonomy-system-name">
    <xs:annotation>
      <xs:documentation xml:lang="en">
        <bccmsmodel:displayName>
          My Topic Property
        </bccmsmodel:displayName>
      </xs:documentation>
    </xs:annotation>
      </xs:element>
      <xs:element name="myObjectReferenceProperty" type="bccmsmodel:contentObjectReferenceType"
          bccmsmodel:acceptedContentTypes="concrete/abstract content type">
    <xs:annotation>
      <xs:documentation xml:lang="en">
        <bccmsmodel:displayName>
          My Reference Property
        </bccmsmodel:displayName>
      </xs:documentation>
    </xs:annotation>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
</xs:element>   

The other way to create a multi-value property is by defining a array that holds one or more multi-value properties. Let us assume that we are creating a student object type which has a property that holds student's grades. For this example, we assume that we do not hold information about which course the grade was assigned for. Here is how to define an array property called arrayOfGrade.

<xs:element name="arrayOfGrade" minOccurs="0" maxOccurs="1">
 
  <xs:annotation>
    <xs:documentation>
      <bccmsmodel:displayName>Grades</bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
 
  <xs:complexType>
 
    <xs:element name="grade" type="xs:string"
                minOccurs="1" maxOccurs="unbounded">
      
      <xs:annotation>
        <xs:documentation xml:lang="en">
          <bccmsmodel:displayName>Grade</bccmsmodel:displayName>        
        </xs:documentation>
      </xs:annotation>
    
    </xs:element>
    
  </xs:complexType>

</xs:element>

The arrayOfGrade is a single value, optional property that holds one or more values for the property grade (grade is a simple property; a string). In other words, all values of grade property are enclosed in an another property, the arrayOfGrade one.

There is a great difference between specifying a property as an array that holds many values (for a property) and specifying a multi-value property. Assume that we model the grade property as a multi-value property like this:

<xs:element name="grade" type="xs:string"
            minOccurs="1" maxOccurs="unbounded">
 
  <!-- grade is multi-value property -->
 
  <xs:annotation>
    <xs:documentation>
      <bccmsmodel:displayName>Grades</bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
   
</xs:element>

Here is how values are represented by each property. Note that, on the left-hand box the arrayOfGrade property encloses values for the grade property just like an array. On the other hand, on the right-hand box, no such array exists and grade values are list in a flat way, one below the other.

<!-- Using a grade 
     "array" property -->
<arrayOfGrade>
  <grade>A</grade>
  <grade>B</grade>
  <grade>D</grade>
  <!-- ... many more
       grades here ... -->
  <grade>A+</grade>
</arrayOfGrade>
<!-- Using flat multi-value 
     grade property -->
<grade>A</grade>
<grade>B</grade>
<grade>D</grade>
<!-- ... many more 
     grades here ... -->
<grade>A+</grade>
 

Create a concrete object type through extension

Astroboa comes with a set of abstract object types, such as the personType, designed for extension so as to create your own object types. You may need to extend an existing object type in order to add one or more properties that are not defined in the parent object type. Note that you may edit the XML schema of the parent type and add there new properties. However, you do not create a new object type in this way, rather you modify an existing object type. Moreover, it may not be possible to modify an existing type. For example, object types defined by Astroboa cannot be modified, they are read-only. Perhaps, you want to use another object type from another Astroboa which you are not allowed to modify it. Thus, extending the type is the only way to add more properties. Extending or inheriting an existing object type means that the new type contains all the properties of the parent type along with the new properties defined in the new object type.

The example below, shows how to extend the personType provided by Astroboa to create the myPersonObject concrete type. We start with the object definition preamble, shown below:

<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:bccmsmodel="http://www.betaconceptframework.org/schema/astroboa/model"
    xmlns:tns="http://www.myAstroboaObjects.org/schema/myNewObject"
    xmlns:person="http://www.betaconceptframework.org/schema/astroboa/identity/person"
    targetNamespace="http://www.myAstroboaObjects.org/schema/myNewObject"
    version="1.0">

  <xs:import namespace="http://www.betaconceptframework.org/schema/astroboa/model"
         schemaLocation="astroboa-model-3.0.0-SNAPSHOT.xsd"/>
  <xs:import namespace="http://www.betaconceptframework.org/schema/astroboa/identity/person"
         schemaLocation="person-3.0.0-SNAPSHOT.xsd" />
  <!-- The myPersonObject definition -->
</xs:schema>

The personType provided by Astroboa is defined in the person namespace identified by the http://www.betaconceptframework.org/schema/astroboa/identity/person URL. We import that namespace in the <xs:import ... />. We refer to this person namespace through the person alias defined in xmlns:person="http://www.betaconceptframework.org/schema/astroboa/identity/person" attribute.

The myPersonObject shown below, extends the personType abstract type in <xs:extension base="person:personType"> ... </xs:extension>. Note also that we prepend the personType with person as personType is defined in the person namespace.

<xs:element name="myPersonObject">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <bccmsmodel:displayName>My person object extends personType</bccmsmodel:displayName>
    </xs:documentation>
  </xs:annotation>
  <xs:complexType>
    <xs:complexContent>
      <xs:extension base="person:personType">
    <xs:sequence>
      <xs:element name="myFavoriteMovie" type="xs:string" minOccurs="0" maxOccurs="1">
        <xs:annotation>
          <xs:documentation xml:lang="en">
        <bccmsmodel:displayName>My favorite Movie title</bccmsmodel:displayName>
          </xs:documentation>
        </xs:annotation>
      </xs:element>
    </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:element>  

The myPersonObject type adds one more property, the myFavoriteMovie property to the personType abstract object type, however you may add as many properties as you like.

Create re-usable object types

Abstract object types provide a way to create re-usable object types, that is, object types which can be extended to create other concrete object types or abstract ones. In this way, you can create a library of object types, so other content modelers can take advantage and extend them to address their own needs. Remember that you cannot use an abstract type to directly create object instances so you need to create at least a concrete object type for an abstract type. In Astroboa, the personType is an abstract type and personObject is a concrete class. Thus, you create instances of personObject and not of personType. Note that Astroboa uses the Object suffix to designate a concrete type and the Type suffix to designate abstract types. You may use this naming scheme if you feel like but it is not necessary.

Here is how to create an abstract type named orderType and extend this type to create the concrete orderObject type. Log-in to the Astroboa Demo (Username: demo, Password: astroboa-demo) and choose "Add New... > XML Schema". In the filename field enter order.xsd and add the following code list shown below:

<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:bccmsmodel="http://www.betaconceptframework.org/schema/astroboa/model"
    xmlns:tns="http://www.myAstroboaObjects.org/schema/order"
    targetNamespace="http://www.myAstroboaObjects.org/schema/order"
    version="1.0">
  <xs:import namespace="http://www.betaconceptframework.org/schema/astroboa/model"
         schemaLocation="astroboa-model-3.0.0-SNAPSHOT.xsd"/>
 
  <!-- DEFINTITION OF ABSTRACT TYPE: orderType -->
  <xs:complexType name="orderType">
    <xs:annotation>
      <xs:documentation>
    <bccmsmodel:displayName>Order Type</bccmsmodel:displayName>
      </xs:documentation>
    </xs:annotation>
    <xs:complexContent>
      <xs:extension base="bccmsmodel:contentObjectType">
    <xs:sequence>
      <xs:element name="orderNumber" type="xs:string">
        <xs:annotation>
          <xs:documentation>
        <bccmsmodel:displayName>Order number</bccmsmodel:displayName>
          </xs:documentation>
        </xs:annotation>
      </xs:element>
    </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
 
  <!-- DEFINITION OF CONCRETE TYPE: orderObject -->
  <xs:element name="orderObject">
    <xs:annotation>
      <xs:documentation>
    <bccmsmodel:displayName>Order</bccmsmodel:displayName>
      </xs:documentation>
    </xs:annotation>
    <xs:complexType>
      <xs:complexContent>
    <xs:extension base="tns:orderType">
    </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>
</xs:schema>     

We define both the abstract type orderType and the concrete type orderObject in this xsd file. Don't add just the abstract type only because Astroboa will not recognize it. Note that you need to extend the contentObjectType as always. Once again we start with the preamble where we define our new type in the namespace identified by the following URL: http://www.myAstroboaObjects.org/schema/order.

There are two things you can do with this abstract type, either extend it and create a concrete type (described in the previous section) or extend it and create a new abstract type. 

We will create the specialOrderType abstract type extending the orderType and we will do this in a separate namespace which will identify it by the following URL: http://www.acme.com/schema/model/specialOrderType. So, log-in to the Astroboa Demo (Username: demo, Password: astroboa-demo) and choose "Add New... > XML Schema"; in the file name field enter specialOrder.xsd and enter the following code listing:

<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:bccmsmodel="http://www.betaconceptframework.org/schema/astroboa/model"
    xmlns:order="http://www.myAstroboaObjects.org/schema/order"
    xmlns:tns="http://www.acme.com/schema/model/specialOrderType"
    targetNamespace="http://www.acme.com/schema/model/specialOrderType"
    version="1.0">

  <xs:import namespace="http://www.betaconceptframework.org/schema/astroboa/model"
         schemaLocation="astroboa-model-3.0.0-SNAPSHOT.xsd"/>
  <xs:import namespace="http://www.myAstroboaObjects.org/schema/order"
         schemaLocation="order.xsd"/>

  <!-- Define specialOrderType which re-uses orderType -->
  <xs:complexType name="specialOrderType">
    <xs:annotation>
      <xs:documentation>
    <bccmsmodel:displayName>A Special Order Type</bccmsmodel:displayName>
      </xs:documentation>
    </xs:annotation>
    <xs:complexContent>
      <xs:extension base="order:orderType">
    <xs:sequence>
      <xs:element name="productId" type="xs:long">
        <xs:annotation>
          <xs:documentation>
        <bccmsmodel:displayName>Product id</bccmsmodel:displayName>
          </xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="orderDate" type="xs:dateTime">
        <xs:annotation>
          <xs:documentation>
        <bccmsmodel:displayName>Order Date - Time</bccmsmodel:displayName>
          </xs:documentation>
        </xs:annotation>
      </xs:element>
    </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <!-- Define specialOrderObject which extends specialOrderType -->
  <xs:element name="specialOrderObject">
    <xs:annotation>
      <xs:documentation xml:lang="en">
    <bccmsmodel:displayName>Special Order</bccmsmodel:displayName>
      </xs:documentation>
    </xs:annotation>
    <xs:complexType>
      <xs:complexContent>
    <xs:extension base="tns:specialOrderType">
      <xs:sequence>
        <xs:element name="deliveryDate" type="xs:date">
          <xs:annotation>
        <xs:documentation xml:lang="en">
          <bccmsmodel:displayName>Delivery Date</bccmsmodel:displayName>
        </xs:documentation>
          </xs:annotation>
        </xs:element>
      </xs:sequence>
    </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>
</xs:schema>  

Let's take it one step at a time. In line 11-12 we import the orderType type -actually the namespace that contains it- which we created in the previous section. We save the orderType in the order.xsd file and that file appears in the schemaLocation attribute in line 12. We refer to this namespace using the "order" alias, which we define in line 4, xmlns:order="http://myAstroboaObject.org/schema/order. Now we have all we need to extend the abstract type orderType.

We create the abstract specialOrderType in lines 15-43, extending the orderType in line 23. Recall that orderType already extends the contentObjectType, so our specialOrderType gets all properties defined in it. The specialOrderType defines two properties, the productId and the orderDate, both mandatory. Next, we define the concrete specialOrderObject in lines 47-61. We extend the specialOrderType in line 49. Note, that we say tns:specialOrderType because specialOrderType is defined in this namespace.

This section is incomplete and a work in progress.


Last Modified: 20 February 2012
ajax activity image Loading...