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
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
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
174
175
176
177 response.setStatus(200);
178
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
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
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 }