svn commit: r1648152 [1/2] - in /ofbiz/trunk/framework/widget: dtd/widget-catalog.xml dtd/widget-common.xsd dtd/widget-screen.xsd src/org/ofbiz/widget/ModelWidgetCondition.java src/org/ofbiz/widget/screen/ModelScreenCondition.java

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r1648152 [1/2] - in /ofbiz/trunk/framework/widget: dtd/widget-catalog.xml dtd/widget-common.xsd dtd/widget-screen.xsd src/org/ofbiz/widget/ModelWidgetCondition.java src/org/ofbiz/widget/screen/ModelScreenCondition.java

adrianc
Author: adrianc
Date: Sun Dec 28 07:37:03 2014
New Revision: 1648152

URL: http://svn.apache.org/r1648152
Log:
Extract screen widget condition models to a separate class so they can be reused in other widgets.

Added:
    ofbiz/trunk/framework/widget/dtd/widget-common.xsd
    ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetCondition.java
Modified:
    ofbiz/trunk/framework/widget/dtd/widget-catalog.xml
    ofbiz/trunk/framework/widget/dtd/widget-screen.xsd
    ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ModelScreenCondition.java

Modified: ofbiz/trunk/framework/widget/dtd/widget-catalog.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/dtd/widget-catalog.xml?rev=1648152&r1=1648151&r2=1648152&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/dtd/widget-catalog.xml (original)
+++ ofbiz/trunk/framework/widget/dtd/widget-catalog.xml Sun Dec 28 07:37:03 2014
@@ -26,6 +26,7 @@ under the License.
 <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
   <!-- <public publicId="-//W3C//DTD SVG 1.0//EN" uri="svg10.dtd"/> -->
 
+  <system systemId="http://ofbiz.apache.org/dtds/widget-common.xsd" uri="widget-common.xsd"/>
   <system systemId="http://ofbiz.apache.org/dtds/widget-form.xsd" uri="widget-form.xsd"/>
   <system systemId="http://ofbiz.apache.org/dtds/widget-menu.xsd" uri="widget-menu.xsd"/>
   <system systemId="http://ofbiz.apache.org/dtds/widget-screen.xsd" uri="widget-screen.xsd"/>

