Thanks!
Paul.
On Aug 17, 2009, at 7:35 PM, Gabriel Klein @ Poken wrote:
> At poken, we use jaxb to generate java classes for xsd.
>
> I have coded a @Provider
>
> This code is
> - incomplete: Many cases are missing. (Like get functions with
> annotations).
> - totally free to use: Do what you want with it.
> - Not really tested but it works great for us.
> - Works with jersey 1.1.2, doesn't work with jersey 1.1.1, not
> tested on other versions.
> - Based on annotation in Java domain objects
>
> Check in you logs that you have something similar to
> INFO: Provider classes found:
> class
> ch.poken.api.rest.v081.resources.server.JAXBFixJSONArrayProvider
>
> --
>
> package ch.poken.api.rest.v081.resources.server;
>
> import java.lang.annotation.Annotation;
> import java.lang.reflect.Field;
> import java.lang.reflect.InvocationTargetException;
> import java.lang.reflect.Method;
> import java.lang.reflect.ParameterizedType;
> import java.lang.reflect.Type;
> import java.util.Collections;
> import java.util.HashMap;
> import java.util.List;
> import java.util.Map;
>
> import javax.ws.rs.ext.ContextResolver;
> import javax.ws.rs.ext.Provider;
> import javax.xml.bind.JAXBContext;
> import javax.xml.bind.annotation.XmlElement;
>
> import org.slf4j.Logger;
> import org.slf4j.LoggerFactory;
>
> import com.sun.jersey.api.json.JSONConfiguration;
> import com.sun.jersey.api.json.JSONJAXBContext;
>
> @Provider
> public class JAXBFixJSONArrayProvider implements
> ContextResolver<JAXBContext> {
>
> // Logs
> static final Logger logger = LoggerFactory
> .getLogger(JAXBContextResolver.class);
>
> /**
> * This map store all jaxb context once processed by the parser.
> */
> private static Map<Class<? extends Object>, JAXBContext>
> jaxbContexts = Collections
> .synchronizedMap(new HashMap<Class<? extends Object>, JAXBContext>());
>
> /**
> * Get the jaxb context, generate this context if it doesn't exists
> yet.
> *
> * @param the
> * class used to generate the JAXB context
> * @return JAXB context
> * @throws InvocationTargetException
> * @throws IllegalAccessException
> * @throws NoSuchMethodException
> * @throws IllegalArgumentException
> * @throws SecurityException
> */
> private static JAXBContext getJAXBContext(Class<? extends Object>
> class1)
> throws Exception {
>
> // Get from cache
> JAXBContext context = jaxbContexts.get(class1);
> if (context != null) {
> return context;
> }
>
> // Parse all jaxb nodes
> Map<Class<? extends Object>, Object> mapClassIterated = new
> HashMap<Class<? extends Object>, Object>();
> Map<String, Object> mapFieldsList = new HashMap<String, Object>();
>
> parseJAXBContext(class1, mapClassIterated, mapFieldsList);
> String[] fields = mapFieldsList.keySet().toArray(new String[0]);
>
> // Create the JAXB Context
> context = new JSONJAXBContext(JSONConfiguration.mapped()
> .rootUnwrapping(true).arrays(fields).build(), class1);
>
> // Add this context to cache.
> jaxbContexts.put(class1, context);
> return context;
> }
>
> /**
> * Parse a jaxb context, add the element in mapFields.
> *
> * @param class1
> * is the name of the class to be parser
> * @param mapClassIterated
> * is the map of iterated classes
> * @param mapFieldsList
> * is the map of fields that have been extracted
> * @throws NoSuchMethodException
> * @throws SecurityException
> * @throws InvocationTargetException
> * @throws IllegalAccessException
> * @throws IllegalArgumentException
> */
> private static void parseJAXBContext(Class<? extends Object> class1,
> Map<Class<? extends Object>, Object> mapClassIterated,
> Map<String, Object> mapFieldsList) throws SecurityException,
> NoSuchMethodException, IllegalArgumentException,
> IllegalAccessException, InvocationTargetException {
>
> // We have already processed this class
> if (mapClassIterated.containsKey(class1)) {
> return;
> }
>
> mapClassIterated.put(class1, Boolean.TRUE);
>
> // Extract from parameters
> for (Field f : class1.getDeclaredFields()) {
>
> Annotation a = f.getAnnotation(XmlElement.class);
> String name = null;
>
> if (a != null) {
> Method m = a.getClass().getMethod("name");
> name = (String) m.invoke(a);
> }
>
> if (name == null || "##default".equals(name)) {
> name = f.getName();
> }
>
> {
> // Is it a list
> if (f.getType() == List.class) {
> mapFieldsList.put(name, Boolean.TRUE);
> ParameterizedType aType = (ParameterizedType) f
> .getGenericType();
> Type[] fieldArgTypes = aType.getActualTypeArguments();
> for (Type fieldArgType : fieldArgTypes) {
> parseJAXBContext((Class<?>) fieldArgType,
> mapClassIterated, mapFieldsList);
> }
> } else {
> parseJAXBContext(f.getType(), mapClassIterated,
> mapFieldsList);
> }
>
> }
> }
>
> // TODO: Extract from methods
> // for (Method m : class1.getMethods()) {
> // }
>
> }
>
> /**
> * Get the JAXB context
> */
> public JAXBContext getContext(Class<?> objectType) {
> try {
> return getJAXBContext(objectType);
> } catch (Throwable t) {
> throw new RuntimeException(t);
> }
> }
>
> }
>
>
>
> ###**###**###**###**###**###**###**###**###
>
> Gabriel Klein
> CSA / Poken SA
>
> Please Poken with me for more information.