This is an automated email from the ASF dual-hosted git repository.
grv pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git The following commit(s) were added to refs/heads/trunk by this push: new fdb67ae WIP: Implemented: Added support for defining nested attributes.(OFBIZ-11902) (#231) fdb67ae is described below commit fdb67aee728a86d4d196ff915fb433029e6d6e22 Author: girishvasmatkar <[hidden email]> AuthorDate: Sat Aug 22 23:50:12 2020 +0530 WIP: Implemented: Added support for defining nested attributes.(OFBIZ-11902) (#231) * Added nested attr definition and code to handle nested attributes * Checkstyle error fix * Fixed indentation and tabs issues --- framework/service/dtd/services.xsd | 35 +++++---- .../java/org/apache/ofbiz/service/ModelParam.java | 13 ++++ .../apache/ofbiz/service/ModelServiceReader.java | 88 ++++++++++++---------- 3 files changed, 82 insertions(+), 54 deletions(-) diff --git a/framework/service/dtd/services.xsd b/framework/service/dtd/services.xsd index fe0339b..2bb58b9 100644 --- a/framework/service/dtd/services.xsd +++ b/framework/service/dtd/services.xsd @@ -69,8 +69,8 @@ under the License. <xs:attribute name="action"> <xs:annotation> <xs:documentation> - Specifies the HTTP method name this service can be called using REST interface. For now only POST and GET are supported. - Services that have export=true and have action attribute defined can be called using REST interface. + Specifies the HTTP method name this service can be called using REST interface. For now only POST and GET are supported. + Services that have export=true and have action attribute defined can be called using REST interface. </xs:documentation> </xs:annotation> <xs:simpleType> @@ -99,7 +99,7 @@ under the License. </xs:documentation> </xs:annotation> </xs:attribute> - <xs:attribute name="hideResultInLog" type="xs:boolean" + <xs:attribute name="hideResultInLog" type="xs:boolean" default="false"> <xs:annotation> <xs:documentation> @@ -187,7 +187,7 @@ under the License. default="true"> <xs:annotation> <xs:documentation> - If set to false, when the permissions failed return the failMessage as error, + If set to false, when the permissions failed return the failMessage as error, else continue the service and give the hand to origin service to resolve the problem. </xs:documentation> </xs:annotation> @@ -237,7 +237,7 @@ under the License. </xs:element> <xs:attributeGroup name="attlist.implements"> <xs:attribute name="service" type="xs:string" use="required"/> - <xs:attribute name="optional" type="xs:boolean" + <xs:attribute name="optional" type="xs:boolean" default="false"> <xs:annotation> <xs:documentation> @@ -251,7 +251,7 @@ under the License. <xs:documentation> Calculate and maintain an average response time for this service. Service metrics can be used for monitoring and reporting. - + The metric works by gathering statistics until a configurable maximum is reached (number of requests or elapsed time), then the average is calculated. A smoothing factor is used to smooth differences between calculations. @@ -261,28 +261,28 @@ under the License. <xs:attribute name="name" type="xs:string" use="required"> <xs:annotation> <xs:documentation> - Each metric must have a unique name. + Each metric must have a unique name. </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute name="estimation-size" type="xs:string"> <xs:annotation> <xs:documentation> - Positive integer number of requests to include in the metrics calculation. Defaults to "100". + Positive integer number of requests to include in the metrics calculation. Defaults to "100". </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute name="estimation-time" type="xs:string"> <xs:annotation> <xs:documentation> - Positive integer number of milliseconds to include in the metrics calculation. Defaults to "1000". + Positive integer number of milliseconds to include in the metrics calculation. Defaults to "1000". </xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute name="smoothing" type="xs:string"> <xs:annotation> <xs:documentation> - Positive decimal smoothing factor - used to smooth the differences between calculations. A value of "1" disables smoothing. Defaults to "0.7". + Positive decimal smoothing factor - used to smooth the differences between calculations. A value of "1" disables smoothing. Defaults to "0.7". </xs:documentation> </xs:annotation> </xs:attribute> @@ -346,6 +346,11 @@ under the License. <xs:sequence> <xs:element minOccurs="0" maxOccurs="unbounded" ref="type-validate"/> <xs:element minOccurs="0" ref="description" /> + <xs:element minOccurs="0" maxOccurs="unbounded" ref="attribute"> + <xs:annotation> + <xs:documentation>List, Map type attributes can have nested attributes.</xs:documentation> + </xs:annotation> + </xs:element> </xs:sequence> <xs:attributeGroup ref="attlist.attribute"/> </xs:complexType> @@ -365,9 +370,9 @@ under the License. <xs:attribute name="optional" type="xs:boolean" default="false"/> <xs:attribute name="default-value" type="xs:string"> <xs:annotation> - <xs:documentation>The value specified will be used for the attribute if no value is passed in. - This will only happen if it is okay to not pass a value in, so if this is set then optional will be set to true. - If optional=false and this is set then the value will be overridden and with a value in default-value is will set + <xs:documentation>The value specified will be used for the attribute if no value is passed in. + This will only happen if it is okay to not pass a value in, so if this is set then optional will be set to true. + If optional=false and this is set then the value will be overridden and with a value in default-value is will set optional=true anyway. </xs:documentation> </xs:annotation> @@ -386,7 +391,7 @@ under the License. Applies only to String fields. Only checked for incoming parameters/attributes (could change in the future, but this is meant for validating input from users, other systems, etc). Defaults to "none" meaning no HTML is allowed (will result in an error message). - If some HTML is desired then use "safe" which will follow the rules in the default custom safe policy file (CustomSafePolicy.java, see also owasp.properties). + If some HTML is desired then use "safe" which will follow the rules in the default custom safe policy file (CustomSafePolicy.java, see also owasp.properties). This should be safe for both internal and public users. You may want to provide your own custom safe policy file to adapt to you needs. In rare cases when users are trusted or it is not a sensitive field the "any" option may be used to not check the HTML content at all. </xs:documentation> @@ -450,7 +455,7 @@ under the License. <xs:attribute name="allow-html" use="optional"> <xs:annotation> <xs:documentation> - See the documentation on the allow-html attribute of the "attribute" element. + See the documentation on the allow-html attribute of the "attribute" element. Note that it is slightly different here as there is no default. </xs:documentation> </xs:annotation> diff --git a/framework/service/src/main/java/org/apache/ofbiz/service/ModelParam.java b/framework/service/src/main/java/org/apache/ofbiz/service/ModelParam.java index 3db0198..d84a181 100644 --- a/framework/service/src/main/java/org/apache/ofbiz/service/ModelParam.java +++ b/framework/service/src/main/java/org/apache/ofbiz/service/ModelParam.java @@ -19,6 +19,7 @@ package org.apache.ofbiz.service; import java.io.Serializable; +import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; @@ -94,6 +95,8 @@ public class ModelParam implements Serializable { /** Is this Parameter set internally? */ private boolean internal = false; + /** Children attributes*/ + private ArrayList<ModelParam> children = null; public ModelParam() { } @@ -514,6 +517,16 @@ public class ModelParam implements Serializable { } /** + * @return the children of the attribute + */ + public ArrayList<ModelParam> getChildren() { + if (children == null) { + children = new ArrayList<>(); + } + return children; + } + + /** * Copy default value. * @param param the param */ diff --git a/framework/service/src/main/java/org/apache/ofbiz/service/ModelServiceReader.java b/framework/service/src/main/java/org/apache/ofbiz/service/ModelServiceReader.java index f08214e..98bd955 100644 --- a/framework/service/src/main/java/org/apache/ofbiz/service/ModelServiceReader.java +++ b/framework/service/src/main/java/org/apache/ofbiz/service/ModelServiceReader.java @@ -467,45 +467,7 @@ public class ModelServiceReader implements Serializable { private static void createAttrDefs(Element baseElement, ModelService service) { // Add in the defined attributes (override the above defaults if specified) for (Element attribute: UtilXml.childElementList(baseElement, "attribute")) { - ModelParam param = new ModelParam(); - - param.setName(UtilXml.checkEmpty(attribute.getAttribute("name")).intern()); - param.setDescription(getCDATADef(attribute, "description")); - param.setType(UtilXml.checkEmpty(attribute.getAttribute("type")).intern()); - param.setMode(UtilXml.checkEmpty(attribute.getAttribute("mode")).intern()); - param.setEntityName(UtilXml.checkEmpty(attribute.getAttribute("entity-name")).intern()); - param.setFieldName(UtilXml.checkEmpty(attribute.getAttribute("field-name")).intern()); - param.setRequestAttributeName(UtilXml.checkEmpty(attribute.getAttribute("request-attribute-name")).intern()); - param.setSessionAttributeName(UtilXml.checkEmpty(attribute.getAttribute("session-attribute-name")).intern()); - param.setStringMapPrefix(UtilXml.checkEmpty(attribute.getAttribute("string-map-prefix")).intern()); - param.setStringListSuffix(UtilXml.checkEmpty(attribute.getAttribute("string-list-suffix")).intern()); - param.setFormLabel(attribute.hasAttribute("form-label") ? attribute.getAttribute("form-label").intern() : null); - param.setOptional("true".equalsIgnoreCase(attribute.getAttribute("optional"))); // default to true - param.setFormDisplay(!"false".equalsIgnoreCase(attribute.getAttribute("form-display"))); // default to false - param.setAllowHtml(UtilXml.checkEmpty(attribute.getAttribute("allow-html"), "none").intern()); // default to none - - // default value - String defValue = attribute.getAttribute("default-value"); - if (UtilValidate.isNotEmpty(defValue)) { - if (Debug.verboseOn()) { - Debug.logVerbose("Got a default-value [" + defValue + "] for service attribute [" + service.getName() + "." - + param.getName() + "]", MODULE); - } - param.setDefaultValue(defValue.intern()); - } - - // set the entity name to the default if not specified - if (param.getEntityName().length() == 0) { - param.setEntityName(service.getDefaultEntityName()); - } - - // set the field-name to the name if entity name is specified but no field-name - if (param.getFieldName().length() == 0 && param.getEntityName().length() > 0) { - param.setFieldName(param.getName()); - } - - // set the validators - addValidators(attribute, param); + ModelParam param = createAttrDef(attribute, null, service); service.addParam(param); } @@ -602,6 +564,54 @@ public class ModelServiceReader implements Serializable { service.addParam(def); } + private static ModelParam createAttrDef(Element attribute, ModelParam parentParam, ModelService service) { + boolean hasParent = parentParam != null; + ModelParam param = new ModelParam(); + + param.setName(UtilXml.checkEmpty(attribute.getAttribute("name")).intern()); + param.setDescription(getCDATADef(attribute, "description")); + param.setType(UtilXml.checkEmpty(attribute.getAttribute("type")).intern()); + param.setMode(hasParent ? parentParam.getMode() : UtilXml.checkEmpty(attribute.getAttribute("mode")).intern()); //inherit mode from parent + param.setEntityName(UtilXml.checkEmpty(attribute.getAttribute("entity-name")).intern()); + param.setFieldName(UtilXml.checkEmpty(attribute.getAttribute("field-name")).intern()); + param.setRequestAttributeName(UtilXml.checkEmpty(attribute.getAttribute("request-attribute-name")).intern()); + param.setSessionAttributeName(UtilXml.checkEmpty(attribute.getAttribute("session-attribute-name")).intern()); + param.setStringMapPrefix(UtilXml.checkEmpty(attribute.getAttribute("string-map-prefix")).intern()); + param.setStringListSuffix(UtilXml.checkEmpty(attribute.getAttribute("string-list-suffix")).intern()); + param.setFormLabel(attribute.hasAttribute("form-label") ? attribute.getAttribute("form-label").intern() : null); + param.setOptional("true".equalsIgnoreCase(attribute.getAttribute("optional"))); // default to true + param.setFormDisplay(!"false".equalsIgnoreCase(attribute.getAttribute("form-display"))); // default to false + param.setAllowHtml(UtilXml.checkEmpty(attribute.getAttribute("allow-html"), "none").intern()); // default to none + + // default value + String defValue = attribute.getAttribute("default-value"); + if (UtilValidate.isNotEmpty(defValue)) { + if (Debug.verboseOn()) { + Debug.logVerbose("Got a default-value [" + defValue + "] for service attribute [" + service.getName() + "." + + param.getName() + "]", MODULE); + } + param.setDefaultValue(defValue.intern()); + } + + // set the entity name to the default if not specified + if (param.getEntityName().length() == 0) { + param.setEntityName(service.getDefaultEntityName()); + } + + // set the field-name to the name if entity name is specified but no field-name + if (param.getFieldName().length() == 0 && param.getEntityName().length() > 0) { + param.setFieldName(param.getName()); + } + + // set the validators + addValidators(attribute, param); + for (Element child: UtilXml.childElementList(attribute, "attribute")) { + ModelParam childParam = createAttrDef(child, param, service); + param.getChildren().add(childParam); + } + return param; + } + private static void createOverrideDefs(Element baseElement, ModelService service) { for (Element overrideElement: UtilXml.childElementList(baseElement, "override")) { String name = UtilXml.checkEmpty(overrideElement.getAttribute("name")); |
Free forum by Nabble | Edit this page |