ws jaxb custom external mapping - binding

I have to do custom JAXB external mapping file.
Already red tutorial about this and can not find any suitable example of JAXB customization. My scenario is that I have two WSDL files main WSDL and secondary WSDL which is included in main one. And in secondary WSDL file is one complexType definition which has a name that I want to customize. BTW name of that complexType is objectFactory. So now you know what I really really need that external customization.
I have came so far that when I run wsimport path-to-my-main-wsdl -b customBindings.jaxb
output is like
[ERROR] XPath evaluation of "//xs:complexType[#name='objectFactory']" results in empty target node
line 2 of file:/customBindings.jaxb
File customBindings.jaxb looks like
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings schemaLocation="path-to-my-secondary-wsdl#types?schema1" node="//xs:complexType[#name='objectFactory']">
<jxb:class name="MyObjectFactory" />
</jxb:bindings>
</jxb:bindings>
At second line of my customBindings.jaxb file are two properties schemaLocation and node. Does property schemaLocation need to point at main WSDL or secondary WSDl? And does property node be exact path (XPath) to wanted complexType or is like this ok? And what is with namespaces within XPath (node property), it has to be xs or what? And what actually this types and schema1 stands for in schemaLocation?
thx

I came across your question while researching the same problem.
A few vague hints are found on this page: http://jaxb.java.net/guide/Dealing_with_errors.html
Causes for the "empty target node" message are suggested at the bottom of that page.

Related

Facelet Tag Library mechanism does not work as expected

I'm unable to pack taglibrary in a war file. I moved tags from project to extra library the current project is depending now. I put the taglibrary file into the META-INF directory of the jar containing tags (how is described here). But the page does not work:
Expression Error: Named Object: eu.barbucha.barbatag.simple.PropertyTag not found.
The server is able to find the taglibrary. Otherwise the page works, just one waring appears:
Warning: This page calls for XML namespace http://barbucha.eu/tags declared with prefix br but no taglibrary exists for that namespace.
Thus the question is: Why the server finds just the descriptor, but not the classes? When I copy classes from WEB-INF/lib/barbatag.jar into WEB-INF/classes and restart the webapp in administration console, the page gets working. The server also finds UI-components only if they are involved directly in classes of the applictation, but not in the jar stored in the WEB-INF/lib directory. On other hand the server loads taglib descriptor from the jar. It's really confusing... Declaration of the critical class:
package eu.barbucha.barbatag.simple;
#FacesComponent("eu.barbucha.barbatag.simple.PropertyTag")
public class PropertyTag extends UIComponentBase { ... }
Definition of critical tag:
<tag>
<display-name>The component taking values from a property file</display-name>
<tag-name>property</tag-name>
<component>
<component-type>eu.barbucha.barbatag.simple.PropertyTag</component-type>
</component>
</tag>
One potentionally important point: I'm using Spring MVC.
You need to supply a /META-INF/faces-config.xml file in the JAR in order to get JSF to scan the JAR file for classes with JSF specific annotations like #FacesComponent. This is done so to prevent JSF from unnecessarily scanning every single JAR file for classes (which might be very time and CPU consuming if you have lot of them).

bean-validation validation.xml ignored

