How to branch a menu that is in a complex grid UI - mobile

We are trying to create a large menu in movilizer to support all our options, while doing so we are using a grid complex UI to support larger devices.
Because we use the complex grid UI we currently have 3 menu's and 2 text fields in our complex grid. However we cannot use the menu to branch to different movelets that are called after pressing the buttons in those menu's.
<question key="Q003" type="6">
<answer attributeType="14"
key="A003_1"
nextQuestionKey="Q407"
<text>menu1button</text>
</answer>
<answer attributeType="72"
key="A003_5"
nextQuestionKey="Q004">
<predefinedValue>X</predefinedValue>
</answer>
<complex linearGroupId="Information" gridGroupId="gridMenu" gridHorizontalLayout="false" linearPos="1" gridPosX="0" gridPosY="1" groupTitle="menuGrid"/>
</question>
<question key="Q004" type="6">
<answer attributeType="14"
key="A004_1"
nextQuestionKey="Q408"
<text>menu2button</text>
</answer>
<answer attributeType="72"
key="A004_3"
nextQuestionKey="Q005">
<predefinedValue>X</predefinedValue>
</answer>
<complex linearGroupId="Information" gridGroupId="gridMenu" gridHorizontalLayout="false" linearPos="2" gridPosX="1" gridPosY="1" groupTitle="menuGrid"/>
</question>
This example excerpt from our code will throw an error saying branching is not allowed for question Q003, however we need these seperate menu's.
Is there any way to circumvent this problem without having to create different movelets for each menu?
Thanks in advance!

you can only achieve this using MEL scripts.
Basic idea is:
you save the selection for all menus that are in the complex UI via MEL scripts
all answers in the first Q in the complex UI link to the second question in the complex UI
all answers in the second Q in the complex UI link to the third question of the complex UI ... and so on
The last question of the complex UI links to an epsilon screen
The epsilon screen uses restrictions that check the selection of the different menus to branch the flow accordingly
This can then look something like this (simplified), Q003:
<question key="Q003" type="6">
<answer key="A003_1"
nextQuestionKey="Q004">
<text>menu1button</text>
</answer>
<answer attributeType="72"
key="A003_DEFAULT"
nextQuestionKey="Q004">
<predefinedValue>X</predefinedValue>
</answer>
<onEnterAssignment>
$local:selections = null;
</onEnterAssignment>
<onLeaveOkPersistAssignment>
$local:selections["Q003"] = getQuestionKey();
</onLeaveOkPersistAssignment>
<complex linearGroupId="Information" gridGroupId="gridMenu" gridHorizontalLayout="false" linearPos="1" gridPosX="0" gridPosY="1" groupTitle="menuGrid"/>
</question>
Q004:
<question key="Q004" type="6">
<answer key="A004_1"
nextQuestionKey="QEPS">
<text>menu2button</text>
</answer>
<answer attributeType="72"
key="A004_DEFAULT"
nextQuestionKey="QEPS">
<predefinedValue>X</predefinedValue>
</answer>
<onLeaveOkPersistAssignment>
$local:selections["Q004"] = getQuestionKey();
</onLeaveOkPersistAssignment>
<complex linearGroupId="Information" gridGroupId="gridMenu" gridHorizontalLayout="false" linearPos="2" gridPosX="1" gridPosY="1" groupTitle="menuGrid"/>
</question>
And QEPS (which does the branching, very simplified):
<question key="QEPS" type="41">
<answer key="AEPS_1"
nextQuestionKey="END"/>
<restriction position="0" nextQuestionKey="Q003">
<condition>$local:selections["Q003"] != $answer:"A003_DEFAULT" ?OR $local:selections["Q004"] != $answer:"A004_DEFAULT"</condition>
</restriction>
</question>

Related

DataProperties in Subclass expression

