Hibernate constraint-mapping validator with message - java

Here is the validation.xml
<constraint-mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.1.xsd"
xmlns="http://jboss.org/xml/ns/javax/validation/mapping" version="1.1">
<default-package>com.esq.rbac.model</default-package>
<bean class="Tenant" ignore-annotations="true">
...
<field name="ivrPin">
<constraint annotation="javax.validation.constraints.Size">
<element name="min">6</element>
<element name="max">6</element>
<message>IVR Pin must be 6 digit numeric</message>
</constraint>
<constraint annotation="javax.validation.constraints.Pattern">
<element name="regexp">[0-9]+</element>
</constraint>
</field>
</bean>
During execution getting error saying
c.e.u.imports.Main [run] - HV000115: Error parsing mapping file.
javax.validation.ValidationException: HV000115: Error parsing mapping file.
Caused by: org.xml.sax.SAXParseException: cvc-complex-type.2.4.a:
Invalid content was found starting with element 'message'. One of '{"http://jboss.org/xml/ns/javax/validation/mapping":element}' is expected.
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
How to include the error message properly

You just need to make one change by placing your message directly after constraint annotation tag, before the element tags.
<bean class="Tenant" ignore-annotations="true">
...
<field name="ivrPin">
<constraint annotation="javax.validation.constraints.Size">
<message>IVR Pin must be 6 digit numeric</message>
<element name="min">6</element>
<element name="max">6</element>
</constraint>
The reason for this is as follows:
If you look at the xsd file for validation-mapping:
validation-mapping-1.1.xsd
<xs:complexType name="constraintType">
<xs:sequence>
<xs:element type="xs:string" name="message" minOccurs="0"/>
<xs:element type="map:groupsType"
name="groups"
minOccurs="0"/>
<xs:element type="map:payloadType"
name="payload"
minOccurs="0"/>
<xs:element type="map:elementType"
name="element"
maxOccurs="unbounded"
minOccurs="0"/>
</xs:sequence>
<xs:attribute type="xs:string" name="annotation" use="required"/>
</xs:complexType>
It is using xs:sequence tag which specifies that the child elements must appear in a sequence. Refer element sequence. Here message attribute comes before other attributes like groups, payload or element.

Related

Handle both null and empty string values with JAXB

I am working with JAXB generated classes from schema and got stuck with following problem. I am trying to handle both null and empty string values with single element.
What I want to achieve is to be able to marshal both null and empty string values and receive the same while unmarshaling.
Element("key1", "value1") -> <element key="key1">value1</element>
Element("key2", "") -> <element key="key2"/>
Element("key3", null) -> <element key="key3" xsi:nil="true"/>
Schema xsd:
<xs:element name="element" nillable="true">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="key" type="xs:string" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
So far I get the following results, if value is null or "" I get the same xml:
Element("key1", null) -> <element key="key1"/> -> Element("key1", "")
Element("key2", "") -> <element key="key2"/> -> Element("key2", "")
Any idea if it is even possible with this xml structure? The only idea I have is to change structure to something like this, but it will generate more useless classes to deal with.
<element>
<key>key1</key>
<value>value1</value>
</element>
Edit
With given schema change it works as expected. The question if it is possible with original structure is still open.
<xs:element name="element">
<xs:complexType>
<xs:sequence>
<xs:element name="key" type="xs:string"/>
<xs:element name="value" type="xs:string" nillable="true"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<element>
<key>key1</key>
<value xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
</element>
<element>
<key>key2</key>
<value/>
</element>

XSD "property already defined"

