View Javadoc

1   package org.codehaus.xfire.transport.http;
2   
3   import java.io.File;
4   import java.io.IOException;
5   import java.io.InputStream;
6   import java.io.UnsupportedEncodingException;
7   import java.util.Collection;
8   import java.util.Iterator;
9   import java.util.Properties;
10  import javax.mail.MessagingException;
11  import javax.mail.Session;
12  import javax.mail.internet.MimeMessage;
13  import javax.mail.internet.MimeMultipart;
14  import javax.servlet.ServletContext;
15  import javax.servlet.ServletException;
16  import javax.servlet.http.HttpServletRequest;
17  import javax.servlet.http.HttpServletResponse;
18  
19  import org.codehaus.xfire.MessageContext;
20  import org.codehaus.xfire.XFire;
21  import org.codehaus.xfire.XFireRuntimeException;
22  import org.codehaus.xfire.attachments.JavaMailAttachments;
23  import org.codehaus.xfire.service.Service;
24  import org.codehaus.xfire.service.ServiceRegistry;
25  import org.codehaus.xfire.transport.TransportManager;
26  
27  /***
28   * Loads XFire and processes requests.
29   * 
30   * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
31   * @since Feb 13, 2004
32   */
33  public class XFireServletController
34  {
35      private static ThreadLocal requests = new ThreadLocal();
36      private static ThreadLocal responses = new ThreadLocal();
37  
38      private File webInfPath;
39  
40      protected XFire xfire;
41  
42      protected ServletContext context;
43  
44      protected SoapHttpTransport transport;
45      
46      public XFireServletController(XFire xfire, ServletContext context)
47      {
48          this.xfire = xfire;
49          this.context = context;
50          this.transport = new SoapHttpTransport();
51          
52          registerTransport();
53      }
54  
55      protected void registerTransport()
56      {
57          TransportManager service = getTransportManager();
58          service.register(transport);
59      }
60  
61      public static HttpServletRequest getRequest()
62      {
63          return (HttpServletRequest) requests.get();
64      }
65  
66      public static HttpServletResponse getResponse()
67      {
68          return (HttpServletResponse) responses.get();
69      }
70      
71      public File getWebappBase()
72      {
73          if (webInfPath == null)
74          {
75              webInfPath = new File(context.getRealPath("/WEB-INF"));
76          }
77  
78          return webInfPath;
79      }
80  
81      /***
82       * @return
83       */
84      protected TransportManager getTransportManager()
85      {
86          return getXFire().getTransportManager();
87      }
88  
89      /***
90       * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest,
91       *      javax.servlet.http.HttpServletResponse)
92       */
93      public void doService(HttpServletRequest request,
94                            HttpServletResponse response)
95          throws ServletException, IOException
96      {
97          String service = getService(request);
98          ServiceRegistry reg = getServiceRegistry();
99  
100         String wsdl = request.getParameter("wsdl");
101         response.setHeader("Content-Type", "UTF-8");
102 
103         requests.set(request);
104         responses.set(response);
105 
106         if (service == null || service.equals("") || !reg.hasService(service))
107         {
108             generateServices(response);
109             return;
110         }
111 
112         try
113         {
114             if (wsdl != null)
115             {
116                 generateWSDL(response, service);
117             }
118             else
119             {
120                 invoke(request, response, service);
121             }
122         }
123         catch (Exception e)
124         {
125             // TODO Auto-generated catch block
126             e.printStackTrace();
127         }
128     }
129 
130     /***
131      * @param response
132      * @throws IOException
133      * @throws ServletException
134      */
135     protected void generateServices(HttpServletResponse response)
136             throws IOException
137     {
138         response.setContentType("text/html");
139         StringBuffer sb = new StringBuffer();
140         sb.append("<html><head><title>XFire Services</title></head>").append(
141                 "<body>No such service.").append("<p>Services:<ul>.");
142 
143         ServiceRegistry registry = getServiceRegistry();
144         Collection services = registry.getServices();
145 
146         for (Iterator itr = services.iterator(); itr.hasNext();)
147         {
148             Service service = (Service) itr.next();
149             sb.append("<li>").append(service.getName()).append("</li>");
150         }
151         sb.append("</ul></p></body></html>");
152 
153         response.getWriter().write(sb.toString());
154         response.getWriter().flush();
155         // response.getWriter().close();
156 
157         return;
158     }
159 
160     /***
161      * @param request
162      * @param response
163      * @param service
164      * @throws ServletException
165      * @throws IOException
166      * @throws UnsupportedEncodingException
167      */
168     protected void invoke(HttpServletRequest request,
169                           HttpServletResponse response, 
170                           String service)
171         throws ServletException, IOException, UnsupportedEncodingException
172     {
173         // TODO: Return 500 on a fault
174         // TODO: Determine if the request is a soap request
175         // and if not responsed appropriately
176         
177         response.setStatus(200);
178         // response.setBufferSize(1024 * 8);
179         response.setContentType("text/xml; charset=UTF-8");
180 
181         XFireHttpSession session = new XFireHttpSession(request);
182         MessageContext context = 
183             new MessageContext(service, 
184                                null, 
185                                response.getOutputStream(), 
186                                session, 
187                                request.getRequestURI());
188 
189         context.setTransport(transport);
190         
191         String contentType = request.getHeader("Content-Type");
192         if ( null == contentType || contentType.toLowerCase().indexOf("multipart/related") != -1 )
193         {
194             try
195             {
196                 getXFire().invoke(createMIMERequest(request, context), context);
197             }
198             catch (MessagingException e)
199             {
200                 throw new XFireRuntimeException("Couldn't parse request message.", e);
201             }
202         }
203         else
204         {
205             getXFire().invoke(request.getInputStream(), context);
206         }
207     }
208 
209     protected InputStream createMIMERequest(HttpServletRequest request, MessageContext context) 
210     	throws MessagingException, IOException
211     {
212         Session session = Session.getDefaultInstance(new Properties(), null);
213         MimeMessage inMsg = new MimeMessage(session, request.getInputStream());
214         inMsg.addHeaderLine("Content-Type: " + request.getContentType());
215 
216         final Object content = inMsg.getContent();
217 
218         if( content instanceof MimeMultipart )
219         {
220             MimeMultipart inMP = (MimeMultipart) content;
221 
222             JavaMailAttachments atts = new JavaMailAttachments(inMP);
223             context.setProperty(JavaMailAttachments.ATTACHMENTS_KEY, atts);
224 
225             return atts.getSoapMessage().getDataHandler().getInputStream();
226         }
227         else
228         {
229             throw new UnsupportedOperationException( );
230             //TODO set 500 and bail
231         }
232     }
233 
234     /***
235      * @param response
236      * @param service
237      * @throws ServletException
238      * @throws IOException
239      */
240     protected void generateWSDL(HttpServletResponse response, String service)
241             throws ServletException, IOException
242     {
243         response.setStatus(200);
244         response.setContentType("text/xml");
245         // response.setBufferSize(1024 * 8);
246 
247         getXFire().generateWSDL(service, response.getOutputStream());
248     }
249 
250     /***
251      * @param request
252      * @return
253      */
254     protected String getService(HttpServletRequest request)
255     {
256         String pathInfo = request.getPathInfo();
257 
258         if (pathInfo == null)
259             return null;
260 
261         String serviceName;
262 
263         if (pathInfo.startsWith("/"))
264         {
265             serviceName = pathInfo.substring(1);
266         }
267         else
268         {
269             serviceName = pathInfo;
270         }
271 
272         return serviceName;
273     }
274 
275     /***
276      * @return
277      */
278     public XFire getXFire()
279     {
280         return xfire;
281     }
282 
283     public ServiceRegistry getServiceRegistry()
284     {
285         return xfire.getServiceRegistry();
286     }
287 }