MicroStrategy ONE
Setting Block Properties
A block node has an arbitrary set of name/value pairs that defines the node. Each name/value pair is called a block property. A block property has a "type" which defines the range of acceptable values it may take. The type can be considered "scalar" or "composite". Scalar values include integer, boolean and string values while composite values are references to other blocks.
Assigning Static Scalar Values
In some occasions, however, the value of the property is static and can be assigned by the Block Library itself. Consider the value of the "dsstp" property for block “Report” (inherited from block Object) that was discussed in Block Inheritance.
<block name="Report" inherits="Object">
<definition>
<property name="numRows" type="Integer" />
<property name="numCols" type="Integer" />
</definition>
</block>
Property "dsstp" is the numeric type of the metadata object. Since the block "Report" represents a report, we know that the value of the "dsstp" property is always 3. In such a case, this value can be assigned to the property directly in the Block Library rather than setting this property programmatically.
The assignments element is used to indicate assignments that are performed by the Block Library. Inside this element, the property element is reused, but instead of declaring the property, it is merely referenced. The value of the property is placed in the text child node of the property element as follows.
<block name="Report" inherits="Object">
<definition>
<property name="numRows" type="Integer" />
<property name="numCols" type="Integer" />
</definition>
<assignments>
<property name="dsstp">3</property>
</assignments>
</block>
In this case, even though the "Report" block does not directly declare the "dsstp" property, it is inherited from the base block "Object". Regardless of where it is declared, the property already exists and so it can be validated. Here "3" is a valid Integer value.
The assignments element can also be used to assign "default values" for properties. As shown below, the Block Library assigns default values of 0 to "numRows" and "numCols".
<block name="Report" inherits="Object">
<definition>
<property name="numRows" type="Integer" />
<property name="numCols" type="Integer" />
</definition>
<assignments>
<property name="numRows">0</property>
<property name="numCols">0</property>
<property name="dsstp">3</property>
</assignments>
</block>
These properties can be modified later using Server-side Layout Definition Files.
Assigning Dynamic Scalar Values
On most occasions, a block is created by the Block Factory and populated with dynamic data programmatically using a specific API. In this case, the block has a number of predefined properties and a value is merely assigned to them as follows.
block.getProperty("dssid").setValue(someObject.getID());
Here the variable block refers to a block instance created by a call to the BlockFactory (e.g., via newBlock("Object")). The method getProperty returns a property named "dssid". The method setValue assigns a value to this property. In this case, the variable someObject calls the method getID to return a string.
For additional details on assigning dynamic scalar values, see Server-side Layout Definition Files.
Assigning Static or Dynamic Composite Values
Composite values have references to other blocks. Similar to assigning static scalar values, elements assignments and property element are used in the XML structure. However, instead of putting the value in a text node, the value is included in a nested block or list (depending on whether the type of the property is Block or List, respectively). Note the absence of the inherits element.
Consider a new block, C, which has a reference to two other Blocks:
<block name="C">
<definition>
<property name="t" type="Block" />
<property name="f" type="Block" />
</definition>
<assignments>
<property name="t">
<block name="Object" />
</property>
<property name="f">
<block name="Object" />
</property>
</assignments>
</block>
In the example above, two new properties, "t" and "f", are defined; both of type Block. The values of these properties, each pointing to the block “Object” are assigned using the assignments element.
The advantages of this representation are two-fold.
- A Block Tree can be created by using just the Block Factory.
- When block C is created, two instance of block “Object” are also created and attached to C.
You can also build up a list using the assignments element. Consider block D which contains a list of “Object” blocks:
<block name="D">
<definition>
<property name="objects" type="List" />
</definition>
<assignments>
<property name="objects">
<list>
<block name="Object" />
<block name="Object" />
</list>
</property>
</assignments>
</block>
When block D is created, it is pre-populated with the objects property pointing to a list of two block “Object” instances.
Assigning Static Composite Values to Specific Blocks
It is possible to initialize a composite property for a specific block using a nested property element.
From the example above, consider block “C” which has two properties, "t" and "f", both of type Block, with each pointing to the block “Object”.
<block name="C">
<definition>
<property name="t" type="Block" />
<property name="f" type="Block" />
</definition>
<assignments>
<property name="t">
<block name="Object" />
</property>
<property name="f">
<block name="Object" />
</property>
</assignments>
</block>
By nesting the property element, you can assign the value of the dsstp property of the “Object” block to "t" and "f" as shown below. The "t" property of “C” not only points to the “Object” block, but has its dsstp property set to 2.
<block name="C">
<definition>
<property name="t" type="Block" />
<property name="f" type="Block" />
</definition>
<assignments>
<property name="t">
<block name="Object">
<property name="dsstp">2</property>
</block>
</property>
<property name="f">
<block name="Object">
<property name="dsstp">1</property>
</block>
</property>
</assignments>
</block>
This form of nested property assignment can be performed to any arbitrary depth.
Inheriting Assignments
The concept of Block Inheritance (inheriting block properties) also extends to block assignments. That is, when block 2 inherits from block 1, it inherits the assignments of block 1 as well.
From the example above, consider block “C” which has two properties, "t" and "f", both of type Block, with each pointing to the block “Object”. By nesting the property element, the value of the dsstp property of the “Object” block is assigned to "t" and "f" as shown below. The "t" property of “C” not only points to the “Object” block, but has its dsstp property set to 2.
<block name="C">
<definition>
<property name="t" type="Block" />
<property name="f" type="Block" />
</definition>
<assignments>
<property name="t">
<block name="Object">
<property name="dsstp">2</property>
</block>
</property>
<property name="f">
<block name="Object">
<property name="dsstp">1</property>
</block>
</property>
</assignments>
</block>
Now assume we need to create a new block “E” that inherits from C. However, we want the "t" property to point to a Block (of type “Object”) that has a dsstp property, but this "t" property should have a value of 200 instead of 2.
This can be accomplished using the code below; however, the disadvantage to this approach is that if the "t" property changes and points to a different block in the future, the code in block “C” as well as in “E” would need to be changed.
<block name="E" inherits="C">
<assignments>
<property name="t">
<block name="Object">
<property name="dsstp">200</property>
</block>
</property>
</assignments>
</block>
An efficient way to create block “E” is by using a property path in the name element. In the context of a definition section, the name attribute of the property element is a simple name. That is, it is the name of the property to define. However, in the context of an assignments section, the name attribute can be a path to a property.
For our example block “E”, we want to assign 200 to the dsstp property which exists in the block “Object” pointed to by the "t" property. Using property path notation, we assemble the names of the properties that lead up to the target (from the currently defined block). We separate the names of the properties with forward slash ('/').
In our case, it would appear as t/dsstp. Here is how we would define block E more efficiently:
<block name="E" inherits="C">
<assignments>
<property name="t/dsstp">200</property>
</assignments>
</block>