I'm trying to use jaxb to compile some Veracode provided .xsd files
the "detailedreport.xsd" is throwing this error:
[ERROR] Property "Vulnerabilities" is already defined. Use <jaxb:property> to resolve this conflict.
line 930 of file:detailedreport.xsd
[ERROR] The following location is relevant to the above error
line 936 of detailedreport.xsd
when I look at the XSD file, I see that Vulnerabilities is both an attr and a type:
<xs:complexType name="Component">
<xs:annotation>
<xs:documentation>
The element describe the details of vulnerable component.
* file_paths: File paths of the component.
-----> * vulnerabilities : Vulnerabilities of the component.
* violated_policy_rules: Violated policy rules of the component.
* component_id: The id of the component.
* file_name: File name of the component.
-----> * vulnerabilities: Number of vulnerabilities available in the component.
* max_cvss_score: Max cvss_score of the component.
* library: Library name of the component.
* version: Version of the component.
* vendor: Vendor name of the component.
* description: Description about component.
* blacklisted: Component's blacklisted status.
* new: Component added newly.
* added_date: Component's added_date.
* component_affects_policy_compliance: COmponent's policy violation status.
* licenses: Contains license details of the component.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="file_paths" minOccurs="0" maxOccurs="1" type="tns:FilePathList"/>
<xs:element name="licenses" minOccurs="0" maxOccurs="1" type="tns:LicenseList"/>
-----> <xs:element name="vulnerabilities" minOccurs="0" maxOccurs="1" type="tns:VulnerabilityList" />
<xs:element name="violated_policy_rules" minOccurs="0" maxOccurs="1" type="tns:ViolatedRuleList" />
</xs:sequence>
<xs:attribute name="component_id" type="xs:string" use="required"/>
<xs:attribute name="file_name" type="xs:string" use="required"/>
<xs:attribute name="sha1" type="xs:string" use="required"/>
-----> <xs:attribute name="vulnerabilities" type="xs:integer" use="required"/>
<xs:attribute name="max_cvss_score" type="xs:string" use="required"/>
<xs:attribute name="library" type="xs:string" use="required"/>
<xs:attribute name="version" type="xs:string" use="required"/>
<xs:attribute name="vendor" type="xs:string" use="required"/>
<xs:attribute name="description" type="xs:string" use="required"/>
<xs:attribute name="blacklisted" type="xs:string"/>
<xs:attribute name="new" type="xs:string"/>
<xs:attribute name="added_date" type="xs:string"/>
<xs:attribute name="component_affects_policy_compliance" type="xs:string"/>
</xs:complexType>
here's the xsd they publish: https://analysiscenter.veracode.com/resource/detailedreport.xsd
from what I can figure out, I need to create a detailedreport.xjb file and (as the output states) setup a <jaxb:property> to convert the vulnerabilities integer attribute into something like vulnerabilityCount.
I created detailedreport.xjb:
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
<!-- Used to avoid the duplicate element/attribute name conflict -->
<jaxb:bindings node="//xsd:attribute[#name='vulnerabilities']">
<jaxb:property name="vulnerabilityCount"/>
</jaxb:bindings>
</jaxb:bindings>
but my xpath is wrong:
[ERROR] XPath evaluation of "//xsd:attribute[#name='vulnerabilities']" results in empty target node
line 10 of file: detailedreport.xjb
am I even on the right path
any xpath help is appreciated
One more bindins element referencing schema location should be provided:
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
version="2.1"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemalocation="http://java.sun.com/xml/ns/jaxb
http://java.sun.com/xml/ns/jaxb"
>
<jxb:bindings schemaLocation="PATH_TO_THE_SCHEMA" node="/xs:schema">
<jxb:bindings node="//xs:attribute[#name='vulnerabilities']">
<jxb:property name="vulnerabilityCount"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
Path can be relative to xjb file, e.g.: schemaLocation="../detailedreport.xsd"

How to get datatypes from XSD generic

I want to get the datatypes of an XSD. It have to be static, cause the XSD could be variate.
In my case I know the element names.
Small sample of XSD, but it could be go deeper:
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Order">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:float" name="OrderNo"/>
<xs:element type="xs:string" name="OrderDate"/>
<xs:element type="xs:string" name="Name"/>
<xs:element type="xs:float" name="NameNo"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
I tried with org.apache.xerces.xs but don´t know how to get the Object XSParticleDecl with Interface XSElementDeclaration from root Elem
I expect the output for each individual element name to be the type.
It's generally best to work with a schema processor that gives you some kind of access to the "schema component model" rather than working directly with source XSD documents.
The Xerces schema API is one approach but I don't have experience with that and can't help you with it.
Saxon offers two alternatives:
(a) you can generate an SCM file representing the compiled schema. This is an XML file, so it can be processed easily using XSLT or XQuery.
(b) there's a set of extension functions, starting with saxon:schema() that allow you to explore the schema directly from XPath.
I would personally work with an SCM file. The SCM file for your schema is:
<?xml version="1.0" encoding="UTF-8"?>
<scm:schema xmlns:scm="http://ns.saxonica.com/schema-component-model"
generatedAt="2019-08-22T18:14:23.59+01:00"
xsdVersion="1.1">
<scm:element id="C0"
name="Order"
type="C1"
global="true"
nillable="false"
abstract="false"/>
<scm:complexType id="C1"
base="#anyType"
derivationMethod="restriction"
abstract="false"
variety="element-only">
<scm:modelGroupParticle minOccurs="1" maxOccurs="1">
<scm:sequence>
<scm:elementParticle minOccurs="1" maxOccurs="1" ref="C2"/>
<scm:elementParticle minOccurs="1" maxOccurs="1" ref="C3"/>
<scm:elementParticle minOccurs="1" maxOccurs="1" ref="C4"/>
<scm:elementParticle minOccurs="1" maxOccurs="1" ref="C5"/>
</scm:sequence>
</scm:modelGroupParticle>
<scm:finiteStateMachine initialState="0">
<scm:state nr="0">
<scm:edge term="C2" to="1"/>
</scm:state>
<scm:state nr="1">
<scm:edge term="C3" to="2"/>
</scm:state>
<scm:state nr="2">
<scm:edge term="C4" to="3"/>
</scm:state>
<scm:state nr="3">
<scm:edge term="C5" to="4"/>
</scm:state>
<scm:state nr="4" final="true"/>
</scm:finiteStateMachine>
</scm:complexType>
<scm:element id="C2"
name="OrderNo"
type="#float"
global="false"
containingComplexType="C1"
nillable="false"
abstract="false"/>
<scm:element id="C3"
name="OrderDate"
type="#string"
global="false"
containingComplexType="C1"
nillable="false"
abstract="false"/>
<scm:element id="C4"
name="Name"
type="#string"
global="false"
containingComplexType="C1"
nillable="false"
abstract="false"/>
<scm:element id="C5"
name="NameNo"
type="#float"
global="false"
containingComplexType="C1"
nillable="false"
abstract="false"/>
</scm:schema>
<?Σ 954c7f5b?>
Built-in types are represented using, for example, type="#float", whereas user-defined types will be represented by a reference such as type="C89" where C89 is a reference to the #id attribute of an scm:simpleType or scm:complexType child of the scm:schema element.

