5.2 Model Creation


  • The basic Element of XML

    • project

      The project element is the root of the application.

      These elements such as namespace, state, service, and zdb could be defined in the project element, which names the root of the namespace.


      <project name="limax" xmlns:xi="http://www.w3.org/2001/XInclude">                                   
      </project>
      

      The project "limax" is defined and the support of "XInclude" is enabled in the project element.


    • state

      The state element is defined in the project element and referenced by the manager element.

      The network server could run in multiple status. The state element defines the protocol and rpc which are allowed to accept by the network server in the current status. Though the View is strongly recommended, the protocol and rpc are also supported, because the View itself is implemented in protocol within the system.


      <state name="XXX">
          <namespace ref="a"/>
          <protocol ref="b.a"/>
          <rpc ref="b.c"/>
      </state>
      

      The state element is used to define the status "XXX", in which all the protocols and rpc in the namespace of "a", the protocol "a" in the namespace of the "b", and the protocol "c" in the namespace of the "b" are imported.

      The namespace allows the nesting. When using state to refer to the namespace, only the outermost layer could be referenced to avoid the confusion.


    • namespace

      The namespace element is defined in the project and namespace elements and referenced by the state element.

      The elements namespace, bean, protocol, rpc and view could be defined in the namespace element.


      <namespace name="gs" pvid="12">                                   
      </namespace>    
      

      The namespace element defines the namespace "gs" and the pvid of this namespace is set as 12. If there are nested namespaces, the outmost pvid is valid and the inner pvid is ignored.


    • bean

      The bean element is defined in the namespace elements, and used to define the variable as structured type.

      Both the enum and variable elements could be defined in the bean element.


      <bean name="b1">
          <enum name="e0" value="1"/>
          <variable name="v0" type="int"/>
          <variable name="v1" type="binary"/>
      </bean> 
      
      <bean name="b2">
          <variable name="a0" type="b1">
          <variable name="a1" type="string"/>
          <variable name="a2" type="list" value="float"/>
          <variable name="a3" type="vector" value="b1"/>
          <variable name="a4" type="set" value="b1"/>
          <variable name="a5" type="map" key="int" value="b1"/>    
      </bean>    
      

      In this example, the bean element "b2" refers to the bean element "b1". The detailed type reflection will be described in the next content.


    • protocol

      The protocol element could be defined in the element of namespace, and be referenced by the state element.

      Both the enum and variable elements could be defined in the protocol element, which is similar with the bean element.


      <protocol name="CHandShake" type="101" maxsize="1030">
          <variable name="dh_group" type="byte" />
          <variable name="dh_data" type="binary"/>
      </protocol>    
      

      The "101" protocol "CHandShake" is defined, and the maximum size allowed by this protocol is 1030. The protocol number in one PVID which is determined by the outermost namespace is not repetitive. If the value of the maximum size is set as 0, that means there is no limitation. In the actual operating environment, there is a compulsive constraint to limit the size of all the protocols for the server. The limitation could be adjusted via the execution parameter of the virtual machine just like java -D limax.net.Engine.limitProtocolSize=xxx, and the default value is 1M.


    • rpc

      The rpc element is defined in the namespace element, and referred by the state element.


      <bean name="CheckProviderKeyArg">
          <variable name="pvid" type="int" />
          <variable name="pvkey" type="string"/>
      </bean>
      <bean name="CheckProviderKeyRes">
          <variable name="errorcodes" type="int" />
      </bean>
      <rpc name="CheckProviderKey" type="305" argument="CheckProviderKeyArg"
              result="CheckProviderKeyRes" maxsize="1024" timeout="10000" />        
      

      The "305" rpc "CheckProviderKey" is defined , whose allowed maximum size is 1024, and the value of the timeout is set as 10000 millisecond. The parameters and results of the rpc should be the bean element. The rpc and protocol is numbered in the same namespace and could not be duplicated each other. The maximum size is used to limit the parameter and result individually and the bigger value of them is applied.

      Please pay special attention to that the rpc is only supported in the Java environment and used by the Limax framework itself. The other client versions except the Java do not support it. We suggest that DO NOT USE it.


    • view

      The view element is defined in the namespace element, and referred by the state element.

      If the bind element has no ref element contained, it should not refer to the table with xbean field containing ANY type. If the bind element has ref element, the xbean field referred by the ref element should not contain ANY type.


      <view name="globalview" lifecycle="global">
          <variable name="var4" type="list" value="MyBeanAll" />
          <bind name="bindfirst" table="first">
              <ref name="s" />
              <ref name="sets" />
          </bind>
          <bind name="bindsecond" table="second" />
          <control name="control1">
              <variable name="var1" type="int" />
              <variable name="var2" type="MyBean" />
          </control>    
      </view>    
      

      The global view "globalview" is defined here and contains the fields whose names are "var4", "bindfirst", "bindsecond" and the control "control1". The field "var4" is the normal field and changed via the set field in the view object. The field "bindfirst" is the bind field, and when the s field or the set filed in the value structure is changed, the value of the "bindfirst" is set as the structure organized by the "value.s" and "value.sets". The field "bindsecond" is the bind field and is set as the value when the value of the "second" table is changed. The "control1" is the control and the parameters are the structure organized by the "var1" and "var2".


      <namespace name="gs" pvid="12">
          <namespace name="for_session">
              <view name="firstview" lifecycle="session">
                  <variable name="var1" type="int" />
                  <bind name="bindsecond" table="second" />
              </view>
          </namespace>
          <namespace name="for_temp">
              <view name="TestTempView" lifecycle="temporary">
                  <variable name="var1" type="int" />
                  <subscribe name="_var1" ref="gs.for_session.firstview.var1" />
                  <subscribe name="_bindsecond" ref="gs.for_session.firstview.bindsecond" />
              </view>
          </namespace>    
      </namespace>    
      

      In this example, when the "var1" field of the temporary view "TestTempView" is changed, all the members of the "TestTempView" will receive this change. The subscribed fields "_var1" and "_bindsecond" of the "TestTempView" view separately subscribe the "var1" and "bindsecond" fields of the session View "firstview". In the members of the "TestTempView", if the "var1" or "bindsecond" field of one member's "firstview" is changed, this change will be broadcasted to all the members via "_var1" or "_bindsecond". Actually, the "_var1" and "_bindsecond" are implemented as map with the SessionId as the key. In particularly, when the member's "firstview.var1" is changed, this member will receive two changes, including "firstview.var1" and " TestTempView._var1[SessionId]".


    • service

      The service element is defined in the project element and describes the services supported by this project. Multiple services are allowed in one project.


      <service name="switcher">
          <manager name="SwitcherServer" type="server" initstate="EndpointKeyExchange" port="10000">
              <state ref="EndpointSessionLogin"/>
              <state ref="EndpointClient" />
          </manager>
          <manager name="ProviderServer" type="server" initstate="ForProvider" port="10100" />
          <manager name="AuanyClient" type="client" initstate="AuanyClient" port="10200" />
      </service>    
      

      This is the definition for the "Switcher" server components of the Limax.

      A server is composed by a serial network services and the manager element defines the network services. The "SwitcherServer" as the network server runs at the 10000 port and accepts the request from the client. The "ProviderServer" as the network server runs at the 10100 port and accepts the connection request from the Provider. The "AuanyClient" as the client of the Auany server component connects to the 10200 port of the Auany server.

      One network service could run in one or multiple status, refer to the protocol, rpc and view allowed in this status via state. The initial status of the service is defined by the initstate attribute and the other statuses are defined in the manager element.


      <state name="GsProvider">
          <namespace ref="gs" />
      </state>
      <service name="demogsd" useGlobalId="true" useZdb="true">
          <manager name="Provider" type="provider" initstate="GsProvider" port="10100"/>
      </service>    
      

      The service "demogsd" is defined here. The value of the type attribute in the manager element is "provider" which means that the source codes required by the provider is generated. The implementation of the Limax application noted in the previous contents is implementing the provider, that is the mostly common usage. Actually, the provider is the client of the Switcher server component, so the port 10100 determines that the connection between the provider and the Switcher server is the 10100 port. At the same time, the provider is the server of the application client, and the Switcher is used to forward the data of the protocol, rpc and view between the application client and the provider.

      The useGlobalId is used to determine whether to generate the configuration demanded by the GlobalId service components in the service configuration file.

      The useZdb is used to determine whether to generate the launch configuration template using Zdb in the service configuration file.

      In particular, the manager in the provider model supports only one status. There is no mean to define multiple status and this status refers to only one namespace, the PVID of which is used as the provider's PVID.


    • zdb

      The zdb element describes all the information of the database used by the application. One application use only one zdb database and at most only one zdb element could be defined in the project element.


    • cbean

      The cbean is described in the project, namespace and zdb.

      When the structured type is the key of the table, the key of the map, and the value of the set, it must be defined as the cbean. The cbean element is similar with the definition of the bean element, whose field members' types could be the primitive types except the binary and any, and the cbean, the container type excluded.

      In particular, the cbean element could be referred by the bean, protocol, rpc, view and control elements.


      <cbean name="xcompare">
          <variable name="b" type="boolean" />
          <variable name="s" type="short" />
          <variable name="i" type="int" />
          <variable name="l" type="long" />
          <variable name="text" type="string" />
      </cbean>
      <cbean name="xcompare2">
          <enum name="eX" value="1" />
          <variable name="xc1" type="xcompare" />
      </cbean>    
      

    • xbean

      The xbean is described in the zdb.

      When the structured type is the value of the table, it must be defined as the xbean. Similar with the definition of the bean, the types of the xbean's field members are all basic types, container type , cbean or xbean if the nested structured type could be used. Since the cbean is the constant bean, the object with this nested type could not be modified. The xbean also supports a special type --- any, which is none-persistent. When the xbean using the any type is the value of the table, the table only could be the memory table.

      In particular, the xbean without containing ANY type could be referred via the variable element by the bean, protocol, rpc, view and control. The bind element could not totally refer to the xbean table containing ANY type as the value, however, the partial reference to none ANY members is allowed.


      <xbean name="BasePlayerInfo">
          <variable name="name" type="string" />
          <variable name="level" type="int" />
          <variable name="sid" type="long"  />
      </xbean>
      
      <xbean name="WaitingPlayerInfo">
          <variable name="baseinfo" type="BasePlayerInfo" />
          <variable name="ready" type="boolean" />
      </xbean> 
      
      <xbean name="ObservePlayerInfo">
          <variable name="baseinfo" type="BasePlayerInfo"/>
          <variable name="obpos" type="int" />
      </xbean> 
      
      <xbean name="WaitingTableInfo">
          <enum name="POS_EAST" value="0"/>
          <enum name="POS_SOUTH" value="1"/>
          <enum name="POS_WEST" value="2"/>
          <enum name="POS_NORTH" value="3" />
          <enum name="POS_COUNT" value="4"/>
          <enum name="POS_OBSERVE" value="4" />
          <variable name="tableid" type="int"/>
          <variable name="players" type="vector" value="WaitingPlayerInfo" />
          <variable name="observe" type="vector" value="ObservePlayerInfo"/>
          <variable name="playing" type="boolean" />                
      </xbean>  
      
      <xbean name="RoomInfo">
          <variable name="name" type="string" capacity="32" />
          <variable name="hallid" type="long"  />
          <variable name="players" type="set" value="long" />
          <variable name="tables" type="vector" value="WaitingTableInfo"/>
      </xbean>  
      

      A complicated xbean structure is defined here.


      <xbean name="Any">
          <variable name="any" type="any:Object" capacity="32"/>
          <variable name="anyset" type="set" value="any:Object"/>
          <variable name="boolv" type="boolean" />
      </xbean>   
      

      An xbean element containing "any" type is defined, and the Object is "java.lang.Object" which could refer to any object. All legal java type, and common bean and view appeared in the description could be referenced in the behind of the "any:", because the bean and view themselves will generate the corresponding java class after generating the source code.


      <view name="Info" lifecycle="session">
          <variable name="info" type="BasePlayerInfo"/>
          <variable name="testany" type="Any"/>
      </view>   
      

      The variable field of this view refers to the xbean. The "testany" field is an "any" type, which is false because the exception threw in the code generation process will indicate that the "Info.testany" has the dependency on the "any" type. The any dependency is the iterative detection.


      <table name="anytable" key="int"  value="testany"  persistence="MEMORY"/>
      <view name="Info" lifecycle="session">
          <variable name="info"type="BasePlayerInfo"/>
          <bind name="bindtestany" table="anytable">
              <ref name="boolv"/>
          </bind>
      </view>   
      

      In this example, the bind element binds the "anytable" whose attribute type is xbean Any. Even though this xbean contains ANY type, only boolean field is referenced. So the description here is correct.


    • table

      The table element is used in the zdb database to describe the table.


      <table autoIncrement="true" cacheCapacity="4096" key="long" name="roominfos" persistence="MEMORY" value="RoomInfo"/>  
      

      The table is described in the zdb.

      In the "roominfos" table, the type of key is long, and the type of the value is the xbean "RoomInfo" which is defined in the previous content. The key with long type supports the automatic incremental under the condition that the attribute autoIncrement="true" is configured. The attribute persistence="MEMORY" determines that this table is memory table. The attribute cacheCapacity="4096" determines that this table could cache at most 4096 piece of records in the memory. For the memory table, once the number of the record exceeds the value of the cacheCapacity attribute, some records will be discarded.


      <table name="keyisxcompare2" key="xcompare2" value="string" cacheCapacity="4096"/>  
      

      In the "keyiscompare2" table, the key is the cbean type "xcompare2" defined in the previous content, and the value is the string. Without defining the persistence, it is a disk table.


      <table name="tany" key="int" value="Any" cacheCapacity="4096" persistence="MEMORY"/>  
      

      In the "tany" table, the type of the value is the xbean "Any" which is defined in the previous content. The xbean contains the "any" type field. The table is the memory table.


      <table autoIncrement="true" cacheCapacity="4096" key="long" name="testtype" value="TestType" lock="abc"/>
      <table name="secondaryindex" key="long" value="SecondaryIndex" cacheCapacity="2000" lock="abc"/>   
      

      There is a new attribute lock. The lock of the zdb database is row lock, in which the basic lock mode is lock(table, key) and the table with same lock attribute shares the lock. In this example, when the key row of the table "testype" is locked, the key row of the table "secondaryindex" is also locked. On the contrary, it is also correct. There is no error when locking the key row of the tables "testtype" and "secondaryindex" at the same time. The proper planning could simplify the lock.


    • monitorset

      The monitorset is described in the project or namespace to provide the relative monitor ability to the running data for the application.


      <monitorset name="TransactionMonitor" supportTransaction="false">
          <monitor name="runned" type="counter"/>
          <monitor name="false" type="counter" />
          <monitor name="exception" type="counter"/>
          <key name="procedureName" type="string"/>
      </monitorset>   
      

      This is the definition of the zdb transaction monitor set in the limax.xml. The key is the storage procedure name, which seperately defines three piece of count information for the storage procedure: the sum of the exectution, the sum of the false returned by the execution, and the sum of the exception threw by the execution.

      The supportTransaction points out that whether this monitor set needs the transaction feature or not. If the value is true, the count in the transaction, will be actually executed only if the transaction is successfully submitted.default is true.

      The type of the monitor has two: counter and gauge. The counter provides the increment function in the generated source code, and the gauge provides the set funtion.

      A monitorset allows multiple keys. Divided more finely, the type of the key only use the primitive type except for the binary and any.


  • Specification of the xml description

    The Limax describes the architecture of the project model via xml, and defines the named element and referenced element these two kinds of xml elements. There is this kind of element which is named element and referenced element at the same time. The resolution to the internal name of the xml follows the specification of the internal namespace.

    • The named element

      The named element includes the name attribute. The generated code link the name according to the particular specification and organizes the namespace of the project. The names of the table in the zdb database must be all low case, and the other names have no limitation.


    • The referenced element

      All the elements using ref attribute belong to the referenced element and the value of the ref attribute should be the reference of the named element. The subscribe element of the temporary View element not only belongs to the referenced element because it refers to the field of the session View, but also belongs to the named element which is named as the field of the current View.

      The variable element in all elements must define the type attribute. When the type attribute defines the structure described in the internal xml, bean, cbean and xbean, this variable element could be called as the referenced element. The variable element as the field element of the upper level element is named, so it is also the named element.


    • The specification of the internal namespace

      The named element in the same xml element should not have the same name.

      The element path is constituted by the parent's element name plus "." plus children's element name. The element path could expand out layer by layer till the root element, and the element path beginning from the root element is the full path. Both the element name and element path could legally refer to the element itself.

      In the processing of the generating source code, when the ambiguous element reference issue is reported, the longer element path should be used to resolve the ambiguity issue. For example, the bean "X" is defined both in the namespace A and in the namespace B. When some variable element defines the field, the "X" is appointed as the type. So there is ambiguous error reported when generating the source code. In this case, "A.X" or "B.X" should be correctly chosen to eliminate the ambiguity.


    • The special conditions

      1. The zdb element is also the named element. Because its name would not be applied in the generated source code, no name is allowed and the default name is empty string in this case. For the convenient of resolving the namespace, the name is acceptable in the required condition.

      2. As the special const type bean, the cbean is the global and does not be restricted by the namespace. In the whole project, the name of the cbean described in anywhere could not be duplicated.

      3. The name of the table must be low case is because that the name will be directly used to name the table file when using the file database. If the operating system uses a case-insensitive file system such as windows, the applications running on this kind of operating system should totally use low case as the best solution to avoid the conflict that may arise.

      4. The ref element in the bind element, which looks like the named element, should be interpreted that it combines with the table attribute of the bind element and refers to the fields of the xbean. The reason why it is designed like this is that the description is simple and clear, or the ref attribute should be added into the bind element, and the names of the xbean's fields are separated by the comma.


Prev Next