Coverage Report - org.mule.module.json.transformers.JsonTransformerResolver
 
Classes in this File Line Coverage Branch Coverage Complexity
JsonTransformerResolver
0%
0/51
0%
0/16
0
 
 1  
 /*
 2  
  * $Id: JsonTransformerResolver.java 19715 2010-09-24 15:08:06Z dirk.olmes $
 3  
  * -------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 package org.mule.module.json.transformers;
 11  
 
 12  
 import org.mule.api.MuleContext;
 13  
 import org.mule.api.context.MuleContextAware;
 14  
 import org.mule.api.lifecycle.Disposable;
 15  
 import org.mule.api.registry.RegistrationException;
 16  
 import org.mule.api.registry.ResolverException;
 17  
 import org.mule.api.registry.TransformerResolver;
 18  
 import org.mule.api.transformer.DataType;
 19  
 import org.mule.api.transformer.Transformer;
 20  
 import org.mule.config.i18n.CoreMessages;
 21  
 import org.mule.transformer.simple.ObjectToString;
 22  
 
 23  
 import java.util.List;
 24  
 import java.util.Map;
 25  
 import java.util.WeakHashMap;
 26  
 
 27  
 import org.apache.commons.logging.Log;
 28  
 import org.apache.commons.logging.LogFactory;
 29  
 import org.codehaus.jackson.map.ObjectMapper;
 30  
 
 31  
 /**
 32  
  * A {@link org.mule.api.registry.TransformerResolver} implementation used to discover whether the current transform
 33  
  * requests requires Json mashaling. The resolver will scan the source and return type for Jackson (http://jackson.codehaus.org) Json annotations and will configure
 34  
  * a JSON transformer accordingly.  The transformer is cached and will be used for any subsequent requests.
 35  
  *
 36  
  * The {@link org.codehaus.jackson.map.ObjectMapper} instance needed for the transform can be discovered from the registry, this means one can be
 37  
  * pre-configured in Spring or Guice.  If there is no pre-configured {@link org.codehaus.jackson.map.ObjectMapper} one will be created with the
 38  
  * annotated JSON class.  This context will cached with the transformer.
 39  
  *
 40  
  * @since 3.0
 41  
  */
 42  0
 public class JsonTransformerResolver implements TransformerResolver, MuleContextAware, Disposable
 43  
 {
 44  
     public static final String JSON_MIME_TYPE = "application/json";
 45  
     /**
 46  
      * logger used by this class
 47  
      */
 48  0
     protected transient final Log logger = LogFactory.getLog(JsonTransformerResolver.class);
 49  
     
 50  
     private MuleContext muleContext;
 51  
 
 52  
     //We cache the the transformers, this will get cleared when the server shuts down
 53  0
     private Map<String, Transformer> transformerCache = new WeakHashMap<String, Transformer>();
 54  
 
 55  
     private JsonMapperResolver resolver;
 56  
 
 57  
     public void setMuleContext(MuleContext context)
 58  
     {
 59  0
         muleContext = context;
 60  0
     }
 61  
 
 62  
     public Transformer resolve(DataType<?> source, DataType<?> result) throws ResolverException
 63  
     {
 64  
         //Check the cache
 65  0
         Transformer t = transformerCache.get(source.toString() + result.toString());
 66  
 
 67  0
         if (t != null)
 68  
         {
 69  0
             return t;
 70  
         }
 71  
 
 72  
         try
 73  
         {
 74  0
             ObjectMapper mapper = getMapperResolver().resolve(ObjectMapper.class, source, result, muleContext);
 75  
 
 76  0
             if(mapper==null)
 77  
             {
 78  0
                 return null;
 79  
             }
 80  
             boolean marshal;
 81  
             Class<?> annotatedType;
 82  
 
 83  
             //Check the class caches before we start scanning classes
 84  0
             if (getMapperResolver().getMatchingClasses().contains(result.getType()))
 85  
             {
 86  0
                 annotatedType = result.getType();
 87  
                 //Set the correct mime type on the raw type
 88  0
                 source = source.cloneDataType();
 89  0
                 source.setMimeType(JSON_MIME_TYPE);
 90  0
                 marshal = false;
 91  
             }
 92  0
             else if (getMapperResolver().getMatchingClasses().contains(source.getType()))
 93  
             {
 94  0
                 annotatedType = source.getType();
 95  
                 //Set the correct mime type on the raw type
 96  0
                 result = result.cloneDataType();
 97  0
                 result.setMimeType(JSON_MIME_TYPE);
 98  0
                 marshal = true;
 99  
             }
 100  
             else
 101  
             {
 102  0
                 return null;
 103  
             }
 104  
 
 105  
 
 106  
             //At this point we know we are dealing with Json, now lets check the registry to see if there is an exact
 107  
             //transformer that matches our criteria
 108  0
             List<Transformer> ts = muleContext.getRegistry().lookupTransformers(source, result);
 109  
             //ObjectToString continues to cause pain to auto transforms, here
 110  
             //we check explicitly since we want to generate a Json transformer if
 111  
             //one does not already exist in the context
 112  0
             if (ts.size() == 1 && !(ts.get(0) instanceof ObjectToString))
 113  
             {
 114  0
                 t = ts.get(0);
 115  
             }
 116  0
             else if (marshal)
 117  
             {
 118  0
                 ObjectToJson otj = new ObjectToJson();
 119  0
                 otj.setSourceClass(annotatedType);
 120  0
                 otj.setReturnDataType(result);
 121  0
                 otj.setMapper(mapper);
 122  0
                 muleContext.getRegistry().applyProcessorsAndLifecycle(otj);
 123  0
                 t = otj;
 124  0
             }
 125  
             else
 126  
             {
 127  0
                 JsonToObject jto = new JsonToObject();
 128  0
                 jto.setReturnDataType(result);
 129  0
                 jto.setMapper(mapper);
 130  0
                 muleContext.getRegistry().applyProcessorsAndLifecycle(jto);
 131  0
                 t = jto;
 132  
             }
 133  
 
 134  0
             transformerCache.put(source.toString() + result.toString(), t);
 135  0
             return t;
 136  
 
 137  
         }
 138  0
         catch (Exception e)
 139  
         {
 140  0
             throw new ResolverException(CoreMessages.createStaticMessage("Failed to unmarshal"), e);
 141  
         }
 142  
     }
 143  
 
 144  
     public void transformerChange(Transformer transformer, RegistryAction registryAction)
 145  
     {
 146  
         //nothing to do
 147  0
     }
 148  
 
 149  
     public void dispose()
 150  
     {
 151  0
         transformerCache.clear();
 152  0
     }
 153  
 
 154  
     protected JsonMapperResolver getMapperResolver() throws ResolverException
 155  
     {
 156  0
         if(resolver==null)
 157  
         {
 158  
             try
 159  
             {
 160  0
                 resolver = muleContext.getRegistry().lookupObject(JsonMapperResolver.class);
 161  
             }
 162  0
             catch (RegistrationException e)
 163  
             {
 164  0
                 throw new ResolverException(e.getI18nMessage(), e);
 165  0
             }
 166  
         }
 167  0
         return resolver;
 168  
     }
 169  
 }