Added: ofbiz/trunk/framework/widget/dtd/widget-common.xsd
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/dtd/widget-common.xsd?rev=1648152&view=auto
==============================================================================
--- ofbiz/trunk/framework/widget/dtd/widget-common.xsd (added)
+++ ofbiz/trunk/framework/widget/dtd/widget-common.xsd Sun Dec 28 07:37:03 2014
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+
+    <xs:complexType name="ConditionRootType">
+        <xs:choice>
+            <xs:element ref="and" />
+            <xs:element ref="or" />
+            <xs:element ref="xor" />
+            <xs:element ref="not" />
+            <xs:element ref="if-service-permission" />
+            <xs:element ref="if-has-permission" />
+            <xs:element ref="if-entity-permission" />
+            <xs:element ref="if-validate-method" />
+            <xs:element ref="if-compare" />
+            <xs:element ref="if-compare-field" />
+            <xs:element ref="if-regexp" />
+            <xs:element ref="if-empty" />
+        </xs:choice>
+    </xs:complexType>
+    <xs:element name="AllConditionals" abstract="true" />
+    <xs:element name="condition" type="ConditionRootType" />
+    <xs:element name="and" substitutionGroup="AllConditionals">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element maxOccurs="unbounded" ref="AllConditionals" />
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="xor" substitutionGroup="AllConditionals">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element maxOccurs="unbounded" ref="AllConditionals" />
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="or" substitutionGroup="AllConditionals">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element maxOccurs="unbounded" ref="AllConditionals" />
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="not" substitutionGroup="AllConditionals">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element ref="AllConditionals" />
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="if-service-permission" substitutionGroup="AllConditionals">
+        <xs:complexType>
+            <xs:attribute type="xs:string" name="service-name" use="required" />
+            <xs:attribute type="xs:string" name="resource-description" use="optional" />
+            <xs:attribute type="xs:string" name="context-map" use="optional" />
+            <xs:attribute name="main-action" use="optional">
+                <xs:simpleType>
+                    <xs:restriction base="xs:token">
+                        <xs:enumeration value="CREATE" />
+                        <xs:enumeration value="UPDATE" />
+                        <xs:enumeration value="DELETE" />
+                        <xs:enumeration value="VIEW" />
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:attribute>
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="if-has-permission" substitutionGroup="AllConditionals">
+        <xs:complexType>
+            <xs:attribute type="xs:string" name="permission" use="required" />
+            <xs:attribute type="xs:string" name="action" />
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="if-entity-permission" substitutionGroup="AllConditionals">
+        <xs:complexType>
+            <xs:choice minOccurs="0">
+                <xs:element minOccurs="0" maxOccurs="1" ref="permission-condition-getter" />
+                <xs:element minOccurs="0" maxOccurs="1" ref="related-role-getter" />
+                <xs:element minOccurs="0" maxOccurs="1" ref="auxiliary-value-getter" />
+            </xs:choice>
+            <xs:attribute type="xs:string" name="entity-name" use="required" />
+            <xs:attribute type="xs:string" name="entity-id" use="required">
+                <xs:annotation>
+                    <xs:documentation>Can have multiple pipe separated values, but don't use spaces.</xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="target-operation" use="required">
+                <xs:annotation>
+                    <xs:documentation>Can have multiple pipe separated values, but don't use spaces.</xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="display-fail-cond" default="false">
+                <xs:simpleType>
+                    <xs:restriction base="xs:token">
+                        <xs:enumeration value="true" />
+                        <xs:enumeration value="false" />
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:attribute>
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="permission-condition-getter">
+        <xs:complexType>
+            <xs:attribute type="xs:string" name="entity-name" />
+            <xs:attribute type="xs:string" name="operation-field-name" />
+            <xs:attribute type="xs:string" name="role-field-name" />
+            <xs:attribute type="xs:string" name="auxiliary-field-name" />
+            <xs:attribute type="xs:string" name="status-field-name" />
+            <xs:attribute type="xs:string" name="privilege-field-name" />
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="related-role-getter">
+        <xs:complexType>
+            <xs:attribute type="xs:string" name="entity-name" />
+            <xs:attribute type="xs:string" name="role-entity-name" />
+            <xs:attribute type="xs:string" name="role-type-field-name" />
+            <xs:attribute type="xs:string" name="party-field-name" />
+            <xs:attribute type="xs:string" name="owner-entity-field-name" />
+            <xs:attribute type="xs:string" name="entity-id-name" />
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="auxiliary-value-getter">
+        <xs:complexType>
+            <xs:attribute type="xs:string" name="entity-name" />
+            <xs:attribute type="xs:string" name="auxiliary-field-name" />
+            <xs:attribute type="xs:string" name="entity-id-name" />
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="if-validate-method" substitutionGroup="AllConditionals">
+        <xs:annotation>
+            <xs:documentation>Calls a static Java method that takes a String and returns a boolean.</xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:attribute type="xs:string" name="field" use="required" />
+            <xs:attribute type="xs:string" name="method" use="required" />
+            <xs:attribute type="xs:string" name="class" default="org.ofbiz.base.util.UtilValidate" />
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="if-compare" substitutionGroup="AllConditionals">
+        <xs:complexType>
+            <xs:attribute name="field" type="xs:string" use="required" />
+            <xs:attribute name="operator" use="required">
+                <xs:simpleType>
+                    <xs:restriction base="xs:token">
+                        <xs:enumeration value="less" />
+                        <xs:enumeration value="greater" />
+                        <xs:enumeration value="less-equals" />
+                        <xs:enumeration value="greater-equals" />
+                        <xs:enumeration value="equals" />
+                        <xs:enumeration value="not-equals" />
+                        <xs:enumeration value="contains" />
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:attribute>
+            <xs:attribute name="value" type="xs:string" use="required" />
+            <xs:attribute name="type" default="String">
+                <xs:simpleType>
+                    <xs:restriction base="xs:token">
+                        <xs:enumeration value="PlainString" />
+                        <xs:enumeration value="String" />
+                        <xs:enumeration value="BigDecimal" />
+                        <xs:enumeration value="Double" />
+                        <xs:enumeration value="Float" />
+                        <xs:enumeration value="Long" />
+                        <xs:enumeration value="Integer" />
+                        <xs:enumeration value="Date" />
+                        <xs:enumeration value="Time" />
+                        <xs:enumeration value="Timestamp" />
+                        <xs:enumeration value="Boolean" />
+                        <xs:enumeration value="Object" />
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="format" />
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="if-compare-field" substitutionGroup="AllConditionals">
+        <xs:complexType>
+            <xs:attribute name="field" type="xs:string" use="required" />
+            <xs:attribute name="operator" use="required">
+                <xs:simpleType>
+                    <xs:restriction base="xs:token">
+                        <xs:enumeration value="less" />
+                        <xs:enumeration value="greater" />
+                        <xs:enumeration value="less-equals" />
+                        <xs:enumeration value="greater-equals" />
+                        <xs:enumeration value="equals" />
+                        <xs:enumeration value="not-equals" />
+                        <xs:enumeration value="contains" />
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:attribute>
+            <xs:attribute name="to-field" type="xs:string" />
+            <xs:attribute name="type" default="String">
+                <xs:simpleType>
+                    <xs:restriction base="xs:token">
+                        <xs:enumeration value="PlainString" />
+                        <xs:enumeration value="String" />
+                        <xs:enumeration value="BigDecimal" />
+                        <xs:enumeration value="Double" />
+                        <xs:enumeration value="Float" />
+                        <xs:enumeration value="Long" />
+                        <xs:enumeration value="Integer" />
+                        <xs:enumeration value="Date" />
+                        <xs:enumeration value="Time" />
+                        <xs:enumeration value="Timestamp" />
+                        <xs:enumeration value="Boolean" />
+                        <xs:enumeration value="Object" />
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:attribute>
+            <xs:attribute type="xs:string" name="format" />
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="if-regexp" substitutionGroup="AllConditionals">
+        <xs:complexType>
+            <xs:attribute type="xs:string" name="field" use="required" />
+            <xs:attribute type="xs:string" name="expr" use="required" />
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="if-empty" substitutionGroup="AllConditionals">
+        <xs:complexType>
+            <xs:attribute type="xs:string" name="field" use="required" />
+        </xs:complexType>
+    </xs:element>
+</xs:schema>

Modified: ofbiz/trunk/framework/widget/dtd/widget-screen.xsd
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/dtd/widget-screen.xsd?rev=1648152&r1=1648151&r2=1648152&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/dtd/widget-screen.xsd (original)
+++ ofbiz/trunk/framework/widget/dtd/widget-screen.xsd Sun Dec 28 07:37:03 2014
@@ -18,10 +18,11 @@ specific language governing permissions
 under the License.
 -->
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+    <xs:include schemaLocation="http://ofbiz.apache.org/dtds/widget-common.xsd" />
     <xs:element name="screens">
         <xs:complexType>
             <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="screen"/>
+                <xs:element maxOccurs="unbounded" ref="screen" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
@@ -57,7 +58,7 @@ under the License.
     <xs:element name="section" substitutionGroup="AllWidgets">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" ref="condition" />
+                <xs:element name="condition" type="ScreenConditionRootType" minOccurs="0" />
                 <xs:element minOccurs="0" ref="actions" />
                 <xs:element minOccurs="0" ref="widgets" />
                 <xs:element minOccurs="0" ref="fail-widgets" />
@@ -67,217 +68,25 @@ under the License.
     </xs:element>
 
     <!-- ================ CONDITIONS ================ -->
