Coverage Report - org.mule.transport.ajax.container.MuleAjaxServlet
 
Classes in this File Line Coverage Branch Coverage Complexity
MuleAjaxServlet
0%
0/35
0%
0/10
0
MuleAjaxServlet$MuleContinuationBayeux
0%
0/9
0%
0/2
0
MuleAjaxServlet$MuleMessageImpl
0%
0/14
0%
0/8
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.transport.ajax.container;
 8  
 
 9  
 import org.mule.api.MuleContext;
 10  
 import org.mule.api.MuleException;
 11  
 import org.mule.api.config.MuleProperties;
 12  
 import org.mule.api.transport.Connector;
 13  
 import org.mule.module.json.transformers.ObjectToJson;
 14  
 import org.mule.transport.ajax.BayeuxAware;
 15  
 import org.mule.transport.ajax.i18n.AjaxMessages;
 16  
 import org.mule.transport.service.TransportFactory;
 17  
 import org.mule.transport.servlet.MuleServletContextListener;
 18  
 import org.mule.util.annotation.AnnotationUtils;
 19  
 
 20  
 import java.io.IOException;
 21  
 import java.util.HashSet;
 22  
 import java.util.Set;
 23  
 
 24  
 import javax.servlet.ServletException;
 25  
 import javax.servlet.http.HttpServletRequest;
 26  
 import javax.servlet.http.HttpServletResponse;
 27  
 
 28  
 import org.cometd.Message;
 29  
 import org.mortbay.cometd.AbstractBayeux;
 30  
 import org.mortbay.cometd.MessageImpl;
 31  
 import org.mortbay.cometd.MessagePool;
 32  
 import org.mortbay.cometd.continuation.ContinuationBayeux;
 33  
 import org.mortbay.cometd.continuation.ContinuationCometdServlet;
 34  
 
 35  
 /**
 36  
  * Wraps the {@link ContinuationCometdServlet} servlet and binds the Bayeux object to
 37  
  * the Mule {@link AjaxServletConnector}.
 38  
  */
 39  0
 public class MuleAjaxServlet extends ContinuationCometdServlet
 40  
 {
 41  0
     protected Connector connector = null;
 42  
 
 43  
     private ObjectToJson jsonTransformer;
 44  
 
 45  0
     private Set<Class> ignoreClasses = new HashSet<Class>();
 46  0
     private Set<Class> jsonBindings = new HashSet<Class>();
 47  
 
 48  
     @Override
 49  
     public void init() throws ServletException
 50  
     {
 51  0
         super.init();
 52  0
         MuleContext muleContext = (MuleContext)getServletContext().getAttribute(MuleProperties.MULE_CONTEXT_PROPERTY);
 53  0
         if(muleContext==null)
 54  
         {
 55  0
             throw new ServletException("Attribute " + MuleProperties.MULE_CONTEXT_PROPERTY + " not set on ServletContext");
 56  
         }
 57  0
         String servletConnectorName = getServletConfig().getInitParameter(MuleServletContextListener.CONNECTOR_NAME);
 58  0
         if (servletConnectorName == null)
 59  
         {
 60  0
             servletConnectorName = (String)getServletContext().getAttribute(MuleServletContextListener.CONNECTOR_NAME);
 61  
         }
 62  
         
 63  0
         if (servletConnectorName == null)
 64  
         {
 65  0
             connector = new TransportFactory(muleContext).getConnectorByProtocol(getConnectorProtocol());
 66  0
             if (connector == null)
 67  
             {
 68  0
                 connector = new AjaxServletConnector(muleContext);
 69  0
                 connector.setName("ajax.servlet." + getServletContext().getServerInfo());
 70  
                 try
 71  
                 {
 72  0
                     muleContext.getRegistry().registerConnector(connector);
 73  
                 }
 74  0
                 catch (MuleException e)
 75  
                 {
 76  0
                     throw new ServletException("Failed to register the AjaxServletConnector", e);
 77  0
                 }
 78  
             }
 79  
         }
 80  
         else
 81  
         {
 82  0
             connector = muleContext.getRegistry().lookupConnector(servletConnectorName);
 83  0
             if (connector == null)
 84  
             {
 85  0
                 throw new ServletException(AjaxMessages.noAjaxConnectorWithName(servletConnectorName, MuleServletContextListener.CONNECTOR_NAME).toString());
 86  
             }
 87  
         }
 88  
 
 89  
         try
 90  
         {
 91  0
             ((BayeuxAware)connector).setBayeux(getBayeux());
 92  0
             jsonTransformer = new ObjectToJson();
 93  0
             connector.getMuleContext().getRegistry().applyProcessorsAndLifecycle(jsonTransformer);
 94  
         }
 95  0
         catch (MuleException e)
 96  
         {
 97  0
             throw new ServletException(e);
 98  0
         }
 99  0
     }
 100  
 
 101  
     @Override
 102  
     protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
 103  
     {
 104  0
         super.service(request, response);
 105  0
     }
 106  
 
 107  
     protected String getConnectorProtocol()
 108  
     {
 109  0
         return AjaxServletConnector.PROTOCOL;
 110  
     }
 111  
 
 112  
     @Override
 113  
     protected AbstractBayeux newBayeux()
 114  
     {
 115  0
         return new MuleContinuationBayeux();
 116  
     }
 117  
 
 118  
     /**
 119  
      * We subclass the {@link org.mortbay.cometd.continuation.ContinuationBayeux} so tat we can insert a different
 120  
      * message implementation that allows us to have better control over the message going across the wire. Right now this
 121  
      * means that we use Jackson for Json serialization.
 122  
      */
 123  0
     protected class MuleContinuationBayeux extends ContinuationBayeux
 124  
     {
 125  
         @Override
 126  
         public MessageImpl newMessage()
 127  
         {
 128  
             //TODO no access to the message pool, need to have a fork of ContinuationBayeux to mimic exact behaviour
 129  
             MessageImpl message;//_messagePool.poll();
 130  
 //            if (message == null)
 131  
 //            {
 132  0
                 message=new MuleMessageImpl(this);
 133  
            // }
 134  0
             message.incRef();
 135  0
             return message;
 136  
         }
 137  
 
 138  
         @Override
 139  
         public MessageImpl newMessage(Message associated)
 140  
         {
 141  
             //TODO no access to the message pool, need to have a fork of ContinuationBayeux to mimic exact behaviour
 142  
             MessageImpl message;//_messagePool.poll();
 143  
 //            if (message == null)
 144  
 //            {
 145  0
                 message=new MuleMessageImpl(this);
 146  
             //}
 147  0
             message.incRef();
 148  0
             if (associated != null)
 149  0
                 message.setAssociated(associated);
 150  0
             return message;
 151  
         }
 152  
     }
 153  
 
 154  
 
 155  0
     public class MuleMessageImpl extends MessageImpl
 156  
     {
 157  
         public MuleMessageImpl(MessagePool bayeux)
 158  0
         {
 159  0
             super(bayeux);
 160  0
         }
 161  
 
 162  
         @Override
 163  
         public String getJSON()
 164  
         {
 165  0
             Object data = getData();
 166  
             try
 167  
             {
 168  0
                 if(data!=null && !ignoreClasses.contains(data.getClass()))
 169  
                 {
 170  0
                     if(jsonBindings.contains(data.getClass()))
 171  
                     {
 172  0
                         return (String) jsonTransformer.transform(this);
 173  
                     }
 174  0
                     else if(AnnotationUtils.hasAnnotationWithPackage("org.codehaus.jackson", data.getClass()))
 175  
                     {
 176  
                         //Tell the transformer to accept this type next time
 177  0
                         jsonBindings.add(data.getClass());
 178  0
                         return (String) jsonTransformer.transform(this);
 179  
                     }
 180  
                     else
 181  
                     {
 182  
                         //We can ignore objects of this type and delegate to the super class
 183  0
                         ignoreClasses.add(data.getClass());
 184  
                     }
 185  
                 }
 186  0
                 return super.getJSON();
 187  
             }
 188  0
             catch (Exception e)
 189  
             {
 190  0
                 throw new RuntimeException("Failed to convert message to JSON", e);
 191  
 
 192  
             }
 193  
         }
 194  
     }
 195  
 
 196  
 }