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; + } + } +} |
Free forum by Nabble | Edit this page |