I tried working with the OWL2-RL rules build into graphdb. I am obviously doing something wrong or understood something wrong. Here is my toy ontology.
<?xml version="1.0"?>
<rdf:RDF xmlns="http://www.semanticweb.org/rlehmann/ontologies/2017/10/untitled-ontology-182#"
xml:base="http://www.semanticweb.org/rlehmann/ontologies/2017/10/untitled-ontology-182"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:untitled-ontology-182="http://www.semanticweb.org/rlehmann/ontologies/2017/10/untitled-ontology-182#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:ontology="http://www.some/ontology/">
<owl:Ontology rdf:about="http://www.semanticweb.org/rlehmann/ontologies/2017/10/untitled-ontology-182"/>
<!-- http://www.some/ontology/hasValue -->
<owl:DatatypeProperty rdf:about="http://www.some/ontology/hasValue">
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
</owl:DatatypeProperty>
<!-- http://www.some/ontology/ClassA -->
<owl:Class rdf:about="http://www.some/ontology/ClassA"/>
<!-- http://www.some/ontology/InvA -->
<owl:NamedIndividual rdf:about="http://www.some/ontology/InvA">
<rdf:type rdf:resource="http://www.some/ontology/ClassA"/>
<ontology:hasValue rdf:datatype="http://www.w3.org/2001/XMLSchema#string">StringValue</ontology:hasValue>
</owl:NamedIndividual>
<!-- http://www.some/ontology/InvB -->
<owl:NamedIndividual rdf:about="http://www.some/ontology/InvB">
<ontology:hasValue rdf:datatype="http://www.w3.org/2001/XMLSchema#string">FooBar</ontology:hasValue>
</owl:NamedIndividual>
<owl:Restriction>
<owl:onProperty rdf:resource="http://www.some/ontology/hasValue"/>
<owl:someValuesFrom rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
<rdfs:subClassOf rdf:resource="http://www.some/ontology/ClassA"/>
</owl:Restriction>
</rdf:RDF>
If I did not misunderstand Table 2 in OWL2-Profiles this ontology should be in OWL2 RL profile. I would expect "InvB" to be classified as type ClassA. But it doesn't. It actually does with reasoners (HermiT, Pellet, ...) but not with Rules (Drools, Graphdb) is this a gap in the specification.
How can my Ontology be "repaired" or is there any workaround?
Cheers,
Robert
Not using anonymous classes on the left-hand side of the GCI is not an option for our application. And yes object properties work perfectly.
After some research we actually found out, that it can never work that way. In the GraphDB .pie file that corresponds to the RL-Profile there is only a notion to some rules "// These are not implemented (and probably not implementable)". This includes the rule "dt-type2" defined in OWL2 RL Section 4.3 Table 8. RDF section 3.1 gives the actual answer why this is not supposed to work.
RDF Graphs
An RDF graph is a set of RDF triples.
3.1 Triples
An RDF triple consists of three components:
the subject, which is an IRI or a blank node
the predicate, which is an IRI
the object, which is an IRI, a literal or a blank node
"FooBar"^^xsd:string rdf:type xsd:string this is simply not allowed but obviously required.
We are quite uncertain what the guys at w3c had in mind besides RDF?!
As it is now, this kind of inference will not work in GraphDB at all (and on no rule engines in general?). But it is not the fault of GraphDB but merely a gap in the specification chain.
However, we did a workaround in our ontology that solves the problem and is working for us. We simply
defined new concepts for the data types we use
Transformed all DataProperties to ObjectProperties
introduces new DataType properties with domain one of the new datatype concepts and range xsd:xyz. For example Property:hasStringValue Domain:string Range:xsd:string
This works for us.

XML Value buried inside the node

