New eXistdb distribution addresses the needs of professional users
Rüsselsheim, Germany – January 27, 2014
eXist Solutions today announced eXist LTS, a long-term support version of the well-know NoSQL database eXistdb. ‘LTS’ is available as an especially tested and maintained subscription of the community edition establishing a stable application platform for professional and enterprise users. Additional service-level agreements complement the new commercial offerings.
LTS addresses the needs of users that require a stable version or do not have the capacity to follow the open source community in search for improvements and bugfixes. The community edition however will continue to stay free and un-restricted.
eXistdb is used in many application domains and has users around the globe. Started as a native XML database it has grown to a full-fledged application server including an application packaging facility, a browser-based IDE to develop your code as well as various tools to administer and manage the platform. With a fine-grained authorization model and a powerful forms framework it is ideally suited for managing complex data.
eXistdb increases the productivity by using a single data-model across all layers of an application thereby completely avoiding the need for mapping tools. All prominent XML standards like XQuery, XPath, XSL, XML Schema, XForms and others are available for use out-of-the-box. With it’s support for XML and binary data eXistdb is ideally suited for managing semi-structured data. Applications range from content management, eHealth, science, network and configuration management to solutions in the digital humanities, technical documentation, publishing and data integration.
about eXist Solutions
eXist Solutions was formed by the developers behind the Open Source native XML database ‘eXistdb’ to offer commercial support and consulting around the product and XML technologies in general. eXist solutions and the betterFORM team have joined forces to provide optimal support for the product and continue to enhance the platform.
Why this news on the betterFORM blog?
The answer is simple: eXist Solutions (the company behind eXist-db) and betterFORM have joined forces to integrate their two long-standing projects and offer commercial support for this new platform. As true Open Sourcers we’ll continue to offer this new product as free, Open Source software. Not much change here. But additionally there now will be subscription-based support for those that need long-term reliability for their commercial applications.
Beyond having integrated our products to work seamlessly with each other we have also joined our skill set and experience in the XML domain. We offer this joint expertise to our customers as consulting, development and training services to enable them to build better applications in less time.
See the new eXist-db homepage for details.
Since: betterFORM 5.0rc1 – buildNumber:11612
Model Item Properties (MIPs) are one of the central features of XForms. In short they allow to add constraints to XML nodes. The available MIPs are:
- readonly – boolean XPath expression
- required – boolean XPath expression
- calculate – XPath expression
- relevant – boolean XPath expression
- constraint – boolean XPath expression
- type – XML Schema simple datatype or extension thereof
However with XForms 1.1 each of these MIPs were allowed to be attached to a node only once. If a bind element happened to attach one MIP to same node a second time the processor would throw a XFormsBindingException.
This was rather limiting expecially with respect to the ‘constraint’ MIP as in practice it often happens that you’d like to test for more than one condition. Of course you can combine conditions with a simple ‘and’ like so:
<xf:bind nodeset="a" constraint=". > 5 and . < 10" />
But this leads to long and hard to read expressions. Wouldn’t it be much nicer to be able to write:
<xf:bind nodeset="a" constraint=". > 5" /> <xf:bind nodeset="a" constraint=". < 10" />
MIPs in XForms 2.0…
This is exactly what is addressed in the upcoming XForms 2.0. It now allows that one and the same MIP is attached to the same node several time and defines some combination rules. This table was taken from the current XForms 2.0 Draft.
‘all’ means that all conditions are chained with a boolean ‘and’ so all conditions must become true for the constraint validation to become true. ‘one’ on the other hand combines the statement with boolean ‘or’.
The combination rules for ‘constraint’, ‘relevant’, ‘required’ and ‘readonly’ are now implemented in betterFORM. But we went some steps further and also picked up some of the ideas from a post published under the name ‘MIP Names, Type, Etc.’ on the W3C XForms group wiki.
Besides using the syntax shown above you are now able to write the following statements:
<xf:bind ref="a"> <bf:constraint value=". > 5"/> <bf:constraint value=". < 10" /> </xf:bind>
The custom element ‘constraint’ in the betterFORM namespace is an alternative notation that allows some interesting options beyond making the markup even more readable. See this:
<xf:bind ref="a"> <bf:constraint value=". > 5"> <xf:alert>The value must be bigger than 5</xf:alert> </bf:constraint> <bf:constraint value=". < 10" > <xf:alert>The value must be smaller than 10</xf:alert> </bf:constraint> </xf:bind>
Here we find our good old friend the ‘alert’ element which XForms authors know as one of the child elements of XForms controls to signal an error. The alerts are now attached to a single constraint MIP and allow to tell the user exactly which of multiple constraints has failed in a given situation.
But there’s even more. In some situations even a single condition might be complicated and therefore hard to read. This is especially true when it’s crammed into an attribute. Now you can also write:
<xf:bind ref="a"> <bf:constraint> <bf:value> my really long and complicated possibly multiline XPath </bf:value> <xf:alert>The value must be bigger than 5</xf:alert> </bf:constraint> </xf:bind>
Besides for constraint also
<bf:relevant/> <bf:required/> <bf:readonly/>
are supported and useable in the same way.
Of course the new custom syntax fully harmonizes with the standard syntax so the following will be perfectly valid:
<xf:bind ref="a"> <bf:constraint value=". > 5"> <xf:alert>The value must be bigger than 5</xf:alert> </bf:constraint> </xf:bind> ... <xf:bind nodeset="a" constraint=". < 10"/>
One Question left
Great, now we have the ability to signal to the user what exactly went wrong, combine several occurrences of a MIP and we can trigger each UI control bound to that node. But what if we do not want that? It might be even confusing if alert messages pop up in the UI at several places.
So we need a mechanism to selectively and explicitly say that we want an error to be displayed for a given control. We currently solved this like so:
<xf:input ref="a"> <xf:label>a text</xf:label> <xf:alert srcBind="aBind"/> </xf:input>
‘srcBind’ is an idref and points to an existing bind with id=’aBind’. This is taken as the root element for all alerts that might be displayed (if their respective constraint fails) or not displayed (if their respective constraint passes). The xf:alert in the UI becomes a container for all messages whose constraint fails and are displayed as a stack.
We hope these extensions are useful and welcome your feedback.
Since: betterFORM 5.0rc1 - buildNumber:11541
A while back the XForms Working Group proposed to use @ref Attribute everywhere in XForms and replace all usages of @nodeset. We have followed this proposal and implemented this in betterFORM 5 development branch. This means that you don’t have to think any more which attribute (@ref or @nodeset) is right for the given element.
As a consequence the following elements now also accept @ref:
- repeat + repeat-ref
We appreciate this simplification and hope it helps avoiding authoring errors. Of course old forms that use @nodeset will continue to work.
Since: betterFORM 5.0rc1 – buildNumber:11523
Author: Lars Wndauer
When building applications with many forms and especially when using a lot of subforms you’re often facing a lot of markup redundancy. This article shows a new utility in betterFORM to avoid such redundant parts thereby making your applications more maintainable.
In the XML world there is the well-known XInclude specification that handles includes in the XML markup language. However this specification only handles very simple file inclusions. If you have more fine-grained snippets to assemble you have to go for XPointer in addition which has unfortunately some shortcomings – it’s simply not or only partly implemented in many environments and has a somewhat crude syntax.
This article shows a more pragmatic approach which has been developed by the betterFORM team during its work on a large customer project.
Example 1 – simple inclusion
<xf:model> <xf:instance id="i-contacts" src="data/contacts.xml"/> <bf:include src="templates/binds-contacts.xml"/> </xf:model>
This isn’t differnt to what you would get from XInclude. It simply includes a complete file and replaces the <bf:include /> tag with that.
If authors don’t want to create a bind file for any group of binds but to manage them in a single file this is possible as well. Imagine a bind.xml as shown in example 2.
Example 2 – inclusion of a specific element
This example goes one step further allowing you to address a specific id in the referenced file. Consider the XML snippet below:
<binds> <bind id="b-contacts" nodeset="contacts"> <bind nodeset="user/@shortname" constraint="string-length(.) > 5" /> </bind> <bind id="b-events" nodeset="contacts"> … </bind </bind>
To reference the “b-contact” bind in your form simply use the fragment identifier on the URI: <bf:include src=”templates/binds.xml#b-contacts />.
This technique already allows to group similar contents together in one file but to use them in different contexts.
Form authors will quickly see how useful this small extension is, but they will also notice that in the real world things are often not as easy as this. Consider example 3.
Example 3 – add some markup to the inclusion
Often when building large form applications with XForms you’re facing markup that is largely the same in different contexts. This is especially true with many submissions that load the same data in different parts of the application. But you have to repeat the whole block just to add a different a different error-handler as the message in the example below:
<xf:submission id="s-load-data" resource="context:payload" method="get" replace="instance" instance="i-default"> <xf:message id="load-data-error-handler" ev:event="xforms-submit-error" ref="instance('i-lang')/msg[@key='submissionLoadError']"/> </xf:submission>
To handle this use case the bf:include mechanism provides an additional bf:action attribute that can be used to add some markup.
This can be achieved with the following markup:
<bf:include src="templates/submission.xml#s-load-data"> <xf:message bf:action="append" id="load-data-error-handler" ev:event="xforms-submit-error" (...) </bf:include/>
Please note the bf:action attribute here. This tells the engine to append the xf:message element to the included submission with id=”s-load-data”.
Extend Included Markup
Markup included via bf:include can easily be extended using the bf:action attribute. Example 4 shows how the bf:action attribute value “append” is used to chain a submission transforming the instance data to the “s-load-data” submission.
Example 4 – Append
<bf:include src="templates/submission.xml#s-load-data"> <xf:send bf:action="append" ev:event="xforms-submit-done" submission="s-transform-data"/> </bf:include/>
Overwrite Included Markup
Another scenario that comes up quite often is that a single piece of the included markup must be overwritten with some other markup. Example 5 shows how this can be achieved. Here the error message from example 3 is overwritten with another error submission handler:
<bf:include src="templates/submission.xml#s-load-data"> <xf:send id="load-data-error-handler" bf:action="overwrite" ev:event="xforms-submit-done" submission="s-error-handler"/> </bf:include/>
It should be noted that this inclusion mechanism can be applied at deploy- or runtime. If you want to apply inclusions at runtime you have to configure betterFORM to do so by editing the betterform-config.xml file and setting the property “webprocessor.doIncludes” to “true”.
No question bf:include especially in combination with the XForms subforms mechanism is a powerful technique for form authors when writing maintainable enterprise applications. The bf:action attributes will be available in the upcoming betterFORM 5 release. If you can’t wait simply check out the betterFORM development branch at https://github.com/betterFORM/betterFORM/tree/development and get started.
Note: the inclusion is currently still not yet integrated within the build process of betterFORM. This will follow at a later stage.
XForms has a MVC architecture and this it what makes it so powerful when it comes to build complex applications that reach far beyond a few fields with validation. But as applications grow there naturally comes the requirement for modularization. Models are the building blocks of an XForms application.
XForms already supports multiple models on one page, each with its own, encapsulated instances and constraints. But models must be able to exchange some data in order to act as a whole in a larger architecture. Sometimes this just means to pass a single or only a few values and sometimes this means to exchange whole instances. At the same time a model should enforce some kind of encapsulation as known from object-oriented languages to ensure consistency and robustness.
Before discussing possible ways to enable model-to-model communication it should be mentioned that there is already a pattern to exchange instances between models. As two models existing in a page can perfectly use the same instance URI to load and submit data it’s already possible to ‘share’ those. But first this comes to the price of serializing the data as XML and re-parsing them when loading into the other model. Second – there will be two (detached) copies of the same instance – one in each model that need to be synchronized with each other.
Alternatives for data-exchange between models
Though XForms is not a new technology there are no established patterns for data-exchange between models. The following paragraphs are based upon our experiences with this topic. Though the need has existed before the upcoming of subforms has made the need for some kind of data-exchange more urgent as for maximum re-use of subforms (which can be full-fledged standalone forms in other contexts) you’ll likely want your models to be as independent and loosely coupled as possible.
The following paragraphs present some approaches we found during our project work over time. It should be noted that these techniques are custom betterFORM extensions to the standard but equivalents might be found in other XForms implementations.
If complete instances or larger parts of them need to be shared between models a cross-model submission is the right answer. An example might an address model that shall be re-used within a larger context that also needs the address instance data structure for incorporation into one of its instances.
<xf:submission ref="instance()" resource="context:aKey" method="put" replace="none" ...
A bit of background will help to understand what the ContextSubmissionHandler is doing. In betterFORM each instance of a XForms processor maintains a hashmap called ‘context’ with params. E.g. this map holds URL params and http headers that were used to call the XForms page and serves as a way to pass in some values for use within the form. The above submission stores the default instance into this map under the key ‘aKey’. To fetch the instance from that map the following submission can be used:
<xf:submission ref="instance('another')" resource="context:aKey" method="get" replace="instance" ...
Here the ‘get’ method is used to read the previously stored instance from the map and replace instance ‘another’ with it. For safety the submissionhandler is consuming which means that the instance will be deleted automatically from the ‘context’ hashmap once it has been read.
This kind of submission is especially useful in conjunction with subforms – if you are using multiple subforms e.g. in a wizard and you want to pass instance data from one subform to another the context hashmap is the right way to do it. Form A might already have been destroyed when loading form B but the instance data can survive within the context hashmap and be used in the next step of the wizard.
Another advantage of cross-model submissions is that one model can re-use the validation constraints and logic of another without breaking the encapsulation between the models as data exit and enter a model through its interface – the submission module. As the data are exchanged directly between models within a single instance of an XForms processor its reasonably safe to rely on validations done by a foreign model without duplicating binding constraints in both models.
The instanceOfModel() function
If there are only a few values to be passed the instanceOfModel(modelId, instanceId) function is a way to do this. It takes two params – the id of a model and the id of an instance within that model.
<xf:setvalue ref="instanceOfModel('modelA', 'default')/baz" value="instanceOfModel('modelB','default')/foo/bar"/>
In this case the value of the XPath ‘foo/bar’ in the ‘default’ instance of ’modelB’ will be set to the node ‘baz’ in the instance ‘default’ of ‘modelA’. Easy enough but this function also is somewhat dangerous as users might expect this function to work in any context. E.g. they might expect that instanceOfModel can also be used on bind elements. But this would create inter-model dependencies which is not a healthy thing to do. The XForms dependency engine was designed to efficiently handle dependencies within one model but not to create dependencies between models. Ignoring this could cause serious consequences for the consistency of data.
For this reason this function should be used with caution. As long as its used in conjunction with the setvalue action everything should be fine but you shouldn’t use it within a model. Therefore if in doubt the method proposed in the next section should be preferred.
Dispatching custom events
Dispatching a custom event with contextinfo is a less intrusive way of passing values between models than the instanceOfModel() function (and avoids its dangers). It uses the ability of XML Events to carry context information along with the actual event. A small addition to the standard XForms dispatch action allows you to specify custom parameters for a event and pass a set of values to a target in another model. As always an example illustrates this best.
Somewhere within the scope of model ‘A’ a dispatch action is fired. It passes two params as contextinfo to the event. The first one is a static string while the second (someXPath) pulls a value from an instance in model ‘A’.
<xf:group model="A"> --- <xf:dispatch name="customEvent" targetid="foo"> <xf:contextinfo name="param1" value="'hello'"/> <xf:contextinfo name="param2" value="someXPath"/> </xf:dispatch> ... </xf:group>
Somewhere in the scope of Model ‘B’ a handler for ‘customEvent’ is defined and can access the passed params with the standard XForms event() function. – That easy.
<group model="B" id="foo"> <xf:action ev:event="customEvent"> <xf:setvalue ref="staticResult" value="event('param1')"/> <xf:setvalue ref="xpathResult" value="event('param2')"/> </xf:action> ... </xf:group>
Though this method uses a bit more markup than the instanceOfModel approach it avoids its dangers. As it passes data by value and not by reference it honors the encapsulation of models.
This article was intended to show some alternatives for the model-to-model communication in XForms. However it is assumed that this is not the end of the discussion and other ways will be invented and hopefully be standardized in future version of XForms.
As always comments and suggestions are more than welcome.