1
2
3
4
5
6
7
8
9
10
11 package org.mule.module.jersey;
12
13 import org.mule.api.MuleEvent;
14 import org.mule.api.MuleMessage;
15 import org.mule.api.component.JavaComponent;
16 import org.mule.api.endpoint.EndpointURI;
17 import org.mule.api.lifecycle.InitialisationException;
18 import org.mule.api.processor.MessageProcessor;
19 import org.mule.api.transformer.TransformerException;
20 import org.mule.component.AbstractComponent;
21 import org.mule.transport.http.HttpConnector;
22
23 import com.sun.jersey.api.core.DefaultResourceConfig;
24 import com.sun.jersey.core.header.InBoundHeaders;
25 import com.sun.jersey.core.spi.component.ioc.IoCComponentProviderFactory;
26 import com.sun.jersey.spi.container.ContainerRequest;
27 import com.sun.jersey.spi.container.ContainerResponse;
28 import com.sun.jersey.spi.container.WebApplication;
29 import com.sun.jersey.spi.container.WebApplicationFactory;
30
31 import java.io.InputStream;
32 import java.net.URI;
33 import java.net.URISyntaxException;
34 import java.util.ArrayList;
35 import java.util.HashSet;
36 import java.util.List;
37 import java.util.Set;
38
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41
42
43
44
45
46
47 public class JerseyResourcesComponent extends AbstractComponent
48 {
49 public static String JERSEY_RESPONSE = "jersey_response";
50
51 protected final Log logger = LogFactory.getLog(this.getClass());
52
53 private List<JavaComponent> components;
54
55 private WebApplication application;
56
57 @Override
58 protected void doInitialise() throws InitialisationException
59 {
60 super.doInitialise();
61
62 final Set<Class<?>> resources = new HashSet<Class<?>>();
63
64 if (components == null)
65 {
66 throw new IllegalStateException("There must be at least one component in the Jersey resources.");
67 }
68
69
70 for (JavaComponent component : components)
71 {
72 Class<?> c;
73 try
74 {
75 c = component.getObjectType();
76 resources.add(c);
77 }
78 catch (Exception e)
79 {
80 throw new InitialisationException(e, this);
81 }
82 }
83
84 DefaultResourceConfig resourceConfig = createConfiguration(resources);
85
86 application = WebApplicationFactory.createWebApplication();
87 application.initiate(resourceConfig, getComponentProvider());
88 }
89
90 protected DefaultResourceConfig createConfiguration(final Set<Class<?>> resources)
91 {
92 return new DefaultResourceConfig(resources);
93 }
94
95 @Override
96 protected Object doInvoke(MuleEvent event) throws Exception
97 {
98 MuleMessage message = event.getMessage();
99
100 String path = (String) message.getInboundProperty(HttpConnector.HTTP_REQUEST_PROPERTY);
101 String contextPath = (String) message.getInboundProperty(HttpConnector.HTTP_CONTEXT_PATH_PROPERTY);
102 String query = null;
103 int queryIdx = path.indexOf('?');
104 if (queryIdx != -1)
105 {
106 query = path.substring(queryIdx + 1);
107 path = path.substring(0, queryIdx);
108 }
109
110 EndpointURI endpointUri = event.getEndpoint().getEndpointURI();
111 String host = message.getInboundProperty("Host", endpointUri.getHost());
112 String method = message.getInboundProperty(HttpConnector.HTTP_METHOD_PROPERTY);
113 InBoundHeaders headers = new InBoundHeaders();
114 for (Object prop : message.getInboundPropertyNames())
115 {
116 Object property = message.getInboundProperty(prop.toString());
117 if (property != null)
118 {
119 headers.add(prop.toString(), property.toString());
120 }
121 }
122
123 String scheme;
124 if ("servlet".equals(endpointUri.getScheme()))
125 {
126 scheme = "http";
127 }
128 else
129 {
130 scheme = endpointUri.getScheme();
131 }
132
133 URI baseUri = getBaseUri(endpointUri, scheme, host, contextPath);
134 URI completeUri = getCompleteUri(endpointUri, scheme, host, path, query);
135 ContainerRequest req = new ContainerRequest(application, method, baseUri, completeUri, headers,
136 getInputStream(message));
137 if (logger.isDebugEnabled())
138 {
139 logger.debug("Base URI: " + baseUri);
140 logger.debug("Complete URI: " + completeUri);
141 }
142
143 MuleResponseWriter writer = new MuleResponseWriter(message);
144 ContainerResponse res = new ContainerResponse(application, req, writer);
145
146 application.handleRequest(req, res);
147
148 return writer.getResponse();
149 }
150
151 protected static InputStream getInputStream(MuleMessage message) throws TransformerException
152 {
153 return message.getPayload(InputStream.class);
154 }
155
156 protected IoCComponentProviderFactory getComponentProvider()
157 {
158 return new MuleComponentProviderFactory(muleContext, components);
159 }
160
161 protected static URI getCompleteUri(EndpointURI endpointUri,
162 String scheme,
163 String host,
164 String path,
165 String query) throws URISyntaxException
166 {
167 String uri = scheme + "://" + host + path;
168 if (query != null)
169 {
170 uri += "?" + query;
171 }
172
173 return new URI(uri);
174 }
175
176 protected static URI getBaseUri(EndpointURI endpointUri, String scheme, String host, String contextPath)
177 throws URISyntaxException
178 {
179 if (!contextPath.endsWith("/"))
180 {
181 contextPath += "/";
182 }
183
184 return new URI(scheme + "://" + host + contextPath);
185 }
186
187 public List<JavaComponent> getComponents()
188 {
189 return components;
190 }
191
192 public void setComponents(List<JavaComponent> components)
193 {
194 this.components = components;
195 }
196
197 public void setMessageProcessors(List<MessageProcessor> messageProcessors)
198 {
199 List<JavaComponent> components = new ArrayList<JavaComponent>();
200 for (MessageProcessor mp : messageProcessors)
201 {
202 if (mp instanceof JavaComponent)
203 {
204 components.add((JavaComponent)mp);
205 }
206 else
207 {
208 throw new IllegalStateException("Only JavaComponents are allowed as MessageProcessors. Type " + mp.getClass().getName() + " is not allowed.");
209 }
210 }
211 setComponents(components);
212 }
213 }