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