Is it possible to customize the namespace prefix that JAXB uses when marshalling to a String? - xml-serialization

For example, I've got a simple schema which imports another schema. The second schema (urn:just:attributes, just-attributes.xsd) just defines an attribute group.
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/MySchema"
xmlns:tns="http://www.example.org/MySchema"
elementFormDefault="qualified"
xmlns:ja="urn:just:attributes">
<import schemaLocation="just-attributes.xsd" namespace="urn:just:attributes"/>
<element name="MyElement">
<complexType>
<attributeGroup ref="ja:AttributeGroup"/>
</complexType>
</element>
</schema>
I'm using the Metro xjc Ant task to generate classes off of this schema. The problem I'm running into is that the third party application I'm interacting with is peculiar about namespaces. This case I need a String value, so I have to serialize it. I use boilerplate code for this.
private static <T> String marshal(T object) throws JAXBException{
OutputStream outputStream = new ByteArrayOutputStream();
JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass());
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.marshal(object, outputStream);
return outputStream.toString();
}
Which gives me something along the lines of
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:MyElement xmlns:ns1="urn:just:attributes" xmlns:ns2="http://www.example.org/MySchema" ns1:attrib1="1234" ns1:attrib2="5678"/>
The problem I have is that this third party expects something like xmlns:thirdpartyns="urn:just:attributes", which is to say, they are parsing based on the name given to the namespace. It has to be "thirdpartyns" for their software to work.
Does anyone know of a way around this, short of doing a find and replace in the resulting string? A custom binding rule perhaps?

http://hwellmann.blogspot.com/2011/03/jaxb-marshalling-with-custom-namespace.html
This shows how to do it.
Another:
http://www.systemmobile.com/?p=280
Key bits in case that link dies too:
the NamespacePrefixMapper class, found in the com.sun.xml.bind.marshaller package. The abstract class has one method to implement:
public abstract String getPreferredPrefix(
String namespaceUri,
String suggestion,
boolean requirePrefix);
then
Marshaller marshaller =
jaxbContext.createMarshaller();
marshaller.setProperty(”com.sun.xml.bind.namespacePrefixMapper”,
new MyNamespacePrefixMapper());
If you’re also using javax.xml.xpath.XPath, your NamespacePrefixMapper can also implement javax.xml.namespace.NamespaceContext, centralizing your namespace customization in a single class.

I tested that in Java SE6 and it requires a small change compared to the solution for Java SE 5 (as described above):
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
m.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper", mapper);
So the third property from above contains the additional .internal. in the package name compared to the Java SE5 version.
What I did not find out yet is how to tell the Marshaller which namespace URI becomes the default namespace (""). If I override the method getPreferredPrefix() and return an empty string, the Marshaller has issues with writing attributes of the default namespace (in this case it creates a new namespace called ns1)

I had the same question. In package-info.java (if you don't have it, you can just manually create it) add the xmlns part:
#javax.xml.bind.annotation.XmlSchema(xmlns = {
#javax.xml.bind.annotation.XmlNs(namespaceURI = "urn:just:attributes", prefix = "thirdpartyns") },
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)

There is a way of doing this, which uses an internal JAXB implementation class called NamespacePrefixMapper. In the JAXB RI, this is in com.sun.xml.bind.marshaller, but in Java6, it's in com.sun.xml.internal.bind.marshaller.
This is an abstract class, which you can subclass and implement the abstract method which maps namespace URIs on to prefixes.
You then inject an instance of that subclass into the marshaller:
JAXBContext context = ...
Marshaller marshaller = context.createMarshaller();
NamespacePrefixMapper prefixMapper = new MyPrefixMapperImpl();
marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", prefixMapper);
The property name is going to be different for the Java6 version, but you get the idea.
Note that this is an internal JAXB implementation class, so there's no guarantee it'll be there in future versions.

Related

Using Guice/Peaberry for osgi declarative services