-    <xs:element name="AllConditionals" abstract="true"/>
-    <xs:element name="condition">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element minOccurs="1" maxOccurs="1" ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="and" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="xor" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="or" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="not" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-service-permission" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="service-name" use="required" />
-            <xs:attribute type="xs:string" name="resource-description" use="optional" />
-            <xs:attribute type="xs:string" name="context-map" use="optional" />
-            <xs:attribute name="main-action" use="optional">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="CREATE" />
-                        <xs:enumeration value="UPDATE" />
-                        <xs:enumeration value="DELETE" />
-                        <xs:enumeration value="VIEW" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-has-permission" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="permission" use="required" />
-            <xs:attribute type="xs:string" name="action" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-entity-permission" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:choice minOccurs="0">
-                <xs:element minOccurs="0" maxOccurs="1" ref="permission-condition-getter" />
-                <xs:element minOccurs="0" maxOccurs="1" ref="related-role-getter" />
-                <xs:element minOccurs="0" maxOccurs="1" ref="auxiliary-value-getter" />
-            </xs:choice>
-            <xs:attribute type="xs:string" name="entity-name" use="required" />
-            <xs:attribute type="xs:string" name="entity-id" use="required">
-                <xs:annotation>
-                    <xs:documentation>Can have multiple pipe separated values, but don't use spaces.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="target-operation" use="required">
-                <xs:annotation>
-                    <xs:documentation>Can have multiple pipe separated values, but don't use spaces.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute name="display-fail-cond" default="false">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="permission-condition-getter">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="entity-name" />
-            <xs:attribute type="xs:string" name="operation-field-name" />
-            <xs:attribute type="xs:string" name="role-field-name" />
-            <xs:attribute type="xs:string" name="auxiliary-field-name" />
-            <xs:attribute type="xs:string" name="status-field-name" />
-            <xs:attribute type="xs:string" name="privilege-field-name" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="related-role-getter">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="entity-name" />
-            <xs:attribute type="xs:string" name="role-entity-name" />
-            <xs:attribute type="xs:string" name="role-type-field-name" />
-            <xs:attribute type="xs:string" name="party-field-name" />
-            <xs:attribute type="xs:string" name="owner-entity-field-name" />
-            <xs:attribute type="xs:string" name="entity-id-name" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="auxiliary-value-getter">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="entity-name" />
-            <xs:attribute type="xs:string" name="auxiliary-field-name" />
-            <xs:attribute type="xs:string" name="entity-id-name" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-validate-method" substitutionGroup="AllConditionals">
-        <xs:annotation>
-            <xs:documentation>Calls a static Java method that takes a String and returns a boolean.</xs:documentation>
-        </xs:annotation>
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field" use="required" />
-            <xs:attribute type="xs:string" name="method" use="required" />
-            <xs:attribute type="xs:string" name="class" default="org.ofbiz.base.util.UtilValidate" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-compare" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute name="field" type="xs:string" use="required" />
-            <xs:attribute name="operator" use="required">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="less" />
-                        <xs:enumeration value="greater" />
-                        <xs:enumeration value="less-equals" />
-                        <xs:enumeration value="greater-equals" />
-                        <xs:enumeration value="equals" />
-                        <xs:enumeration value="not-equals" />
-                        <xs:enumeration value="contains" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="value" type="xs:string" use="required" />
-            <xs:attribute name="type" default="String">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="PlainString" />
-                        <xs:enumeration value="String" />
-                        <xs:enumeration value="BigDecimal" />
-                        <xs:enumeration value="Double" />
-                        <xs:enumeration value="Float" />
-                        <xs:enumeration value="Long" />
-                        <xs:enumeration value="Integer" />
-                        <xs:enumeration value="Date" />
-                        <xs:enumeration value="Time" />
-                        <xs:enumeration value="Timestamp" />
-                        <xs:enumeration value="Boolean" />
-                        <xs:enumeration value="Object" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="format" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-compare-field" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute name="field" type="xs:string" use="required" />
-            <xs:attribute name="operator" use="required">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="less" />
-                        <xs:enumeration value="greater" />
-                        <xs:enumeration value="less-equals" />
-                        <xs:enumeration value="greater-equals" />
-                        <xs:enumeration value="equals" />
-                        <xs:enumeration value="not-equals" />
-                        <xs:enumeration value="contains" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="to-field" type="xs:string" />
-            <xs:attribute name="type" default="String">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="PlainString" />
-                        <xs:enumeration value="String" />
-                        <xs:enumeration value="BigDecimal" />
-                        <xs:enumeration value="Double" />
-                        <xs:enumeration value="Float" />
-                        <xs:enumeration value="Long" />
-                        <xs:enumeration value="Integer" />
-                        <xs:enumeration value="Date" />
-                        <xs:enumeration value="Time" />
-                        <xs:enumeration value="Timestamp" />
-                        <xs:enumeration value="Boolean" />
-                        <xs:enumeration value="Object" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="format" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-regexp" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field" use="required" />
-            <xs:attribute type="xs:string" name="expr" use="required" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-empty" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field" use="required" />
-        </xs:complexType>
-    </xs:element>
+
+    <xs:complexType name="ScreenConditionRootType">
+        <xs:choice>
+            <xs:element ref="and" />
+            <xs:element ref="or" />
+            <xs:element ref="xor" />
+            <xs:element ref="not" />
+            <xs:element ref="if-service-permission" />
+            <xs:element ref="if-has-permission" />
+            <xs:element ref="if-entity-permission" />
+            <xs:element ref="if-validate-method" />
+            <xs:element ref="if-compare" />
+            <xs:element ref="if-compare-field" />
+            <xs:element ref="if-regexp" />
+            <xs:element ref="if-empty" />
+            <xs:element ref="if-empty-section" />
+        </xs:choice>
+    </xs:complexType>
+
     <xs:element name="if-empty-section" substitutionGroup="AllConditionals">
         <xs:complexType>
             <xs:attribute type="xs:string" name="section-name" use="required" />
