1
2
3
4
5
6
7
8
9
10
11 package org.mule.construct;
12
13 import org.mule.MessageExchangePattern;
14 import org.mule.api.MuleContext;
15 import org.mule.api.MuleException;
16 import org.mule.api.MuleRuntimeException;
17 import org.mule.api.component.Component;
18 import org.mule.api.component.JavaComponent;
19 import org.mule.api.construct.FlowConstructInvalidException;
20 import org.mule.api.context.MuleContextAware;
21 import org.mule.api.endpoint.InboundEndpoint;
22 import org.mule.api.processor.MessageProcessor;
23 import org.mule.api.processor.MessageProcessorBuilder;
24 import org.mule.api.processor.MessageProcessorChainBuilder;
25 import org.mule.api.source.MessageSource;
26 import org.mule.config.i18n.MessageFactory;
27 import org.mule.util.ClassUtils;
28
29 import java.lang.reflect.Method;
30 import java.util.Collections;
31 import java.util.List;
32
33
34
35
36 public class SimpleService extends AbstractConfigurationPattern
37 {
38 public enum Type
39 {
40
41
42
43 JAX_WS
44 {
45 @Override
46 public void validate(Component component) throws FlowConstructInvalidException
47 {
48 if (!(component instanceof JavaComponent))
49 {
50 throw new FlowConstructInvalidException(
51 MessageFactory.createStaticMessage("SimpleService can only expose instances of JAX-WS annotated JavaComponent instances. You provided a: "
52 + component.getClass().getName()));
53 }
54 }
55
56 @Override
57 public void configureComponentMessageProcessor(MuleContext muleContext,
58 MessageProcessorChainBuilder builder,
59 Component component)
60 {
61 builder.chain(newJaxWsComponentMessageProcessor(muleContext, getComponentClass(component)));
62 builder.chain(component);
63 }
64 },
65
66
67
68
69 JAX_RS
70 {
71 @Override
72 public void validate(Component component) throws FlowConstructInvalidException
73 {
74 if (!(component instanceof JavaComponent))
75 {
76 throw new FlowConstructInvalidException(
77 MessageFactory.createStaticMessage("SimpleService can only expose instances of JAX-RS annotated JavaComponent instances. You provided a: "
78 + component.getClass().getName()));
79 }
80 }
81
82 @Override
83 public void configureComponentMessageProcessor(MuleContext muleContext,
84 MessageProcessorChainBuilder builder,
85 Component component)
86 {
87 builder.chain(newJaxRsComponentWrapper(muleContext, component));
88 }
89 },
90
91
92
93
94 DIRECT
95 {
96 @Override
97 public void validate(Component component) throws FlowConstructInvalidException
98 {
99
100 }
101
102 @Override
103 public void configureComponentMessageProcessor(MuleContext muleContext,
104 MessageProcessorChainBuilder builder,
105 Component component)
106 {
107 builder.chain(component);
108 }
109 };
110
111 public abstract void validate(Component component) throws FlowConstructInvalidException;
112
113 public abstract void configureComponentMessageProcessor(MuleContext muleContext,
114 MessageProcessorChainBuilder builder,
115 Component component);
116
117 public static Type fromString(String string)
118 {
119 String mepString = string.toUpperCase().replace('-', '_');
120 return Type.valueOf(mepString);
121 }
122 }
123
124 private final Component component;
125 private final Type type;
126
127 public SimpleService(String name,
128 MuleContext muleContext,
129 MessageSource messageSource,
130 List<MessageProcessor> transformers,
131 List<MessageProcessor> responseTransformers,
132 Component component,
133 Type type) throws MuleException
134 {
135 super(name, muleContext, transformers, responseTransformers);
136
137 if (messageSource == null)
138 {
139 throw new FlowConstructInvalidException(
140 MessageFactory.createStaticMessage("messageSource can't be null on: " + this.toString()));
141 }
142
143 if (component == null)
144 {
145 throw new FlowConstructInvalidException(
146 MessageFactory.createStaticMessage("component can't be null on: " + this.toString()));
147 }
148
149 if (type == null)
150 {
151 throw new FlowConstructInvalidException(
152 MessageFactory.createStaticMessage("type can't be null on: " + this.toString()));
153 }
154
155 this.messageSource = messageSource;
156 this.component = component;
157 this.type = type;
158 }
159
160 public Component getComponent()
161 {
162 return component;
163 }
164
165 @Override
166 protected void configureMessageProcessorsBeforeTransformation(MessageProcessorChainBuilder builder)
167 {
168
169 }
170
171 @Override
172 protected void configureMessageProcessorsAfterTransformation(MessageProcessorChainBuilder builder)
173 {
174 type.configureComponentMessageProcessor(muleContext, builder, component);
175 }
176
177 @Override
178 protected void validateConstruct() throws FlowConstructInvalidException
179 {
180 super.validateConstruct();
181
182 if ((messageSource instanceof InboundEndpoint)
183 && (!((InboundEndpoint) messageSource).getExchangePattern().equals(
184 MessageExchangePattern.REQUEST_RESPONSE)))
185 {
186 throw new FlowConstructInvalidException(
187 MessageFactory.createStaticMessage("SimpleService only works with a request-response inbound endpoint."),
188 this);
189 }
190
191 type.validate(component);
192 }
193
194 private static Class<?> getComponentClass(Component component)
195 {
196 if (component instanceof JavaComponent)
197 {
198 return ((JavaComponent) component).getObjectFactory().getObjectClass();
199 }
200
201 return component.getClass();
202 }
203
204 private static MessageProcessor newJaxWsComponentMessageProcessor(MuleContext muleContext,
205 Class<?> componentClass)
206 {
207 try
208 {
209 MessageProcessorBuilder wsmpb = (MessageProcessorBuilder) ClassUtils.instanciateClass("org.mule.module.cxf.builder.WebServiceMessageProcessorBuilder");
210
211 Method setServiceClassMethod = ClassUtils.getMethod(wsmpb.getClass(), "setServiceClass",
212 new Class<?>[]{Class.class});
213
214 setServiceClassMethod.invoke(wsmpb, componentClass);
215
216 Method setFrontendMethod = ClassUtils.getMethod(wsmpb.getClass(), "setFrontend",
217 new Class<?>[]{String.class});
218
219 setFrontendMethod.invoke(wsmpb, "jaxws");
220
221 ((MuleContextAware) wsmpb).setMuleContext(muleContext);
222
223 return wsmpb.build();
224 }
225 catch (Exception e)
226 {
227 throw new MuleRuntimeException(
228 MessageFactory.createStaticMessage("Failed to configure the required web service infrastructure: are you missing the Mule CXF Module?"),
229 e);
230 }
231 }
232
233 private static Component newJaxRsComponentWrapper(MuleContext muleContext, Component component)
234 {
235 try
236 {
237 Component jrc = (Component) ClassUtils.instanciateClass("org.mule.module.jersey.JerseyResourcesComponent");
238
239 Method setComponentsMethod = ClassUtils.getMethod(jrc.getClass(), "setComponents",
240 new Class<?>[]{List.class});
241
242 setComponentsMethod.invoke(jrc, Collections.singletonList(component));
243
244 ((MuleContextAware) jrc).setMuleContext(muleContext);
245
246 return jrc;
247 }
248 catch (Exception e)
249 {
250 throw new MuleRuntimeException(
251 MessageFactory.createStaticMessage("Failed to configure the required web service infrastructure: are you missing the Mule Jersey Module?"),
252 e);
253 }
254 }
255
256 @Override
257 public String getConstructType()
258 {
259 return "Simple-Service";
260 }
261 }