.. _mergeable-xml: ============= Mergeable XML ============= .. contents:: :local: :depth: 3 Overview ======== Cloud Softphone and all apps based on Acrobits SDK allows various configurations to be provisioned from the server. At the same time, the apps often contain "settings" or "preferences" GUI which lets the end user set various configuration options. In such a situation, collisions are possible. In case the values from settings GUI and from provisioing are simply saved, values entered by end user will be overwritten by provisioning and vice versa, which leads to chaos and bad user experience. To overcome this, we created a simple system of merging the values based on priorities, which may be either set explicitly, or be deduced automatically from where the values came from. Data Model ========== As the name suggests, Mergeable XML works with XML documents. These documents are treated as key-value stores, where names of nodes which are children of the root nodes are the keys and content of these nodes are values. The node values may be strings - text data inside the nodes, or xml sub-trees, in which case, the whole sub-tree is taken as a single value. .. important:: Mergeable XML document can be seen as a list of key-value pairs, where keys are strings and values may be either strings, or XML sub-trees. Example: .. code-block:: xml example.com udp This example defines a key-value store of three entries: host=>example.com, transport=>udp and rewriting=>(xml tree). This is an actual example of :ref:`account-xml`, which uses Mergeable XML model. The XML nodes which are immediate children of root node will be called ``key nodes`` and the content of these nodes (either strings or XML sub-trees) will be called ``values``. Priorities ========== Every key node in Mergeable XML must have two attributes: ``priority`` and ``source``. ``source`` ---------- The attribute ``source`` is a human readable name which explains where does the key node came from (for example ``default``, ``gui`` etc.) and its value is not used for anything else than troubleshooting. ``priority`` ------------ This attribute contains an integer value in decimal notation. This value specifies the priority of this particular key-value entry, which determines whether this value is going to be overwritten or not. .. important:: Existing key node is overwritten by an incoming key node **ONLY** if the priority of the incoming key node is same or higher than priority of the existing key node. In case the key-node IS overwritten, the incoming key node value and attributes replace the existing key node value and attributes. Merging ======= In case the app stores some data as Mergeable XML, the values may never be written directly. The only way to modify this data is by merging-in other Mergeable XML. The process of merging decides whether the values should be written or not based on key node priorities. Default Priorities ================== The incoming XML to be merged in may come from various sources: provisioning from Cloud Softphone portal, response of some provisioing web service or it may be created by the app GUI when the user saves the form. The attributes ``priority`` and ``source`` don't need to be always explicitly defined; in case they are not set, the app will deduce them based on the origin of the data and assign a default priority: +---------------+----------+-----------------------------------------------------------------+ | source | priority | description | +===============+==========+=================================================================+ | default | 0 | default value, hardcoded in the app | +---------------+----------+-----------------------------------------------------------------+ | provisioning | 10 | values coming from Cloud Softphone portal | +---------------+----------+-----------------------------------------------------------------+ | extProv | 20 | values coming from external provisioning web services | +---------------+----------+-----------------------------------------------------------------+ | gui | 40 | values set by end users using GUI | +---------------+----------+-----------------------------------------------------------------+ | system | 100 | values set by system which should never be overwritten | +---------------+----------+-----------------------------------------------------------------+ .. note:: Priorities of 100 and higher are reserved and should not be used. The app stores various persistent data using these priorities and accidentally overwriting them may cause undefined behavior. Localized values ================ In case of string values, it is possible to specify them either as text contents of the XML node, like shown in the example above for ``transport`` or ``host``, or as a xml tree with multiple ``>`` nodes for different languages. Example: .. code-block:: xml Nahrávaný hovor 記録されたコール Recorded Call The key node ``dialAction`` is a localizable node. The app will pick the string from ```` subnode which matches the current device locale. If such node is not found, the app will take the value from ```` subnode which does not contain a ``lang`` attribude - this node serves as a default. If such a node also doesn't exist, the app uses the text contents of key node, just like in non-localized case. Examples ======== Let's assume the app has an account with values and priorities as in the previous example. The user opens "edit account" form and decides to change the ``transport`` to ``tcp``. When saving the form, the app internally generates the following Mergeable XML: .. code-block:: xml tcp It will then try to merge this document with the one stored in the app. Since the incoming priority of 40 is higher than the stored priority of 20, the merge will be performed and the resulting document will look as follows: .. code-block:: xml example.com tcp If later, the external provisioning web service is called again and it sends the key node ``transport`` in its response, the app will assign default priority of 20 to this node and attempt to merge it. This time, the value will not be written, because the existing priority of 40 is higher and the user-entered value stays. In case the provider later decides to explicitly set the ``transport`` key node priority higher, it can return the following node in the external provisioning response: .. code-block:: xml url This time, the value will be merged, because the priority is higher than the stored 40. When the user opens "edit account" form now, he will see the ``transport`` field as read-only, because the GUI is intelligent and knows that any new value would get a default priority of 40 and would not beat the existing priority of 50. .. note:: In case the value is XML tree, the value is taken as a whole. If the external provisionig web service sends a node ```` in its response, the whole content of the incoming node will be stored. The merging process is not recursive. Filters ======= Some values coming from provider's web services may not be merged even if the priority is set high enough. In case the incoming value would enable functionality which is not included among the selected Cloud Softphone features on Cloud Softphone portal, the relevant key node will be filtered out even before merging is attempted.