I want to solve the following problem and need advice, what the best solution is.
I have a bundle A in which a service interface X is defined. A bundle B provides a service implementation of X and contributes the implementation to the tool. A and B use Google Guice and Peaberry to configure the setup of the objects.
There are two possibilities I can use to contribute the service implementation:
Using an eclipse extension:
In this solution I can use the GuiceExtensionFactory mechanism of Peaberry to create the service implementation using Guice and therefore can inject stuff needed by the implementation. The disadvantage here is that in the bundle defining the extension point, I need the boilerplate code for the resolution of the extensions because there is to my knowledge no way to get the extensions injected into the class which uses the extensions.
This looks like this:
<extension point="A.service.X">
<xservice
...
class="org.ops4j.peaberry.eclipse.GuiceExtensionFactory:B.XImpl"
.../>
</extension>
<extension
point="org.ops4j.peaberry.eclipse.modules">
<module
class="B.XModule">
</module>
</extension>
but I need the boilerplate code like this:
private List<X> getRegisteredX() {
final List<X> ximpls = new ArrayList<>();
for (final IConfigurationElement e : Platform.getExtensionRegistry().getConfigurationElementsFor( X_EXTENSION_POINT_ID)) {
try {
final Object object = e.createExecutableExtension("class"); //$NON-NLS-1$
if (object instanceof X) {
ximpls.add((X) object);
}
} catch (final CoreException ex) {
// Log
}
}
return ximpls;
}
Using an OSGI service:
My main problem here is to ensure that the service is registered. I want the bundle loaded lazily, so at least an access to one of the classes of the bundle is required. Registering the service programmatically using Peaberry has an issue, because nobody ever asks for a class of the bundle. The solution is to provide the service as a declarative service, but I do not know a way to create the service implementation in a way, that I can use Guice to inject required objects.
So I have some questions:
Is there something I do not know so far that implements the code needed to read the extensions at an extension point generically and allows to inject the extensions to the class using the extensions?
Is there a way to ensure that the service is provided even if it is added using the standard Peaberry mechanism, i.e., the bundle is activated when the service is requested?
Is there a way like the GuiceExtensionFactory for declarative services, so that the creation of the service implementation can be done by the injector of the bundle?
Something that look like:
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Ximpl">
<implementation class="some.generic.guiceaware.ServiceFactory:B.Ximpl"/>
<service>
<provide interface="A.X"/>
</service>
</scr:component>
Summarized, I want a service implementation generated by Guice and I want to get the service implementations simply injected into the classes using the service without extensive boilerplate code. Has anybody a solution for that?
Sorry, to ask, but I searched the web for quite a while and so far I did not find a solution.
Thanks and best regards,
Lars
I found a solution, but since I did not find it without a lot of trying out and thinking I thought I share it here. From the options I mentioned in my posting, my solution uses the first one, that is Eclipse extension points and extensions. In order to use Guice in the context of extension points there are two aspects to consider:
Providing an extension that is created by an Guice injector
This is explained very well here: https://code.google.com/p/peaberry/wiki/GuiceExtensionFactory. There is one remark to make from my side. The creation of the extension object is done in an injector inside of the GuiceExtensionFactory, so it is an own context, which needs to be configured by the module given as additional extension to the factory. This can become an issue, if you have other needs that require creating the injector in the bundle on your own.
Defining an extension point so that the extensions are simply injected into the classes which use the extensions.
First thing to do is to define the extension point schema file as normally. It should contain the reference of an interface that has to be implemented by the extensions.
The id of the extension point has to be connected to the interface which is provided by the extensions and which is injected by guice/peaberry. Therefore peaberry provides an annotation to be used to annotate the interface:
import org.ops4j.peaberry.eclipse.ExtensionBean;
#ExtensionBean("injected.extension.point.id")
public interface InjectedInterface {
...
}
On some web pages you also find the information that if the id is equal to the qualified name of the interface, it can be found directly without the annotation but I did not try this out.
In order to enable the injection, you have to do two things to configure the Guice injector creation.
First the EclipseRegistry object of Peaberry has to be set as ServiceRegistry. Second the binding of the extension implementations to a provided service has to be done.
The injector creation has to be done in this way:
import org.osgi.framework.BundleContext;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.ops4j.peaberry.eclipse.EclipseRegistry;
import static org.ops4j.peaberry.Peaberry.*;
void initializer() {
Injector injector = Guice.createInjector(osgiModule(context, EclipseRegistry.eclipseRegistry()), new Module() {
binder.bind(iterable(InjectedInterface.class)).toProvider(service(InjectedInterface.class).multiple());
});
}
The extension implementations can then simply be injected like this:
private Iterable<InjectedInterface> registeredExtensions;
#Inject
void setSolvers(final Iterable<InjectedInterface> extensions) {
registeredExtensions = extensions;
}
With the described way it is possible to have injected extensions which are implemented by classes using Guice to get dependencies injected.
I did not find a solution to use osgi services so far, but perhaps there is someone who has an idea.
Best regards,
Lars