I am using JSR 303 Bean validation in my JSF 2.0 web application and it works fine with annotations. Now I would like to ignore annotations and configure validation rules using the validation.xml file, so this is what I did (I am using an eclipse dynamic web project) :
Added validation.xml under WebContent/META-INF/validation.xml
<?xml version="1.0" encoding="UTF-8"?>
<validation-config
xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.0.xsd"
>
<constraint-mapping>META-INF/validation/constraint-mapping.xml</constraint-mapping>
</validation-config>
Then created the file constraint-mapping.xml under WebContent/META-INF/validation/constraint-mapping.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.0.xsd"
xmlns="http://jboss.org/xml/ns/javax/validation/mapping">
<bean class="my.full.path.ValidationMB" ignore-annotations="true">
</bean>
</constraint-mappings>
Having these configurations in place, I suppose the annotations in my bean class ValidationMB shall be ignored, BUT this is not happening!, which makes me assume that the validation.xml file is not being loaded.
any ideas? thanks.
Environment:
Apache Tomcat 7.0.23
javax.faces-2.1.4.jar
hibernate-validator-4.2.0.Final.jar
hibernate-validator-annotation-processor-4.2.0.Final.jar
validation-api-1.0.0.GA.jar
slf4j-api-1.6.1.jar
From the spec: section 4.4.6. XML Configuration: META-INF/validation.xml
Unless explicitly ignored by calling
Configuration.ignoreXMLConfiguration(), a Configuration takes into
account the configuration available in META-INF/validation.xml. This
configuration file is optional but can be used by applications to
refine some of the Bean Validation behavior. If more than one
META-INF/validation.xml file is found in the classpath, a
ValidationException is raised.
To solve my problem I had to create a META-INF folder under the project src folder, which ends in the WEB-INF/classes/META-INF.
The structure of the web application is:
ROOT
|_META-INF -- don't put validation.xml here
|_WEB-INF
|__ classes
|_META-INF
|__validation.xml
But I think that if I pack my web application in a jar file and reuse it in another project It may not work, I will let you know later once I do it.
Try to put your validation.xml directly into the WEB-INF/ directory.
I stumbled across this while looking for something else but wanted to clarify to the OP what is happening. You do in fact need the file to exist at META-INF/validation.xml; however, that is relative to the classpath which is why it worked when you put it under WEB-INF/classes/META-INF/validation.xml.
The cleaner approach is to let the file be put there for you. Your Eclipse project should already be outputting whatever is in your source directory to WEB-INF/classes somehow for you or nothing would be running. But sometimes there are filters on what it outputs so it might excluding something. You might want to check your src dirs and make sure they don't have exclusions.
Just as an example, if you had a Maven war project, all of your java sources would go in src/main/java and the generated classes would end up in the WEB-INF/classes directory. The equivalent happens for src/main/resources which contains non-source files. When I want *.xml, *.properties, etc. to end up in WEB-INF/classes I put them in src/main/resources. For your example I would have a src/main/resources/META-INF/validation.xml file.
Hope this helps anyone else who comes across this and is confused.

Combine JAXB and JAXWS for an imported XML Schema