@@ -285,11 +94,12 @@ under the License.
     </xs:element>
 
     <!-- ================ ACTIONS ================ -->
-    <xs:element name="AllActions" abstract="true"/>
+
+    <xs:element name="AllActions" abstract="true" />
     <xs:element name="actions">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllActions"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllActions" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
@@ -623,7 +433,7 @@ under the License.
                     <xs:documentation>
                         Ignore the condition if flag is true.
                         Defaults to false.
-                </xs:documentation>
+                    </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
         </xs:complexType>
@@ -681,18 +491,19 @@ under the License.
     </xs:element>
 
     <!-- ================ WIDGETS ================ -->
-    <xs:element name="AllWidgets" abstract="true"/>
+
+    <xs:element name="AllWidgets" abstract="true" />
     <xs:element name="widgets">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllWidgets"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllWidgets" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
     <xs:element name="fail-widgets">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllWidgets"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllWidgets" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
@@ -725,7 +536,8 @@ under the License.
             <xs:attribute type="xs:string" name="auto-update-target">
                 <xs:annotation>
                     <xs:documentation>The URL to be called for periodic asynchronous area updates.
-                        Some widget rendering environments support asynchronous updates.</xs:documentation>
+                        Some widget rendering environments support asynchronous updates.
+                    </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
             <xs:attribute type="xs:string" name="auto-update-interval">
@@ -772,8 +584,8 @@ under the License.
     <xs:element name="link" substitutionGroup="AllWidgets">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" ref="auto-parameters-service"/>
-                <xs:element minOccurs="0" ref="auto-parameters-entity"/>
+                <xs:element minOccurs="0" ref="auto-parameters-service" />
+                <xs:element minOccurs="0" ref="auto-parameters-entity" />
                 <xs:element minOccurs="0" maxOccurs="unbounded" ref="parameter" />
                 <xs:element minOccurs="0" ref="image" />
             </xs:sequence>
@@ -792,7 +604,7 @@ under the License.
                         <xs:enumeration value="auto">
                             <xs:annotation>
                                 <xs:documentation>
-                                    If selected the hidden-form type will be used if the url-mode is intra-app
+                                    If selected the hidden-form type will be used if the url-mode is intra-app
                                     and the request specified has an event, otherwise the anchor type will be used,
                                     except if the ajax-window mode is specified.
                                 </xs:documentation>
@@ -850,18 +662,18 @@ under the License.
     <xs:element name="auto-parameters-service">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="exclude"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="exclude" />
             </xs:sequence>
             <xs:attribute name="service-name" type="xs:string" use="required">
-                 <xs:annotation>
-                     <xs:documentation>The service name used to resolve parameters. If empty, use form defaultServiceName. Flexible string allowed.</xs:documentation>
-                 </xs:annotation>
+                <xs:annotation>
+                    <xs:documentation>The service name used to resolve parameters. If empty, use form defaultServiceName. Flexible string allowed.</xs:documentation>
+                </xs:annotation>
             </xs:attribute>
             <xs:attribute name="send-if-empty" default="true">
                 <xs:simpleType>
                     <xs:restriction base="xs:token">
-                        <xs:enumeration value="true"/>
-                        <xs:enumeration value="false"/>
+                        <xs:enumeration value="true" />
+                        <xs:enumeration value="false" />
                     </xs:restriction>
                 </xs:simpleType>
             </xs:attribute>
@@ -870,27 +682,27 @@ under the License.
     <xs:element name="auto-parameters-entity">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="exclude"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="exclude" />
             </xs:sequence>
             <xs:attribute name="entity-name" type="xs:string" use="required">
-                 <xs:annotation>
-                     <xs:documentation>The entity name used to resolve parameters. If empty use form defaultEntityName attribute. Flexible string allowed.</xs:documentation>
-                 </xs:annotation>
+                <xs:annotation>
+                    <xs:documentation>The entity name used to resolve parameters. If empty use form defaultEntityName attribute. Flexible string allowed.</xs:documentation>
+                </xs:annotation>
             </xs:attribute>
             <xs:attribute name="include" default="pk">
                 <xs:simpleType>
                     <xs:restriction base="xs:token">
-                        <xs:enumeration value="pk"/>
-                        <xs:enumeration value="nonpk"/>
-                        <xs:enumeration value="all"/>
+                        <xs:enumeration value="pk" />
+                        <xs:enumeration value="nonpk" />
+                        <xs:enumeration value="all" />
                     </xs:restriction>
                 </xs:simpleType>
             </xs:attribute>
             <xs:attribute name="send-if-empty" default="true">
                 <xs:simpleType>
                     <xs:restriction base="xs:token">
-                        <xs:enumeration value="true"/>
-                        <xs:enumeration value="false"/>
+                        <xs:enumeration value="true" />
+                        <xs:enumeration value="false" />
                     </xs:restriction>
                 </xs:simpleType>
             </xs:attribute>
@@ -898,7 +710,7 @@ under the License.
     </xs:element>
     <xs:element name="exclude">
         <xs:complexType>
-            <xs:attribute name="field-name" type="xs:string" use="required"/>
+            <xs:attribute name="field-name" type="xs:string" use="required" />
         </xs:complexType>
     </xs:element>
 
@@ -968,6 +780,7 @@ under the License.
     </xs:element>
 
     <!-- ================ WIDGETS - Includers ================ -->
+
     <xs:element name="content" substitutionGroup="AllWidgets">
         <xs:complexType>
             <xs:attribute type="xs:string" name="content-id" />
@@ -1148,57 +961,58 @@ under the License.
     <xs:element name="platform-specific" substitutionGroup="AllWidgets">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" ref="html"/>
-                <xs:element minOccurs="0" ref="swing"/>
-                <xs:element minOccurs="0" ref="xsl-fo"/>
-                <xs:element minOccurs="0" ref="xml"/>
+                <xs:element minOccurs="0" ref="html" />
+                <xs:element minOccurs="0" ref="swing" />
+                <xs:element minOccurs="0" ref="xsl-fo" />
+                <xs:element minOccurs="0" ref="xml" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
     <!-- ============== HTML Specific Elements =============== -->
