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 <and> 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 <if-compare> 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 <if-compare-field> 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 <if-empty> 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 <if-entity-permission> 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 <if-has-permission> 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 <if-regexp> 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 <if-service-permission> 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 <if-validate-method> 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 <not> 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 <or> 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 <xor> 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;
+ }
+ }
+}