XSD attribute-value based regex-validation in XSD 1.1 assert

I have and XML snippet like this. I need to do an XSD validation such that, for example: if the field attribute 'name' is port, then it has to match a regex for whether it is a number (like '\p{Nd}+')
<Data>
<Attributes>
<Field name="nodeType">abcd</Field>
<Field name="port">5462</Field>
</Attributes>
</Data>
In my XSD , I'm using an assert as shown below
<xs:element name="Field" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="name" use="optional"/>
<xs:assert test="if(#name='port') then matches($value,'\p{Nd}+') else false())"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
But, when I run, I am getting the following Exception thrown
xml is NOT valid reason:org.xml.sax.SAXParseException;cvc-xpath.3.13.4.2a: XPST0003 - Assertion XPath expression ('if(#name='port') then matches($value,'\p{Nd}+') else false())') on the schema type '#AnonType_FieldAttributesDataContainerRtms' couldn't compile successfully
You've got a stray closing bracket:
false())
^
Saxon error message for comparison:
Error at xs:assert on line 7 column 102 of test.xsd:
Unexpected token ")" beyond end of expression

Error while generating JAXB model from xsd in eclipse

I am trying to generate JAXB model from the following xsd
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://abc.com/mmm/trt" attributeFormDefault="unqualified"
elementFormDefault="qualified">
<xs:annotation>
<xs:documentation>Schema for Cache Refresh Event.
</xs:documentation>
</xs:annotation>
<xs:simpleType name="cacheCode">
<xs:restriction base="xs:string">
<xs:enumeration value="BUSINESS_RULE" />
<xs:enumeration value="USER" />
</xs:restriction>
</xs:simpleType>
<xs:element name="cacheRefreshEvent">
<xs:complexType>
<xs:sequence>
<xs:element name="cacheCode" type="cacheCode" minOccurs="1"
maxOccurs="1" />
<xs:element name="entityRefId" type="xs:string" minOccurs="0"
maxOccurs="20" />
<xs:element name="cacheRefreshDate" type="xs:dateTime"
minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
But, it is giving me the following error, which i got in Eclipse console
parsing a schema...
[ERROR] src-resolve.4.1: Error resolving component 'cacheCode'. It was detected that 'cacheCode' has no namespace, but components with no target namespace are not referenceable from schema document 'file:/F:/Sprint6/cache/src/main/resources/CacheRefreshEvent.xsd'. If 'cacheCode' is intended to have a namespace, perhaps a prefix needs to be provided. If it is intended that 'cacheCode' has no namespace, then an 'import' without a "namespace" attribute should be added to 'file:/F:/Sprint6/cache/src/main/resources/CacheRefreshEvent.xsd'.
line 18 of file:/F:/Sprint6/cache/src/main/resources/CacheRefreshEvent.xsd
Failed to parse a schema.
Please help.
Remove this extra namespace attribute targetNamespace="http://www.hcentive.com/mea/trr"
OR add this xmlns="http://www.hcentive.com/mea/trr"
Both solutions will work :)
For you reference targetnamespace-and-xmlns

Categories