-    <xs:element name="HtmlWidgets" abstract="true"/>
+    <xs:element name="HtmlWidgets" abstract="true" />
     <xs:element name="html">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
     <xs:element name="xsl-fo">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
     <xs:element name="xml">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
     <xs:element name="html-template" substitutionGroup="HtmlWidgets">
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.html-template"/>
+            <xs:attributeGroup ref="attlist.html-template" />
         </xs:complexType>
     </xs:element>
     <xs:attributeGroup name="attlist.html-template">
-        <xs:attribute type="xs:string" name="location" use="required"/>
+        <xs:attribute type="xs:string" name="location" use="required" />
     </xs:attributeGroup>
     <xs:element name="html-template-decorator" substitutionGroup="HtmlWidgets">
         <xs:annotation>
             <xs:documentation>
                 We don't really want to encourage the use of the html-template-decorator, should be done on the screen level.
                 To include the sections in the decorator template just use the "render(sectionName)" method "sections" object, FTL example: ${sections.render("main")}.
-                For more efficient use the sections.render(sectionName, writer) method should be used, in FTL this would be in a transform or something.
+                For more
+                efficient use the sections.render(sectionName, writer) method should be used, in FTL this would be in a transform or something.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
             <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="html-template-decorator-section"/>
+                <xs:element maxOccurs="unbounded" ref="html-template-decorator-section" />
             </xs:sequence>
-        <xs:attribute type="xs:string" name="location" use="required"/>
+            <xs:attribute type="xs:string" name="location" use="required" />
         </xs:complexType>
     </xs:element>
     <xs:element name="html-template-decorator-section">
@@ -1211,6 +1025,6 @@ under the License.
     </xs:element>
     <!-- ============== Swing Specific Elements =============== -->
     <xs:element name="swing">
