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