How can I specify a JAXB Binding for an imported XSD within a WSDL when using wsimport?
I tried following binding, which causes the error "XPath evaluation of //xs:element[#name='isFoobar'] results in an empty target node".
<?xml version="1.0" encoding="UTF-8"?>
<jaxws:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" wsdlLocation="example.wsdl"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" xmlns:jaxws="http://java.sun.com/xml/ns/jaxws">
<jaxws:bindings node="wsdl:definitions">
<jaxws:bindings node="wsdl:types" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
<jaxws:bindings
node="//xs:schema[#targetNamespace='http://www.example.org/']">
<jaxb:globalBindings>
<xjc:serializable uid="10000001" />
</jaxb:globalBindings>
<jaxb:bindings
node="//xs:element[#name='isFoobar']">
<jaxb:typesafeEnumClass name="IsFoobar">
<jaxb:typesafeEnumMember value="01" name="TRUE" />
<jaxb:typesafeEnumMember value="02" name="FALSE" />
</jaxb:typesafeEnumClass>
</jaxb:bindings>
</jaxws:bindings>
</jaxws:bindings>
</jaxws:bindings>
</jaxws:bindings>
Any ideas?
Sorry for the necro-threading, I encountered this problem and although this is one of the first answer that showed up on google with various key word combination it didn't hold the answer I ended up using.
For imported schemas, the easiest way to specify a JAXB binding on an imported XSD within a WSDL is... to treat it as a completely different schema !
Short example :
MyXSD.xsd
<xsd:schema targetNamespace="whatever"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="ThingThatNeedsToBeBound">
<!-- Whatever this is made of -->
</xs:complexType>
</xsd:schema>
No matter where this xsd is imported (wether it's at the root of the of my wsdl or within a nested import), all I need to write to bind my "ThingThatNeedsToBeBound" in my custom binding is :
customBindings.xml
<jaxb:bindings schemaLocation="Path/To/MyXSD.xsd" node="/xs:schema/xs:complexType[#name='ThingThatNeedsToBeBound']">
<!-- your custom binding -->
</jaxb:bindings>
So, it's just like a regular case, except that you specify the schemaLocation, but then you can consider the imported schema as a whole itself instead of a part of something.
I hope this will help others stumbling upon this problem.
Source : http://www.oracle.com/technetwork/articles/grid/jax-ws-jaxb-customization-082750.html
(Note : in the source, the solution seems way more complicated, so my case might have been simpler than what they described, I found my solution using that none the less !)
I did something similar ages ago, I think you need to specify the node to select with XPath as follows:
//xs:element[#name='isFoobar']/xs:complexType
Or replace xs:complexType with whatever kind of type you are using here. Hopefully it will fix your probelm.
My first try at resolving this was trying to somehow use XPath or multiple jxb:binding elements, but that didn't work. As far as I know the XPath just isn't validated properly against imported schemas unless it would all be rewritten and mashed together with DOM.
So the way I resolved this problem was by using inline customizations in the imported XSD. I didn't test this approach with multiple nested imports, but if you got access and time to modify all the imported XSDs this should work out ok. In my opinion this is only necessary if you need to generate the mapping and can be scrubbed/removed from the XSD once the mapping is done.

xmltask confused about dtd

I'm trying to use xmltask for ant to modify a file in a subdirectory:
project/path/to/file.xml
The file refers to a DTD like this:
<!DOCTYPE data SYSTEM "mydtd.dtd">
I don't have the flexibility to change these documents.
This DTD is stored in the same subdirectory, which has always worked fine:
project/path/to/mydtd.dtd
Unfortunately, xmltask is trying to locate the dtd in my project's top-level directory, which is where my build file is located, and where I run from:
[xmltask] java.io.FileNotFoundException: /home/me/project/mydtd.dtd (The system cannot find the file specified)
I see in the xmltask documentation that I can correct this with an xmlcatalog element to tell it where to look up the file. But I need to use a dtd element, and I can only find examples for this element, not documentation; the examples show only a publicId, and if I understand XML correctly this document does not have one. I shouldn't need to specify this, anyway, right, since my document already says my DTD is stored locally and shows right where it is?
Why isn't xmltask finding the DTD correctly? What's the best way to correct or work around this situation?
An XML Catalog is the way to go here, it just needs a bit more perseverance.
As you correctly pointed out, the standard Ant <XmlCatalog> type only allows you to specify public DTD references when using the inline syntax, which is of no use to you. However, <XmlCatalog> also lets you specify a standard OASIS-syntax catalog, which is far richer, including resolving SYSTEM DTD references.
An OASIS catalog (full spec here) looks like this:
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system systemId="mydtd.dtd" uri="project/path/to/mydtd.dtd"/>
</catalog>
You can then reference this catalog from the <XmlCatalog>:
<xmlcatalog refid="commonDTDs"/>
<catalogpath>
<pathelement location="path/to/oasis.catalog"/>
</catalogpath>
</xmlcatalog>
And that's that. It's a good idea to build up a reusable OASIS catalog file, and refer to it from various XML-related Ant tasks, all of which can use <XmlCatalog>.
As an alternative, it looks like I can skip the whole validation by creating a blank file with the same name as the DVD file, and then deleting the file when I am done. Odds are I am going to go that route instead of using the catalog.
xmltask isn't finding it because it is looking in the current working directory. Ant allows you to specify a base directory using the basedir attribute of the <target> element. So I suggest you try this:
<target basedir="path/to" ...>
<xmltask...
</target>
It strikes me that it is not the XML/DTD that you really have the problem with, but getting xmltask to interact with the two of them as you want.
If that fails, you could use the Ant Copy task to copy the XML and DTD to the root folder before processing with xmltask, then copying back again.
Have you tried:
<!DOCTYPE data SYSTEM "./path/to/mydtd.dtd">
? Or an absolute path?
Also, you can find <dtd> description here.
I had a similar problem where an XML file had a doctype with SYSTEM reference that could not be changed.
<!DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd">
I first went down the road and created a catalog file with the OASIS catalog as described above, but to be able to use external catalogs I had to include the Apache Commons Resolver 1.1 (resolver.jar) in the Ant classpath (see http://ant.apache.org/manual/Types/xmlcatalog.html).
Because I had multiple machines on which this build was supposed to run this seemed overkill, especially since xmltask worked fine if I just removed the doctype definition. I wasn't allowed to remove it permanently because the doctype was needed elsewhere.
Ultimately I used this workaround: I commented out the doctype definition using Ant's replace task, ran the xmltask, and then put the doctype back into the file.
<replace file="myxmlfile.xml">
<replacetoken><!DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd"></replacetoken>
<replacevalue><!-- !DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd" --></replacevalue>
</replace>
<xmltask .../>
<replace file="${local.opencms.webapp.webinf}/config/opencms-modules.xml">
<replacetoken><!-- !DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd" --></replacetoken>
<replacevalue><!DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd"></replacevalue>
</replace>

Delphi/MSXML: XPath queries fail

I've loaded a XML document, and now I wish to run a XPath query to select a certain subset of the XML. The XML is
<?xml version="1.0"?>
<catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications with
XML.</description>
</book>
</catalog>
and the procedure goes something like
procedure RunXPathQuery(XML: IXMLDOMDocument2; Query: string);
begin
XML.setProperty('SelectionLanguage', 'XPath');
NodeListResult := XML.documentElement.selectNodes(Query));
ShowMessage('Found (' + IntToStr(NodeListResult.length) + ') nodes.');
end;
Problem is: when I run the XPath query '/catalog' for the above XML, it returns (as expected) a nodelist of 1 element. However, if I remove :xsi from
<catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> and re-run the query, the nodelist returned is empty. If I remove the entire 'xmlns'-attribute, the resulting nodelist has, once again, 1 element.
So my question is this: what can I do to remedy this, i.e. how do I make MSXML return the correct number of instances (when running a XPath query), regardless of the namespace (or other attributes)?
Thanks!
See this link!
When you use <catalog xmlns='http://www.w3.org/2001/XMLSchema-instance'> then the whole node will be moved to a different (default) namespace. Your XPath isn't looking inside this other namespace so it can't find any data. With <catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> you're just declaring xsi as a different namespace. This would be a different namespace than the default namespace.
I can't test it right now but adding something like this might help:
XML.setProperty('SelectionNamespaces', 'xmlns=''http://www.w3.org/2001/XMLSchema-instance''');
Or maybe it doesn't. As I said, I can't test it right now.
Figured it out. It seems that my problem has been described here and here (and most likely a zillion other places, too).
The query /*[local-name()='catalog'] works for me.
Use:
document.setProperty('SelectionNamespaces', 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"')
/*[local-name()='catalog']
is a solution to your question.
But why would you want to ignore namespaces? They have been introduced to express something, e.g. to distinguish different types of catalogs. With your query, you can now select the content of any catalog in the world, but I assume you can only handle books. What will happen if you get a catalog of screws or cars instead?
The mentioned things about the prefix (xsi) is correct. If you remove the prefix, all elements are in that namespace (called default namespace then). But you can still deal with it.
In your code, give the namespace a prefix anyway. It needn't even match the original prefix:
XML.setProperty('SelectionNamespaces', "xmlns:xyz='http://www.w3.org/2001/XMLSchema-instance'");
The second thing is to adapt the XPath query. It must then be
/xyz:catalog
The original XML only declares the xsi namespace, but never makes use of it. In this case, you can remove it completely. If you want to use the namespace and you want it with prefixes, then rewrite your XML to
<?xml version="1.0"?>
<xsi:catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<xsi:book id="bk101">
<xsi:author>Gambardella, Matthew</xsi:author>
<xsi:title>XML Developer's Guide</xsi:title>
<xsi:genre>Computer</xsi:genre>
<xsi:price>44.95</xsi:price>
<xsi:publish_date>2000-10-01</xsi:publish_date>
<xsi:description>An in-depth look at creating applications with
XML.</xsi:description>
</xsi:book>
</xsi:catalog>

Resources