I'm brand new to XML, but not SQL. I have data structured by our app vendor as follows that I'm trying to load up into a table:
<windowsets>
<windows>
<question>
<id Value="81b25d-9385-sk3" />
<displayname Value="Thermal Break" />
<answername Value="Yes" />
</question>
<question>
<id Value="73v32k-2743-fd9" />
<displayname Value="Panel Profile" />
<answername Value="Medium Stille" />
</question>
</windows>
</windowsets>
Through other posts here I found and got as far as creating:
select
t.x.value('(id [#Value]/text())[1]','varchar(100)') QuestionID,
t.x.value('(displayname [#Value]/text())[1]','varchar(255)') DisplayName,
t.x.value('(answername [#Value]/text())[1]','varchar(255)') AnswerName
from #xmlData.nodes('//windowsets/windows/question') as T(X)
But it returns nulls for all columns, and I'm guessing that's because it's expecting the format of:
<displayname>Panel Profile</displayname>
So being the XML novice and all the searching I've done hasn't help me understand how to change the code to pull it when the value is buried in node (not even sure of correct terminology I'm so new).
THANK you for your help!
It is called attributes.
To read attributes from xml try something like this
select
t.x.value('(id/#Value)[1]','varchar(100)') QuestionID,
t.x.value('(displayname/#Value)[1]','varchar(255)') DisplayName,
t.x.value('(answername/#Value)[1]','varchar(255)') AnswerName
from #xmlData.nodes('//windowsets/windows/question') as T(X)
This is not an new answer, just some explanation and to much for a comment:
The part within the square brackets is called predicate and is kind of a filter. Your expression
displayname [#Value]/text())[1]
will read the text() of <displayname> and will check, if the attribute #Value exists. Anyway, there is no element's text, so it will return NULL.
You must navigate down the path like .../displayname/#Value if you want to read the attribute's value.
This answer shows some examples how XML deals with empty members.

Reasoner in Protege not working with Restrictions/Cardinalities

I am currently building/modifying a larger ontology. As I had problems to define restrictions I build a very short example:
I have EuropeanCountry as a class and IslandCountry as a class:
<owl:Class rdf:about="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#EuropeanCountry">
<rdfs:subClassOf rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#Country"/>
</owl:Class>
<!-- http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#IslandCountry -->
<owl:Class rdf:about="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#IslandCountry">
<rdfs:subClassOf rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#Country"/>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#borders"/>
<owl:maxQualifiedCardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">0</owl:maxQualifiedCardinality>
<owl:onClass rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#EuropeanCountry"/>
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>
As you can see I set a "maxQualifiedCardinality" restriction in Protege. If I create some individuals and (C1, C2 and Germany are EuropeanCountry, Island is IslandCountry) and relate them with the border property:
<owl:NamedIndividual rdf:about="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#Island">
<rdf:type rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#IslandCountry"/>
<borders rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#C1"/>
<borders rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#C2"/>
<borders rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#Germany"/>
</owl:NamedIndividual>
I get an error thrown by Hermit reasoner that it is not allowed to set 3 neighbours to Island. If I now change the line
<owl:maxQualifiedCardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">1</owl:maxQualifiedCardinality>
to cardinality 1 I don't get any error if I set three neighbours as shown in the example.
Can anyone explain this and hopefully provide me a solution how I can write a restriction that one class should have x other classes (in this case how to write that Island should have 2 neighbours and a third one will throw an error by the reasoner)?
Thanks for your help and kind regards,
tanktoo
Edit:
I have now added all individuals to an AllDifferent:
<rdf:Description>
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#AllDifferent"/>
<owl:distinctMembers rdf:parseType="Collection">
<rdf:Description rdf:about="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#C1"/>
<rdf:Description rdf:about="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#C2"/>
<rdf:Description rdf:about="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#Germany"/>
</owl:distinctMembers>
</rdf:Description>
It is now working with the restriction above and the reasoner tells me that I am not allowed to set 3 border countries as maxCardinality is 1.
I have now changed my restriction to the following:
<owl:Class rdf:about="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#IslandCountry">
<rdfs:subClassOf rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#Country"/>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#borders"/>
<owl:minQualifiedCardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">1</owl:minQualifiedCardinality>
<owl:onClass rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#EuropeanCountry"/>
</owl:Restriction>
</rdfs:subClassOf>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#borders"/>
<owl:maxQualifiedCardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">2</owl:maxQualifiedCardinality>
<owl:onClass rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#EuropeanCountry"/>
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>
I would now expect that the reasoner detects an error if I set less than 1 or more than 2 neighbours:
<owl:NamedIndividual rdf:about="http://www.semanticweb.org/tanktoo
/ontologies/2016/10/untitled-ontology-81#Island">
<rdf:type rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#IslandCountry"/>
<borders rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#C1"/>
<borders rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#C2"/>
<borders rdf:resource="http://www.semanticweb.org/tanktoo/ontologies/2016/10/untitled-ontology-81#Germany"/>
</owl:NamedIndividual>
In this case the reasoner detects an errro because there are 3 neighbours. If I now delete all the neighbours so that Island border 0 countries the reasoner doesn't give me an error. Can someone explain me why?
Thanks for your help :)
I get an error thrown by Hermit reasoner that it is not allowed to set 3 neighbours to Island
If this is what the tool says, then it is a mistake. Granted, you are giving 3 names of bordering countries. But nothing says that these are names of 3 different countries. They could be several names of the same country, like "France", "Republic of France", "République française".
Since the reasoner has no way of knowing whether they are names of the same thing or not, it can't detect an inconsistency in the second case. However, in the first case, having at least a name for something means that there is strictly more than zero thing, so it makes sense that an inconsistency is detected.
If you'd like to make sure the reasoner detects when a country has more than 2 neighbours, then you'd have to explicitly say that the countries are different:
ex:C1 owl:differentFrom ex:C2, ex:Germany .
ex:C2 owl:differentFrom ex:Germany .
or:
[] a owl:AllDifferent;
owl:members ( ex:C1 ex:C2 ex:Germany ) .
In Protégé, in the Individual tab, you can specify from what an individual is different.

Submit data-table in JSF / Primefaces?

I am working on a web application using jsf/ primefaces, netbeans and tomcat.
I have a datatable with some values loaded in from another table and some editable fields. My question is, after the user has edited this table how do i submit the whole table so it can be stored in a database, in a new table?
<h:form id="form" prependId="false">
<h3>All of your Paddocks</h3>
<p:dataTable var="paddock" value="#{paddock.getfromPaddock()}" editable="true">
<p:ajax event="rowEdit" listener="#{paddock.onRowEdit}" />
<p:ajax event="rowEditCancel" listener="#{paddock.onRowCancel}" />
<p:column headerText="Id">
<h:outputText value="#{paddock.idPaddock}" />
</p:column>
<p:column headerText="Name">
<h:outputText value="#{paddock.name}" />
</p:column>
<p:column headerText="Area">
<h:outputText value="#{paddock.area}" />
</p:column>
<p:column headerText="Enter Grass Weight">
<p:cellEditor>
<f:facet name="output"><h:outputText value="0" /></f:facet>
<f:facet name="input"><p:inputText id="modelInput" value="0" style="width:100%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column style="width:32px">
<p:rowEditor />
</p:column>
</p:dataTable>
<h:commandButton value="Log" action="#{paddock.add}" />
</h:form>
Note that the only editable column is the grass column.
First of all, there are two main mistakes which may have undesired side effects:
<h:form ... prependId="false">
Never use prependId. Remove the whole attribute.
<p:dataTable var="paddock" value="#{paddock.getfromPaddock()}">
You should give var a different name than the managed bean. E.g. paddockItem.
As to the concrete question, your other mistake is here:
<p:inputText id="modelInput" value="0" />
You didn't bind the input value to the model. So JSF won't be able to update the model with the submitted values anyway.
Fix it accordingly, e.g.:
<p:inputText id="modelInput" value="#{paddockItem.grass}" />
In the submit method, it'll be right away there in the model.
You should only make absolutely sure that you aren't interacting with the database in the getter method of the <p:dataTable value>, otherwise you will be overwriting the model on every iteration round, hereby basically trashing the submitted values until the last row before the submit method is hit. The strange method name behind the data table value value="#{paddock.getfromPaddock()}" namely suggests that you're doing that. If it were a real property, the average starter would just have used value="#{paddock.fromPaddock}" or so.
See also:
How and when should I load the model from database for h:dataTable

Movilizer - Menu Item in a Complex UI Navigation not working properly?

I'm trying to create a Complex UI consisting of a Menu Item screen (type="6") at the top and a Text Input Screen (type="5") below. I want the Menu Item Screen to go to another screen than the Text Item Screen, though I have to put the Text Item Screen in the nextQuestionKey attribute.
I tried it with a restriction in the Menu Item Screen as shown in the code below, but the validator tells me "Branching is not allowed."
I tried moving the restriction to the Text Input Screen. There the validator tells me that "A menu screen in a complex screen which is not at the end must provide a valid, pre-defined forward navigation answer of attributeType=72"
<question key="15" type="6" backNavigationAllowed="true" sortAnswersByClientKey="false">
<answer key="15_1" nextQuestionKey="16" clientKey="CK#15">
<text>Scan barcode</text>
</answer>
<restriction nextQuestionKey="17" position="0">
<condition>getAnswerValueByClientKey($answer:"15_1", "CK#15") != ""</condition>
</restriction>
<complex linearGroupId="InputAssetNumber" gridGroupId="InputAssetNumber" linearInnerScrollbar="false" gridInnerScrollbar="false" gridHorizontalLayout="false" linearPos="0" gridPosX="0" gridPosY="0" gridWidth="1" gridHeight="1" linearHeight="1" groupTitle="Input Asset number"/>
</question>
<question key="16" type="5" backNavigationAllowed="true" sortAnswersByClientKey="false">
<answer key="16_1" nextQuestionKey="18" clientKey="CK#16" columnSizeType="ROWS">
<text>Enter barcode manually</text>
</answer>
<answer key="16_2" nextQuestionKey="18" clientKey="CK#16" columnSizeType="ROWS">
<text>Reason</text>
</answer>
<complex linearGroupId="InputAssetNumber" gridGroupId="InputAssetNumber" linearInnerScrollbar="false" gridInnerScrollbar="false" gridHorizontalLayout="false" linearPos="1" gridPosX="0" gridPosY="1" gridWidth="1" gridHeight="1" linearHeight="1"/>
</question>
I would appreciate if someone could help me find a solution to this problem.
I think the easiest way to achieve this is to change the sequence of screens so the Text Item screen points to the Menu screen. In the Complex UI you can still display the menu on top if you want, so the sequence for the navigation has no impact on that. In the Menu screen you define a default answer to point to question key 18 ... the clickable answer in the menu screen points to question 17.
For the default answer feature see:
https://devtools.movilizer.com/confluence/display/DOC22/Default+Answer+feature+for+Image+Menu+screens
<question key="15" type="5" backNavigationAllowed="true" sortAnswersByClientKey="false">
<answer key="15_1" nextQuestionKey="16" clientKey="CK#16" columnSizeType="ROWS">
<text>Enter barcode manually</text>
</answer>
<answer key="15_2" nextQuestionKey="16" clientKey="CK#16" columnSizeType="ROWS">
<text>Reason</text>
</answer>
<complex linearGroupId="InputAssetNumber" gridGroupId="InputAssetNumber" linearInnerScrollbar="false" gridInnerScrollbar="false" gridHorizontalLayout="false" linearPos="1" gridPosX="0" gridPosY="1" gridWidth="1" gridHeight="1" linearHeight="1"/>
</question>
<question key="16" type="6" backNavigationAllowed="true" sortAnswersByClientKey="false">
<answer key="16_1" nextQuestionKey="17" clientKey="CK#17">
<text>Scan barcode</text>
</answer>
<answer key="16_2" nextQuestionKey="18" clientKey="CK#18" attributeType="72">
<text>default answer</text>
<predefinedValue>X</predefinedValue>
</answer>
<complex linearGroupId="InputAssetNumber" gridGroupId="InputAssetNumber" linearInnerScrollbar="false" gridInnerScrollbar="false" gridHorizontalLayout="false" linearPos="0" gridPosX="0" gridPosY="0" gridWidth="1" gridHeight="1" linearHeight="1" groupTitle="Input Asset number"/>
</question>
This means that initially the complex UI will display an OK button. If the user presses the OK button, the client navigates to question 18. If the user prsses the Scan barcode button, the client navigates to question 17.

Resources