what is a jaxb provider, jaxb handler, and contextResolvers?

1) What is a JaxB provider, and is it the same as a ContextResolver?
2) What is a jaxb handler?
I'm very lost in these terminologies. Please reply in simple to understand words.
Here it is from the book:
JAXB JAX-RS Handlers
The JAX-RS specification requires implementations to automatically support the marshalling and unmarshalling of classes that are annotated with #XmlRootElement or #XmlType as well as objects wrapped inside javax.xml.bind.JAXBElement instances. Here’s an example that interacts using the Customer class defined earlier:
#Path("/customers")
public class CustomerResource {
#GET
#Path("{id}")
#Produces("application/xml")
public Customer getCustomer(#PathParam("id") int id) {
Customer cust = findCustomer(id);
return cust;
}
#POST
#Consumes("application/xml")
public void createCustomer(Customer cust) {
...
}
}
As you can see, once you’ve applied JAXB annotations to your Java classes, it is very easy to exchange XML documents between your client and web services. The built-in JAXB handlers will handle any JAXB-annotated class for the application/xml, text/xml, or application/*+xml media types. By default, they will also manage the creation and initialization of JAXBContext instances. Because the creation of JAXBContext instances can be expensive, JAX-RS implementations usually cache them after they are first initialized.
Managing your own JAXBContexts with ContextResolvers
If you are already familiar with JAXB, you’ll know that many times you need to configure your JAXBContext instances a certain way to get the output you desire. The JAX-RS built-in JAXB provider allows you to plug in your own JAXBContext instances. The way it works is that you have to implement a factory-like interface called javax.ws.rs.ext.ContextResolver to override the default JAXBContext creation:
public interface ContextResolver<T> {
T getContext(Class<?> type);
}
ContextResolvers are pluggable factories that create objects of a specific type, for a certain Java type, and for a specific media type. To plug in your own JAXBContext, you will have to implement this interface. Here’s an example of creating a specific JAXBContext for our Customer class:
#Provider
#Produces("application/xml")
public class CustomerResolver
implements ContextResolver<JAXBContext> {
private JAXBContext ctx;
public CustomerResolver() {
this.ctx = ...; // initialize it the way you want
}
public JAXBContext getContext(Class<?> type) {
if (type.equals(Customer.class)) {
return ctx;
} else {
return null;
}
}
}
JAXB Provider
A JAXB provider is an implementation of the Java Architecture for XML Binding (JSR-222) specification. This specification was created through the Java Community Process. It was originally lead by Sun Microsystems, but is now lead by Oracle. The expert group had members from several object-to-XML technologies (XMLBeans, EMF, TopLink OX, etc) as well as several individuals. A JAXB implementation is required to pass the Test Compatibility Kit (TCK). Below are links to a couple of JAXB providers:
https://jaxb.java.net/
http://www.eclipse.org/eclipselink/moxy.php
ContextResolver
JAXB is the default object-to-XML provider in JAX-RS. By default it will create a JAXBContext based on the parameter/return type of the JAX-RS annotated method (i.e. annotated with #GET). Then it will pull in all referenced classes to produce metadata as well. Sometimes this doesn't produce all the required metadata and you need to provide the JAXBContext yourself. This can be done with a ContextResolver.
JAXB Handler
I'm not familiar with this term.
JAXB is the acronym for "Java Architecture for XML Binding", a specification defining ways to convert between XML documents and Java object trees, originally created by Sun Microsystems. The valid spec, version 2.0, was completed in 2006.
An implementation according to the JAXB specification is a JAXB provider.
The specification contains some hints, what a plausible implementation might contain. For instance: "The JAXBContext class is the entry point for a Java application into the
JAXB framework." It maintains information about the classes to expect during (un)marshalling. It is created either from one or more packages or from a list of classes. (The process of context resolution may follow hints in the annotation.)
The term "JAXB handler" (as it is used in the quoted text) refers to the code associated with a JAXBContext class that investigates a Java class, introspecting fields and methods and annotations, thus creating a database of all information contained within the Java code.

Using the Apache felix SCR Annoration #Reference in Scala, for an OSGI environment

I am trying to use the #Reference Felix SCR annotation in Scala
This is how it can be used in Java:
public class Foo {
#Reference
MyServiceInterface service;
// some code here
}
Here, MyService is ideally a Java Interface and not a concrete class (dependency injection)
I am using the same annotation in Scala, trying to depend on the same MyService (a Java Interface), like:
class Foo {
#Reference
val service = MyServiceInterface // ??
// some code here
}
How can I use this annotation in Scala, to refer to a Java Interface?
example:
#Reference
val MyServiceInterface service
or
#Reference
val service = MyServiceInterface
is not valid Scala code
Thank you
I know very little about Scala but I believe "val" means an immutable value, and thus it makes very little sense to bind it to a (mutable) service reference.
Shouldn't this member field be declared with "def" or "var" instead? In which case maybe the annotation will be allowed.
The reference annotation has a interfaceReference attribute.
This attribute can be used to specify the java interface.
I assume in scala it would look like (never used Felix Annotation in scala):
#Reference(interfaceReference = MyServiceInterface)
val MyServiceInterface service
It might be that you also have to specify the bind and unbind method in this case.
Please see also Felix Annotations documentation
Since 1.9.0 Felix Annotation are runtime annotations. The Annotation Felix Processor has an option scanClasses to use classes instead of source code to process the annotations. This works perfectly fine with groovy. I see no reason why that should not work with Scala.
If you use Intellij then please have a look at the Felix Annotation Plugin. The plugin uses by default scan classes
I was able to solve this problem by specifying the type of the variable correctly like:
#Reference
var service: MyServiceInterface = null
#Neil is right, we must use a var instead of a val as the service binding happens at runtime.
Secondly, I had to add the following configuration to the maven-scr-plugin:
<configuration>
<scanClasses>true</scanClasses>
</configuration>
Then, I had to specifically instruct the Maven Bundle plugin to NOT import the org.apache.felix.scr.annotations package as follows:
<Import-Package>!org.apache.felix.scr.annotations, *</Import-Package>
because the manifest would otherwise include an entry for this package as something that the bundle depends on.
Once this was done, the mvn-scr-plugin would generate the XML file correctly and the mvn-bundle-plugin would generate the bundle, manifest correctly.

Get env-entry in scala jax-ws web-service

I'm implementing a quick and dirty SOAP web-service, using jax-ws and Scala.
I have a trait for endpoint interface and a class implementing that trait.
Everything was fine until I tried to get evn-entries from web.xml
I do something like that:
In web.xml:
<env-entry>
<env-entry-name>name</env-entry-name>
<env-entry-value>value</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>
In code:
val context = new InitialContext().asInstanceOf[Context]
val value = context.lookup("java:comp/env/name")
I get NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
What am I doing wrong?
It seems that you need to specify a class for initial context factory in the property "java.naming.factory.initial". You can specify that in a HashTable object and pass it to InitialContext.
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"your initial context factory class name here");
val context = new InitialContext(env)

GWT Dynamic loading using GWT.create() with String literals instead of Class literals

GWT.create() is the reflection equivalent in GWT,
But it take only class literals, not fully qualified String for the Class name.
How do i dynamically create classes with Strings using GWT.create()?
Its not possible according to many GWT forum posts but how is it being done in frameworks like Rocket-GWT (http://code.google.com/p/rocket-gwt/wiki/Ioc) and Gwittir (http://code.google.com/p/gwittir/wiki/Introspection)
It is possible, albeit tricky. Here are the gory details:
If you only think as GWT as a straight Java to JS, it would not work. However, if you consider Generators - Special classes with your GWT compiler Compiles and Executes during compilation, it is possible. Thus, you can generate java source while even compiling.
I had this need today - Our system deals with Dynamic resources off a Service, ending into a String and a need for a class. Here is the solutuion I've came up with - btw, it works under hosted, IE and Firefox.
Create a GWT Module declaring:
A source path
A Generator (which should be kept OUTSIDE the package of the GWT Module source path)
An interface replacement (it will inject the Generated class instead of the interface)
Inside that package, create a Marker interface (i call that Constructable). The Generator will lookup for that Marker
Create a base abstract class to hold that factory. I do this in order to ease on the generated source code
Declare that module inheriting on your Application.gwt.xml
Some notes:
Key to understanding is around the concept of generators;
In order to ease, the Abstract base class came in handy.
Also, understand that there is name mandling into the generated .js source and even the generated Java source
Remember the Generator outputs java files
GWT.create needs some reference to the .class file. Your generator output might do that, as long as it is referenced somehow from your application (check Application.gwt.xml inherits your module, which also replaces an interface with the generator your Application.gwt.xml declares)
Wrap the GWT.create call inside a factory method/singleton, and also under GWT.isClient()
It is a very good idea to also wrap your code-class-loading-calls around a GWT.runAsync, as it might need to trigger a module load. This is VERY important.
I hope to post the source code soon. Cross your fingers. :)
Brian,
The problem is GWT.create doen't know how to pick up the right implementation for your abstract class
I had the similar problem with the new GWT MVP coding style
( see GWT MVP documentation )
When I called:
ClientFactory clientFactory = GWT.create(ClientFactory.class);
I was getting the same error:
Deferred binding result type 'com.test.mywebapp.client.ClientFactory' should not be abstract
All I had to do was to go add the following lines to my MyWebapp.gwt.xml file:
<!-- Use ClientFactoryImpl by default -->
<replace-with class="com.test.mywebapp.client.ClientFactoryImpl">
<when-type-is class="com.test.mywebapp.client.ClientFactory"/>
</replace-with>
Then it works like a charm
I ran into this today and figured out a solution. The questioner is essentially wanting to write a method such as:
public <T extends MyInterface> T create(Class<T> clz) {
return (T)GWT.create(clz);
}
Here MyInterface is simply a marker interface to define the range of classes I want to be able to dynamically generate. If you try to code the above, you will get an error. The trick is to define an "instantiator" such as:
public interface Instantiator {
public <T extends MyInterface> T create(Class<T> clz);
}
Now define a GWT deferred binding generator that returns an instance of the above. In the generator, query the TypeOracle to get all types of MyInterface and generate implementations for them just as you would for any other type:
e.g:
public class InstantiatorGenerator extends Generator {
public String generate(...) {
TypeOracle typeOracle = context.getTypeOracle();
JClassType myTYpe= typeOracle.findType(MyInterface.class.getName());
JClassType[] types = typeOracle.getTypes();
List<JClassType> myInterfaceTypes = Collections.createArrayList();
// Collect all my interface types.
for (JClassType type : types) {
if (type.isInterface() != null && type.isAssignableTo(myType)
&& type.equals(myType) == false) {
myInterfaceTypes.add(type);
}
for (JClassType nestedType : type.getNestedTypes()) {
if (nestedType.isInterface() != null && nestedType.isAssignableTo(myType)
&& nestedType.equals(myTYpe) == false) {
myInterfaceTypes.add(nestedType);
}
}
}
for (JClassType jClassType : myInterfaceTypes) {
MyInterfaceGenerator generator = new MyInterfaceGenerator();
generator.generate(logger, context, jClassType.getQualifiedSourceName());
}
}
// Other instantiator generation code for if () else if () .. constructs as
// explained below.
}
The MyIntefaceGenerator class is just like any other deferred binding generator. Except you call it directly within the above generator instead of via GWT.create. Once the generation of all known sub-types of MyInterface is done (when generating sub-types of MyInterface in the generator, make sure to make the classname have a unique pattern, such as MyInterface.class.getName() + "_MySpecialImpl"), simply create the Instantiator by again iterating through all known subtypes of MyInterface and creating a bunch of
if (clz.getName().equals(MySpecialDerivativeOfMyInterface)) { return (T) new MySpecialDerivativeOfMyInterface_MySpecialImpl();}
style of code. Lastly throw an exception so you can return a value in all cases.
Now where you'd call GWT.create(clz); instead do the following:
private static final Instantiator instantiator = GWT.create(Instantiator.class);
...
return instantiator.create(clz);
Also note that in your GWT module xml, you'll only define a generator for Instantiator, not for MyInterface generators:
<generate-with class="package.rebind.InstantiatorGenerator">
<when-type-assignable class="package.impl.Instantiator" />
</generate-with>
Bingo!
What exactly is the question - i am guessing you wish to pass parameters in addition to the class literal to a generator.
As you probably already know the class literal passed to GWT.create() is mostly a selector so that GWT can pick and execute a generator which in the end spits out a class. The easist way to pass a parameter to the generator is to use annotations in an interface and pass the interface.class to GWT.create(). Note of course the interface/class must extend the class literal passed into GWT.create().
class Selector{
}
#Annotation("string parameter...")
class WithParameter extends Selector{}
Selector instance = GWT.create( WithParameter.class )
Everything is possible..although may be difficult or even useless. As Jan has mentioned you should use a generator to do that. Basically you can create your interface the generator code which takes that interface and compile at creation time and gives you back the instance. An example could be:
//A marker interface
public interface Instantiable {
}
//What you will put in GWT.create
public interface ReflectionService {
public Instantiable newInstance(String className);
}
//gwt.xml, basically when GWT.create finds reflectionservice, use reflection generator
<generate-with class="...ReflectionGenerator" >
<when-type-assignable class="...ReflectionService" />
</generate-with>
//In not a client package
public class ReflectionGenerator extends Generator{
...
}
//A class you may instantiate
public class foo implements Instantiable{
}
//And in this way
ReflectionService service = GWT.create(ReflectionService.class);
service.newInstance("foo");
All you need to know is how to do the generator. I may tell you that at the end what you do in the generator is to create Java code in this fashion:
if ("clase1".equals(className)) return new clase1();
else if ("clase2".equals(className)) return new clase2();
...
At the final I thought, common I can do that by hand in a kind of InstanceFactory...
Best Regards
I was able to do what I think you're trying to do which is load a class and bind it to an event dynamically; I used a Generator to dynamically link the class to the event. I don't recommend it but here's an example if it helps:
http://francisshanahan.com/index.php/2010/a-simple-gwt-generator-example/
Not having looked through the code of rocket/gwittir (which you ought to do if you want to find out how they did it, it is opensource after all), i can only guess that they employ deferred binding in such a way that during compile time, they work out all calls to reflection, and statically generate all the code required to implement those call. So during run-time, you cant do different ones.
What you're trying to do is not possible in GWT.
While GWT does a good job of emulating Java at compile time the runtime is of course completely different. Most reflection is unsupported and it is not possible to generate or dynamically load classes at runtime.
I had a brief look into code for Gwittir and I think they are doing their "reflection stuff" at compile time. Here: http://code.google.com/p/gwittir/source/browse/trunk/gwittir-core/src/main/java/com/totsp/gwittir/rebind/beans/IntrospectorGenerator.java
You might be able to avoid the whole issue by doing it on the server side. Say with a service
witch takes String and returns some sort of a serializable super type.
On the server side you can do
return (MySerializableType)Class.forName("className").newInstance();
Depending on your circumstances it might not be a big performance bottleneck.