JAXB customisation for a specifc class - wsdl

Is it possible to apply a JAXB custom binding to one (or a set) of specific classes from the WSDL?
From what I gather, going through the globalBidings element applies the customisation to all classes generated from the WSDL. I would like to be able to name the classes to which the customisation is applied.
So rather than, say...
<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb" version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<globalBindings>
<superClass name="com.syh.Shape"/>
</globalBindings>
</bindings>
... is there someway to limit the scope of the superclass?

You can use just <bindings> to customize a specific schema element (i.e. complex type). For your task I'd recommend using the Inheritance plugin:
<jaxb:bindings schemaLocation="schema.xsd" node="/xsd:schema">
<jaxb:bindings node="xsd:complexType[#name='shape']">
<inheritance:extends>com.syh.Shape</inheritance:extends>
</jaxb:bindings>
</jaxb:bindings>

Related

Are XMPP server implementations of binding not following the standard?

I recently tried binding based on RFC 6120 (9.1.3 pg 132) with:
<iq id='tn281v37' type='set'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq>
I would get a response of 'not well formed':
<stream:error xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'><not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/></stream:error>
It took a few days to find out it needed xmlns='jabber:client' :
<iq id='tn281v37' type='set' xmlns='jabber:client'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq>
It doesn't look like RFC 6120 has been superseded and every example of binding I find on the web doesn't have it. Is this due to implementation of the server? At the time I was binding to chinwag.im
This appears to be a misunderstanding of how XML namespaces work. In one of your comments you suggested that you are using a namespace of jabber:socket, but this is not a namespace that is defined anywhere in the XMPP specs and I could not find any reference to it online. Instead, you want to use jabber:client (or jabber:server if this were a server-to-server connection). A quick overview of XML namespaces is below:
All XML elements have a "name", this name is made of two parts: the local name and the namespace. The namespace is defined using an xmlns attribute, for example the following are different elements, they do not have the same name:
<iq xmlns="jabber:client"/>
<iq xmlns="jabber:server"/>
Namespaces declared using an xmlns attribute are inherited by their child elements (unless that element has its own xmlns attribute), therefore in the following:
<session xmlns="jabber:client">
<iq/>
<foo xmlns="bar"/>
</session>
Both the "session" element and the "iq" elements have the namespace "jabber:client" but "foo" has the namespace "bar".
There is also another way to declare a namespace: using a prefix. Prefixes are declared with an "xmlns:prefix" attribute (where "prefix" is the name of the prefix). The list of prefixes is inherited by child elements and don't need to be redeclared, and the namespace defined by the prefix only applies to elements that start with "prefix:". For example:
<stream:stream xmlns="jabber:client"
xmlns:stream="http://etherx.jabber.org/streams">
<iq/>
<stream:error></stream:error>
</stream:stream>
In the above the "stream" element has the namespace "http://etherx.jabber.org/streams", because it has the "stream:" prefix. The "iq" element on the other hand has the "jabber:client" namespace because it inherits it from the parents "xmlns" attribute. Finally, the "error" element also has the "http://etherx.jabber.org/streams" namespace because it uses the "stream:" prefix as well. Notice that it did not have to redeclare the stream prefix because it also inherits a list of prefixes from its parent elements, so just applying the prefix without re-defining it is okay.
It's impossible to tell from the level of detail you provided, but chances are you need to add xmlns="jabber:client" to your root element. If you don't have a root element to add it to (ie. when you're using the websocket protocol that sends lot of separate XML documents instead of one long stream), you will have to apply it separately to the root element in every frame you send.

JSF 2.2 Composite Component EditableValueHolder

I'm writing a composite component that contains an <h:selectManyMenu> and I'd like to allow clients of this component to supply validators and converters by placing <f:validator> and <f:converter> tags as children of my composite component's tag. In my composite's interface section I have
<composite:editableValueHolder name="select-input" targets="select-many" />
and in the implementation section:
<h:selectManyMenu id="select-many" styleClass="hidden select-input" value="#{cc.attrs['value']}" binding="#{cc.inputComponent}">
<composite:insertChildren />
</h:selectManyMenu>
and finally the usage:
<cwi:selectManyMenu id="select-many-menu" value="#{selectManyBean.selectedItems}">
<f:converter converterId="converter.testItem" for="select-many" />
<f:validator validatorId="validator.testItem" for="select-input" />
<f:selectItems value="#{selectManyBean.possibleItems}" var="item" itemValue="#{item}" itemLabel="#{item.description}" />
</cwi:selectManyMenu>
The problem is neither the validator nor converter are called. I also have validator and converter classes, each annotated with #FacesValidator('validator.testItem') and #FacesConverter("converter.testItem"), respectively. They are being picked up correctly, because if I move the <f:validator> and <f:converter> tags inside the composite component, underneath <composite:insertChildren> everything works fine, but I'd rather expose these to clients than hardcode them. Is there something about the way insertChildren works when using editableValueHolder? To get this working, I could just make the converter and validator IDs part of the interface, but that loses some flexibility for passing attributes to the converters and validators.
I am using Mojarra 2.2.8-jbossorg-1. Aside from the now obvious typo, I should also have included more of my composite component's xhtml. I was using a backing component, and without the backing component, everything worked fine once I fixed the typo, but when I added the backing component, the validator and converter stopped working.
After reviewing the wiki page here for composite components https://stackoverflow.com/tags/composite-component/info I realize backing components for composite components are not the same as the classes for custom components. For composite components, they should always just extend UINamingContainer. My mistake, for specifically this selectManyMenu, was that my backing component extend UISelectMany.

Fake GORM mapping for results of an ad-hoc query

I'd like to use Grails to build application which is a front-end to a complex data search and analysis system written already as a set of stored procedures in a RDBMS (here, oracle).
I'd like to instantiate objects of some class I written as a wrapper against rows of some dataset returned from a stored procedure. For this class I don't need to have any GORM mapping at all, I want to execute the query manually and instantiate these objects from it's rows. Those objects will never be changed and written, as the whole DB should be read-only, only session information can be stored.
Hibernate can do all this, and it has "Immutable" and read-only entities for this, but when I tried to mark this entity as "Immutable" I didn't have much success.
Is it possible to create such a fake mapping and at all, should it be created?
What are other possible ways to do this ?
I don't think you can do that in GORM, but you can use plain Hibernate with Grails.
Add your classes in the src/groovy folder. One example, in src/groovy/example:
package example
import java.io.Serializable;
import javax.persistence.Id
import javax.persistence.Entity
import javax.persistence.Table
import javax.persistence.Column
import org.hibernate.annotations.Immutable
#Entity
#Table(name="first_result")
#Immutable
class FirstResult implements Serializable {
private static final long serialVersionUID = 1L
#Id
Integer id
#Column(name="name")
String resultName
}
(You can also write POJOs in src/java but then you need to write constructors, getters and setters)
And in the grails-app/conf/hibernate/hibernate.cfg.xml add:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="example.FirstResult" />
</session-factory>
</hibernate-configuration>
Then, in your controllers and services you can use:
example.FirstResult.findAllById(1)
or any other method that works on domain classes in Grails.

How to make a Map with cxf in groovy?

GroovyWS is a framework which is internally using CXF. I want to make a request as follows:
<param2 xsi:type="ns2:Map">
<item xsi:type="ns2:Map">
<key xsi:type="xsd:string">param1</key>
<value xsi:type="xsd:string">param2</value>
</item>
</param2>
Currently I am trying to do this from a grails service as following:
def proxy = new WSClient("http://xyz", this.class.classLoader)
proxy.initialize()
proxy.client.invoke("call", new HashMap<String, String>())
Which gives
javax.xml.bind.JAXBException
class java.util.HashMap nor any of its super class is known to this context.
I even tried [:] and stuff but do not get it working.
Well, it's been a while since I did something like this, but I seem to remember that CXF-generated clients had a method called "create", similar to:
def mapObject = proxy.create( "ns2.Map" );
Give that a try and see if the mapObject has the methods or members you're expecting.
This is a known issue with using JAXB
The underlying problem is that your schema is ambiguous.
There are two solutions:
Use name spaces to remove any ambiguity
Resolve each Service individually into a different Java package.

how to customize a JAX-WS generated WSDL?

I am creating a SOAP service using JAX-WS and JAXB, by annotating the classes. My service implementation looks like this:
#Stateless
#Local(WSApplicationService.class)
#WebService(name = "WSApplicationService", serviceName = "WSApplicationService")
#BindingType(SOAPBinding.SOAP11HTTP_BINDING)
public class WSApplicationServiceImpl implements WSApplicationService {
#Override
#WebMethod
#WebResult(name = "reference")
public long submitApplication(#WebParam(name = "application") ApplicationSubmission application) throws SOAPException {
...
}
}
After asking this question, I learned that there's no way to specify certain restrictions on the input data using JAXB annotations. However, I need to restrict certain String properties to patterns (mainly postcodes and phone numbers). Therefore, I'm looking to customize the WSDL generated by above class. I can't find a way to access the WSDL though. Is there a way to override or customize the JAX-WS generated WSDL?
While you can safely have the WSDL generated automatically, it usually makes sense to hand-code the XSD referenced from the WSDL, which gives you all the richness of expression that a schema generated from JAXB classes can't, and also ensures the schema doesn't change when you don't want it to. (This practice is called contract-first, whereas starting with the classes is called code-first.)
When you do contract-first, you can generate your JAXB classes from the XSD automatically as part of your build process, making sure they're always in sync. You can customize the generated classes using XJB files.
In case you're using Maven, generating the classes could look like this:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.7.5</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>src/main/resources/wsdl</schemaDirectory>
<schemaIncludes>
<include>*.xsd</include>
</schemaIncludes>
<verbose>true</verbose>
<extension>true</extension>
</configuration>
</plugin>
Of course you can also use your hand-coded classes with a hand-coded schema definition (by telling the marshaller where to find it). I don't think you can take influence on the WSDL generation by other means.

Resources