-        <xs:complexType/>
+        <xs:complexType />
     </xs:element>
 </xs:schema>

Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetCondition.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetCondition.java?rev=1648152&view=auto
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetCondition.java (added)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/ModelWidgetCondition.java Sun Dec 28 07:37:03 2014
@@ -0,0 +1,650 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.ofbiz.widget;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.apache.oro.text.regex.MalformedPatternException;
+import org.apache.oro.text.regex.Pattern;
+import org.apache.oro.text.regex.PatternMatcher;
+import org.apache.oro.text.regex.Perl5Matcher;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.ObjectType;
+import org.ofbiz.base.util.PatternFactory;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entityext.permission.EntityPermissionChecker;
+import org.ofbiz.minilang.operation.BaseCompare;
+import org.ofbiz.security.Security;
+import org.ofbiz.service.DispatchContext;
+import org.ofbiz.service.GenericServiceException;
+import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.service.ModelService;
+import org.ofbiz.service.ServiceUtil;
+import org.w3c.dom.Element;
+
+/**
+ * Abstract base class for the condition models.
+ */
+@SuppressWarnings("serial")
+public abstract class ModelWidgetCondition implements Serializable {
+
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     DEVELOPERS PLEASE READ
+     * ----------------------------------------------------------------------- *
+     *
+     * This model is intended to be a read-only data structure that represents
+     * an XML element. Outside of object construction, the class should not
+     * have any behaviors.
+     *
+     * Instances of this class will be shared by multiple threads - therefore
+     * it is immutable. DO NOT CHANGE THE OBJECT'S STATE AT RUN TIME!
+     *
+     */
+
+    public static final String module = ModelWidgetCondition.class.getName();
+    public static final ConditionFactory DEFAULT_CONDITION_FACTORY = new DefaultConditionFactory();
+
+    private final ModelWidget modelWidget;
+    private final Condition rootCondition;
+
+    protected ModelWidgetCondition(ConditionFactory factory, ModelWidget modelWidget, Element conditionElement) {
+        this.modelWidget = modelWidget;
+        Element firstChildElement = UtilXml.firstChildElement(conditionElement);
+        this.rootCondition = factory.newInstance(modelWidget, firstChildElement);
+    }
+
+    public boolean eval(Map<String, Object> context) {
+        return rootCondition.eval(context);
+    }
+
+    public ModelWidget getModelWidget() {
+        return modelWidget;
+    }
+
+    public static List<Condition> readSubConditions(ConditionFactory factory, ModelWidget modelWidget, Element conditionElement) {
+        List<? extends Element> subElementList = UtilXml.childElementList(conditionElement);
+        List<Condition> condList = new ArrayList<Condition>(subElementList.size());
+        for (Element subElement : subElementList) {
+            condList.add(factory.newInstance(modelWidget, subElement));
+        }
+        return Collections.unmodifiableList(condList);
+    }
+
+    /**
+     * Models the &lt;and&gt; element.
+     *
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class And extends ModelWidgetCondition implements Condition {
+        private final List<Condition> subConditions;
+
+        private And(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+            super(factory, modelWidget, condElement);
+            this.subConditions = readSubConditions(factory, modelWidget, condElement);
+        }
+
+        @Override
+        public boolean eval(Map<String, Object> context) {
+            // return false for the first one in the list that is false, basic and algo
+            for (Condition subCondition : this.subConditions) {
+                if (!subCondition.eval(context)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    public static interface Condition {
+        boolean eval(Map<String, Object> context);
+    }
+
+    /**
+     * A factory for <code>Condition</code> instances.
+     *
+     */
+    public static interface ConditionFactory {
+        /**
+         * Returns a new <code>Condition</code> instance built from <code>conditionElement</code>.
+         *
+         * @param modelWidget The <code>ModelWidget</code> that contains the <code>Condition</code> instance.
+         * @param conditionElement The XML element used to build the <code>Condition</code> instance.
+         * @return A new <code>Condition</code> instance built from <code>conditionElement</code>.
+         * @throws IllegalArgumentException if no model was found for the XML element
+         */
+        Condition newInstance(ModelWidget modelWidget, Element conditionElement);
+    }
+
+    public static class DefaultConditionFactory implements ConditionFactory {
+        public static final Condition TRUE = new Condition() {
+            @Override
+            public boolean eval(Map<String, Object> context) {
+                return true;
+            }
+        };
+        public static final Condition FALSE = new Condition() {
+            @Override
+            public boolean eval(Map<String, Object> context) {
+                return false;
+            }
+        };
+
+        public Condition newInstance(ModelWidget modelWidget, Element conditionElement) {
+            if (conditionElement == null) {
+                return TRUE;
+            }
+            if ("and".equals(conditionElement.getNodeName())) {
+                return new And(this, modelWidget, conditionElement);
+            } else if ("xor".equals(conditionElement.getNodeName())) {
+                return new Xor(this, modelWidget, conditionElement);
+            } else if ("or".equals(conditionElement.getNodeName())) {
+                return new Or(this, modelWidget, conditionElement);
+            } else if ("not".equals(conditionElement.getNodeName())) {
+                return new Not(this, modelWidget, conditionElement);
+            } else if ("if-service-permission".equals(conditionElement.getNodeName())) {
+                return new IfServicePermission(this, modelWidget, conditionElement);
+            } else if ("if-has-permission".equals(conditionElement.getNodeName())) {
+                return new IfHasPermission(this, modelWidget, conditionElement);
+            } else if ("if-validate-method".equals(conditionElement.getNodeName())) {
+                return new IfValidateMethod(this, modelWidget, conditionElement);
+            } else if ("if-compare".equals(conditionElement.getNodeName())) {
+                return new IfCompare(this, modelWidget, conditionElement);
+            } else if ("if-compare-field".equals(conditionElement.getNodeName())) {
+                return new IfCompareField(this, modelWidget, conditionElement);
+            } else if ("if-regexp".equals(conditionElement.getNodeName())) {
+                return new IfRegexp(this, modelWidget, conditionElement);
+            } else if ("if-empty".equals(conditionElement.getNodeName())) {
+                return new IfEmpty(this, modelWidget, conditionElement);
+            } else if ("if-entity-permission".equals(conditionElement.getNodeName())) {
+                return new IfEntityPermission(this, modelWidget, conditionElement);
+            } else {
+                throw new IllegalArgumentException("Condition element not supported with name: " + conditionElement.getNodeName());
+            }
+        }
+    }
+
+    /**
+     * Models the &lt;if-compare&gt; element.
+     *
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class IfCompare extends ModelWidgetCondition implements Condition {
+        private final FlexibleMapAccessor<Object> fieldAcsr;
+        private final FlexibleStringExpander formatExdr;
+        private final String operator;
+        private final String type;
+        private final FlexibleStringExpander valueExdr;
+
+        private IfCompare(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+            super(factory, modelWidget, condElement);
+            String fieldAcsr = condElement.getAttribute("field");
+            if (fieldAcsr.isEmpty())
+                fieldAcsr = condElement.getAttribute("field-name");
+            this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr);
+            this.valueExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("value"));
+            this.operator = condElement.getAttribute("operator");
+            this.type = condElement.getAttribute("type");
+            this.formatExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("format"));
+        }
+
+        @Override
+        public boolean eval(Map<String, Object> context) {
+            String value = this.valueExdr.expandString(context);
+            String format = this.formatExdr.expandString(context);
+            Object fieldVal = this.fieldAcsr.get(context);
+            // always use an empty string by default
+            if (fieldVal == null) {
+                fieldVal = "";
+            }
+            List<Object> messages = new LinkedList<Object>();
+            Boolean resultBool = BaseCompare.doRealCompare(fieldVal, value, operator, type, format, messages, null, null, true);
+            if (messages.size() > 0) {
+                messages.add(0, "Error with comparison in if-compare between field [" + fieldAcsr.toString() + "] with value ["
+                        + fieldVal + "] and value [" + value + "] with operator [" + operator + "] and type [" + type + "]: ");
+
+                StringBuilder fullString = new StringBuilder();
+                for (Object item : messages) {
+                    fullString.append(item.toString());
+                }
+                Debug.logWarning(fullString.toString(), module);
+                throw new IllegalArgumentException(fullString.toString());
+            }
+            return resultBool.booleanValue();
+        }
+    }
+
+    /**
+     * Models the &lt;if-compare-field&gt; element.
+     *
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class IfCompareField extends ModelWidgetCondition implements Condition {
+        private final FlexibleMapAccessor<Object> fieldAcsr;
+        private final FlexibleStringExpander formatExdr;
+        private final String operator;
+        private final FlexibleMapAccessor<Object> toFieldAcsr;
+        private final String type;
+
+        private IfCompareField(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+            super(factory, modelWidget, condElement);
+            String fieldAcsr = condElement.getAttribute("field");
+            if (fieldAcsr.isEmpty())
+                fieldAcsr = condElement.getAttribute("field-name");
+            this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr);
+            String toFieldAcsr = condElement.getAttribute("to-field");
+            if (toFieldAcsr.isEmpty())
+                toFieldAcsr = condElement.getAttribute("to-field-name");
+            this.toFieldAcsr = FlexibleMapAccessor.getInstance(toFieldAcsr);
+            this.operator = condElement.getAttribute("operator");
+            this.type = condElement.getAttribute("type");
+            this.formatExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("format"));
+        }
+
+        @Override
+        public boolean eval(Map<String, Object> context) {
+            String format = this.formatExdr.expandString(context);
+            Object fieldVal = this.fieldAcsr.get(context);
+            Object toFieldVal = this.toFieldAcsr.get(context);
+            // always use an empty string by default
+            if (fieldVal == null) {
+                fieldVal = "";
+            }
+            List<Object> messages = new LinkedList<Object>();
+            Boolean resultBool = BaseCompare.doRealCompare(fieldVal, toFieldVal, operator, type, format, messages, null, null,
+                    false);
+            if (messages.size() > 0) {
+                messages.add(0, "Error with comparison in if-compare-field between field [" + fieldAcsr.toString()
+                        + "] with value [" + fieldVal + "] and to-field [" + toFieldAcsr.toString() + "] with value ["
+                        + toFieldVal + "] with operator [" + operator + "] and type [" + type + "]: ");
+
+                StringBuilder fullString = new StringBuilder();
+                for (Object item : messages) {
+                    fullString.append(item.toString());
+                }
+                Debug.logWarning(fullString.toString(), module);
+                throw new IllegalArgumentException(fullString.toString());
+            }
+            return resultBool.booleanValue();
+        }
+    }
+
+    /**
+     * Models the &lt;if-empty&gt; element.
+     *
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class IfEmpty extends ModelWidgetCondition implements Condition {
+        private final FlexibleMapAccessor<Object> fieldAcsr;
+
+        private IfEmpty(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+            super(factory, modelWidget, condElement);
+            String fieldAcsr = condElement.getAttribute("field");
+            if (fieldAcsr.isEmpty())
+                fieldAcsr = condElement.getAttribute("field-name");
+            this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr);
+        }
+
+        @Override
+        public boolean eval(Map<String, Object> context) {
+            Object fieldVal = this.fieldAcsr.get(context);
+            return ObjectType.isEmpty(fieldVal);
+        }
+    }
+
+    /**
+     * Models the &lt;if-entity-permission&gt; element.
+     *
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class IfEntityPermission extends ModelWidgetCondition implements Condition {
+        private final EntityPermissionChecker permissionChecker;
+
+        private IfEntityPermission(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+            super(factory, modelWidget, condElement);
+            this.permissionChecker = new EntityPermissionChecker(condElement);
+        }
+
+        @Override
+        public boolean eval(Map<String, Object> context) {
+            return permissionChecker.runPermissionCheck(context);
+        }
+    }
+
+    /**
+     * Models the &lt;if-has-permission&gt; element.
+     *
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class IfHasPermission extends ModelWidgetCondition implements Condition {
+        private final FlexibleStringExpander actionExdr;
+        private final FlexibleStringExpander permissionExdr;
+
+        private IfHasPermission(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+            super(factory, modelWidget, condElement);
+            this.permissionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("permission"));
+            this.actionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("action"));
+        }
+
+        @Override
+        public boolean eval(Map<String, Object> context) {
+            // if no user is logged in, treat as if the user does not have permission
+            GenericValue userLogin = (GenericValue) context.get("userLogin");
+            if (userLogin != null) {
+                String permission = permissionExdr.expandString(context);
+                String action = actionExdr.expandString(context);
+                Security security = (Security) context.get("security");
+                if (UtilValidate.isNotEmpty(action)) {
+                    // run hasEntityPermission
+                    if (security.hasEntityPermission(permission, action, userLogin)) {
+                        return true;
+                    }
+                } else {
+                    // run hasPermission
+                    if (security.hasPermission(permission, userLogin)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Models the &lt;if-regexp&gt; element.
+     *
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class IfRegexp extends ModelWidgetCondition implements Condition {
+        private final FlexibleStringExpander exprExdr;
+        private final FlexibleMapAccessor<Object> fieldAcsr;
+
+        private IfRegexp(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+            super(factory, modelWidget, condElement);
+            String fieldAcsr = condElement.getAttribute("field");
+            if (fieldAcsr.isEmpty())
+                fieldAcsr = condElement.getAttribute("field-name");
+            this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr);
+            this.exprExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("expr"));
+        }
+
+        @Override
+        public boolean eval(Map<String, Object> context) {
+            Object fieldVal = this.fieldAcsr.get(context);
+            String expr = this.exprExdr.expandString(context);
+            Pattern pattern;
+            try {
+                pattern = PatternFactory.createOrGetPerl5CompiledPattern(expr, true);
+            } catch (MalformedPatternException e) {
+                String errMsg = "Error in evaluation in if-regexp in screen: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new IllegalArgumentException(errMsg);
+            }
+            String fieldString = null;
+            try {
+                fieldString = (String) ObjectType.simpleTypeConvert(fieldVal, "String", null, (TimeZone) context.get("timeZone"),
+                        (Locale) context.get("locale"), true);
+            } catch (GeneralException e) {
+                Debug.logError(e, "Could not convert object to String, using empty String", module);
+            }
+            // always use an empty string by default
+            if (fieldString == null)
+                fieldString = "";
+            PatternMatcher matcher = new Perl5Matcher();
+            return matcher.matches(fieldString, pattern);
+        }
+    }
+
+    /**
+     * Models the &lt;if-service-permission&gt; element.
+     *
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class IfServicePermission extends ModelWidgetCondition implements Condition {
+        private final FlexibleStringExpander actionExdr;
+        private final FlexibleStringExpander ctxMapExdr;
+        private final FlexibleStringExpander resExdr;
+        private final FlexibleStringExpander serviceExdr;
+
+        private IfServicePermission(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+            super(factory, modelWidget, condElement);
+            this.serviceExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("service-name"));
+            this.actionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("main-action"));
+            this.ctxMapExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("context-map"));
+            this.resExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("resource-description"));
+        }
+
+        @Override
+        public boolean eval(Map<String, Object> context) {
+            // if no user is logged in, treat as if the user does not have permission
+            GenericValue userLogin = (GenericValue) context.get("userLogin");
+            if (userLogin != null) {
+                String serviceName = serviceExdr.expandString(context);
+                String mainAction = actionExdr.expandString(context);
+                String contextMap = ctxMapExdr.expandString(context);
+                String resource = resExdr.expandString(context);
+                if (UtilValidate.isEmpty(resource)) {
+                    resource = serviceName;
+                }
+                if (UtilValidate.isEmpty(serviceName)) {
+                    Debug.logWarning("No permission service-name specified!", module);
+                    return false;
+                }
+                Map<String, Object> serviceContext = UtilGenerics.toMap(context.get(contextMap));
+                if (serviceContext != null) {
+                    // copy the required internal fields
+                    serviceContext.put("userLogin", context.get("userLogin"));
+                    serviceContext.put("locale", context.get("locale"));
+                } else {
+                    serviceContext = context;
+                }
+                // get the service engine objects
+                LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
+                DispatchContext dctx = dispatcher.getDispatchContext();
+                // get the service
+                ModelService permService;
+                try {
+                    permService = dctx.getModelService(serviceName);
+                } catch (GenericServiceException e) {
+                    Debug.logError(e, module);
+                    return false;
+                }
+                if (permService != null) {
+                    // build the context
+                    Map<String, Object> svcCtx = permService.makeValid(serviceContext, ModelService.IN_PARAM);
+                    svcCtx.put("resourceDescription", resource);
+                    if (UtilValidate.isNotEmpty(mainAction)) {
+                        svcCtx.put("mainAction", mainAction);
+                    }
+                    // invoke the service
+                    Map<String, Object> resp;
+                    try {
+                        resp = dispatcher.runSync(permService.name, svcCtx, 300, true);
+                    } catch (GenericServiceException e) {
+                        Debug.logError(e, module);
+                        return false;
+                    }
+                    if (ServiceUtil.isError(resp) || ServiceUtil.isFailure(resp)) {
+                        Debug.logError(ServiceUtil.getErrorMessage(resp), module);
+                        return false;
+                    }
+                    Boolean hasPermission = (Boolean) resp.get("hasPermission");
+                    if (hasPermission != null) {
+                        return hasPermission.booleanValue();
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Models the &lt;if-validate-method&gt; element.
+     *
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class IfValidateMethod extends ModelWidgetCondition implements Condition {
+        private final FlexibleStringExpander classExdr;
+        private final FlexibleMapAccessor<Object> fieldAcsr;
+        private final FlexibleStringExpander methodExdr;
+
+        private IfValidateMethod(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+            super(factory, modelWidget, condElement);
+            String fieldAcsr = condElement.getAttribute("field");
+            if (fieldAcsr.isEmpty())
+                fieldAcsr = condElement.getAttribute("field-name");
+            this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr);
+            this.methodExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("method"));
+            this.classExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("class"));
+        }
+
+        @Override
+        public boolean eval(Map<String, Object> context) {
+            String methodName = this.methodExdr.expandString(context);
+            String className = this.classExdr.expandString(context);
+            Object fieldVal = this.fieldAcsr.get(context);
+            String fieldString = null;
+            if (fieldVal != null) {
+                try {
+                    fieldString = (String) ObjectType.simpleTypeConvert(fieldVal, "String", null,
+                            (TimeZone) context.get("timeZone"), (Locale) context.get("locale"), true);
+                } catch (GeneralException e) {
+                    Debug.logError(e, "Could not convert object to String, using empty String", module);
+                }
+            }
+            // always use an empty string by default
+            if (fieldString == null)
+                fieldString = "";
+            Class<?>[] paramTypes = new Class[] { String.class };
+            Object[] params = new Object[] { fieldString };
+            Class<?> valClass;
+            try {
+                valClass = ObjectType.loadClass(className);
+            } catch (ClassNotFoundException cnfe) {
+                Debug.logError("Could not find validation class: " + className, module);
+                return false;
+            }
+            Method valMethod;
+            try {
+                valMethod = valClass.getMethod(methodName, paramTypes);
+            } catch (NoSuchMethodException cnfe) {
+                Debug.logError("Could not find validation method: " + methodName + " of class " + className, module);
+                return false;
+            }
+            Boolean resultBool = Boolean.FALSE;
+            try {
+                resultBool = (Boolean) valMethod.invoke(null, params);
+            } catch (Exception e) {
+                Debug.logError(e, "Error in IfValidationMethod " + methodName + " of class " + className
+                        + ", defaulting to false ", module);
+            }
+            return resultBool.booleanValue();
+        }
+    }
+
+    /**
+     * Models the &lt;not&gt; element.
+     *
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class Not extends ModelWidgetCondition implements Condition {
+        private final Condition subCondition;
+
+        private Not(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+            super(factory, modelWidget, condElement);
+            Element firstChildElement = UtilXml.firstChildElement(condElement);
+            this.subCondition = factory.newInstance(modelWidget, firstChildElement);
+        }
+
+        @Override
+        public boolean eval(Map<String, Object> context) {
+            return !this.subCondition.eval(context);
+        }
+    }
+
+    /**
+     * Models the &lt;or&gt; element.
+     *
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class Or extends ModelWidgetCondition implements Condition {
+        private final List<Condition> subConditions;
+
+        private Or(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+            super(factory, modelWidget, condElement);
+            this.subConditions = readSubConditions(factory, modelWidget, condElement);
+        }
+
+        @Override
+        public boolean eval(Map<String, Object> context) {
+            // return true for the first one in the list that is true, basic or algo
+            for (Condition subCondition : this.subConditions) {
+                if (subCondition.eval(context)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Models the &lt;xor&gt; element.
+     *
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class Xor extends ModelWidgetCondition implements Condition {
+        private final List<Condition> subConditions;
+
+        private Xor(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+            super(factory, modelWidget, condElement);
+            this.subConditions = readSubConditions(factory, modelWidget, condElement);
+        }
+
+        @Override
+        public boolean eval(Map<String, Object> context) {
+            // if more than one is true stop immediately and return false; if all are false return false; if only one is true return true
+            boolean foundOneTrue = false;
+            for (Condition subCondition : this.subConditions) {
+                if (subCondition.eval(context)) {
+                    if (foundOneTrue) {
+                        // now found two true, so return false
+                        return false;
+                    } else {
+                        foundOneTrue = true;
+                    }
+                }
+            }
+            return foundOneTrue;
+        }
+    }
+}