1
2
3
4
5
6
7
8
9
10
11 package org.mule.endpoint;
12
13 import org.mule.MessageExchangePattern;
14 import org.mule.api.MuleContext;
15 import org.mule.api.MuleException;
16 import org.mule.api.construct.FlowConstruct;
17 import org.mule.api.endpoint.EndpointMessageProcessorChainFactory;
18 import org.mule.api.endpoint.EndpointURI;
19 import org.mule.api.endpoint.ImmutableEndpoint;
20 import org.mule.api.lifecycle.Disposable;
21 import org.mule.api.processor.MessageProcessor;
22 import org.mule.api.retry.RetryPolicyTemplate;
23 import org.mule.api.routing.filter.Filter;
24 import org.mule.api.security.EndpointSecurityFilter;
25 import org.mule.api.transaction.TransactionConfig;
26 import org.mule.api.transformer.Transformer;
27 import org.mule.api.transport.Connector;
28 import org.mule.processor.SecurityFilterMessageProcessor;
29 import org.mule.routing.MessageFilter;
30 import org.mule.util.ClassUtils;
31
32 import java.net.URI;
33 import java.util.HashMap;
34 import java.util.LinkedList;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.regex.Matcher;
38 import java.util.regex.Pattern;
39
40 import edu.emory.mathcs.backport.java.util.Collections;
41 import org.apache.commons.logging.Log;
42 import org.apache.commons.logging.LogFactory;
43
44
45
46
47
48 public abstract class AbstractEndpoint implements ImmutableEndpoint, Disposable
49 {
50
51 private static final long serialVersionUID = -1650380871293160973L;
52
53
54
55
56 protected static final Log logger = LogFactory.getLog(AbstractEndpoint.class);
57
58
59
60
61 private final Connector connector;
62
63
64
65
66 private final EndpointURI endpointUri;
67
68 private final EndpointMessageProcessorChainFactory messageProcessorsFactory;
69
70 private final List <MessageProcessor> messageProcessors;
71
72 private final List <MessageProcessor> responseMessageProcessors;
73
74 private MessageProcessor messageProcessorChain;
75
76
77
78
79 private final String name;
80
81
82
83
84
85
86 private Map properties = new HashMap();
87
88
89
90
91 private final TransactionConfig transactionConfig;
92
93
94
95
96
97
98 private final boolean deleteUnacceptedMessages;
99
100 private final MessageExchangePattern messageExchangePattern;
101
102
103
104
105
106
107 private final int responseTimeout;
108
109
110
111
112 private final String initialState;
113
114 private final String endpointEncoding;
115
116 private MuleContext muleContext;
117
118 protected RetryPolicyTemplate retryPolicyTemplate;
119
120 private String endpointBuilderName;
121
122 private final String endpointMimeType;
123
124 private boolean disableTransportTransformer = false;
125
126 public AbstractEndpoint(Connector connector,
127 EndpointURI endpointUri,
128 String name,
129 Map properties,
130 TransactionConfig transactionConfig,
131 boolean deleteUnacceptedMessages,
132 MessageExchangePattern messageExchangePattern,
133 int responseTimeout,
134 String initialState,
135 String endpointEncoding,
136 String endpointBuilderName,
137 MuleContext muleContext,
138 RetryPolicyTemplate retryPolicyTemplate,
139 EndpointMessageProcessorChainFactory messageProcessorsFactory,
140 List <MessageProcessor> messageProcessors,
141 List <MessageProcessor> responseMessageProcessors,
142 boolean disableTransportTransformer,
143 String endpointMimeType)
144 {
145 this.connector = connector;
146 this.endpointUri = endpointUri;
147 this.name = name;
148
149
150 this.properties.putAll(properties);
151 this.transactionConfig = transactionConfig;
152 this.deleteUnacceptedMessages = deleteUnacceptedMessages;
153
154 this.responseTimeout = responseTimeout;
155 this.initialState = initialState;
156 this.endpointEncoding = endpointEncoding;
157 this.endpointBuilderName = endpointBuilderName;
158 this.muleContext = muleContext;
159 this.retryPolicyTemplate = retryPolicyTemplate;
160 this.endpointMimeType = endpointMimeType;
161 this.disableTransportTransformer = disableTransportTransformer;
162
163 if (transactionConfig != null && transactionConfig.getFactory() != null &&
164 transactionConfig.getAction() != TransactionConfig.ACTION_NONE &&
165 transactionConfig.getAction() != TransactionConfig.ACTION_NEVER)
166 {
167 if (logger.isDebugEnabled())
168 {
169 logger.debug("Endpoint has a transaction configuration. Defaulting to REQUEST_RESPONSE. Endpoint is: " + toString());
170 }
171 this.messageExchangePattern = MessageExchangePattern.REQUEST_RESPONSE;
172 }
173 else
174 {
175 this.messageExchangePattern = messageExchangePattern;
176 }
177
178 this.messageProcessorsFactory = messageProcessorsFactory;
179 if (messageProcessors == null)
180 {
181 this.messageProcessors = Collections.emptyList();
182 }
183 else
184 {
185 this.messageProcessors = messageProcessors;
186 }
187 if (responseMessageProcessors == null)
188 {
189 this.responseMessageProcessors = Collections.emptyList();
190 }
191 else
192 {
193 this.responseMessageProcessors = responseMessageProcessors;
194 }
195 }
196
197 public EndpointURI getEndpointURI()
198 {
199 return endpointUri;
200 }
201
202 public String getAddress()
203 {
204 EndpointURI uri = getEndpointURI();
205 if (uri != null)
206 {
207 return uri.getUri().toString();
208 }
209 else
210 {
211 return null;
212 }
213 }
214
215 public String getEncoding()
216 {
217 return endpointEncoding;
218 }
219
220 public String getMimeType()
221 {
222 return endpointMimeType;
223 }
224
225 public Connector getConnector()
226 {
227 return connector;
228 }
229
230 public String getName()
231 {
232 return name;
233 }
234
235 public EndpointMessageProcessorChainFactory getMessageProcessorsFactory()
236 {
237 return messageProcessorsFactory;
238 }
239
240 public List <MessageProcessor> getMessageProcessors()
241 {
242 return messageProcessors;
243 }
244
245 public List <MessageProcessor> getResponseMessageProcessors()
246 {
247 return responseMessageProcessors;
248 }
249
250
251 public List<Transformer> getTransformers()
252 {
253 List transformers = new LinkedList();
254 for (MessageProcessor processor : messageProcessors)
255 {
256 if (processor instanceof Transformer)
257 {
258 transformers.add(processor);
259 }
260 }
261 return transformers;
262 }
263
264 public Map getProperties()
265 {
266 return properties;
267 }
268
269 public boolean isReadOnly()
270 {
271 return true;
272 }
273
274 @Override
275 public String toString()
276 {
277
278
279 String sanitizedEndPointUri = null;
280 URI uri = null;
281 if (endpointUri != null)
282 {
283 sanitizedEndPointUri = endpointUri.toString();
284 uri = endpointUri.getUri();
285 }
286
287
288
289 if (uri != null && (uri.getRawUserInfo() != null) && (uri.getScheme() != null) && (uri.getHost() != null)
290 && (uri.getRawPath() != null))
291 {
292
293 Pattern sanitizerPattern = Pattern.compile("(.*):.*");
294 Matcher sanitizerMatcher = sanitizerPattern.matcher(uri.getRawUserInfo());
295 if (sanitizerMatcher.matches())
296 {
297 sanitizedEndPointUri = new StringBuffer(uri.getScheme()).append("://")
298 .append(sanitizerMatcher.group(1))
299 .append(":<password>")
300 .append("@")
301 .append(uri.getHost())
302 .append(uri.getRawPath())
303 .toString();
304 }
305 if (uri.getRawQuery() != null)
306 {
307 sanitizedEndPointUri = sanitizedEndPointUri + "?" + uri.getRawQuery();
308 }
309
310 }
311
312 return ClassUtils.getClassName(getClass()) + "{endpointUri=" + sanitizedEndPointUri + ", connector="
313 + connector + ", name='" + name + "', mep=" + messageExchangePattern + ", properties=" + properties
314 + ", transactionConfig=" + transactionConfig + ", deleteUnacceptedMessages=" + deleteUnacceptedMessages
315 + ", initialState=" + initialState + ", responseTimeout="
316 + responseTimeout + ", endpointEncoding=" + endpointEncoding + ", disableTransportTransformer="
317 + disableTransportTransformer + "}";
318 }
319
320 public String getProtocol()
321 {
322 return connector.getProtocol();
323 }
324
325 public TransactionConfig getTransactionConfig()
326 {
327 return transactionConfig;
328 }
329
330 protected static boolean equal(Object a, Object b)
331 {
332 return ClassUtils.equal(a, b);
333 }
334
335 @Override
336 public boolean equals(Object obj)
337 {
338 if (this == obj)
339 {
340 return true;
341 }
342 if (obj == null || getClass() != obj.getClass())
343 {
344 return false;
345 }
346
347 final AbstractEndpoint other = (AbstractEndpoint) obj;
348 return equal(retryPolicyTemplate, other.retryPolicyTemplate)
349 && equal(connector, other.connector)
350 && deleteUnacceptedMessages == other.deleteUnacceptedMessages
351 && equal(endpointEncoding, other.endpointEncoding)
352 && equal(endpointUri, other.endpointUri)
353 && equal(initialState, other.initialState)
354
355
356 && equal(messageExchangePattern, other.messageExchangePattern)
357 && equal(name, other.name)
358 && equal(properties, other.properties)
359 && responseTimeout == other.responseTimeout
360 && equal(messageProcessors, other.messageProcessors)
361 && equal(responseMessageProcessors, other.responseMessageProcessors)
362 && equal(transactionConfig, other.transactionConfig)
363 && disableTransportTransformer == other.disableTransportTransformer;
364 }
365
366 @Override
367 public int hashCode()
368 {
369 return ClassUtils.hash(new Object[]{this.getClass(), retryPolicyTemplate, connector,
370 deleteUnacceptedMessages ? Boolean.TRUE : Boolean.FALSE,
371 endpointEncoding,
372 endpointUri,
373 initialState,
374
375
376 messageExchangePattern,
377 name,
378 properties,
379 Integer.valueOf(responseTimeout),
380 responseMessageProcessors,
381 transactionConfig,
382 messageProcessors,
383 disableTransportTransformer ? Boolean.TRUE : Boolean.FALSE});
384 }
385
386 public Filter getFilter()
387 {
388
389 for (MessageProcessor mp : messageProcessors)
390 {
391 if (mp instanceof MessageFilter)
392 {
393 return ((MessageFilter) mp).getFilter();
394 }
395 }
396 return null;
397 }
398
399 public boolean isDeleteUnacceptedMessages()
400 {
401 return deleteUnacceptedMessages;
402 }
403
404
405
406
407
408
409
410
411
412 public EndpointSecurityFilter getSecurityFilter()
413 {
414 for (MessageProcessor mp : messageProcessors)
415 {
416 if (mp instanceof SecurityFilterMessageProcessor)
417 {
418 return ((SecurityFilterMessageProcessor)mp).getFilter();
419 }
420 }
421
422 return null;
423 }
424
425 public MessageExchangePattern getExchangePattern()
426 {
427 return messageExchangePattern;
428 }
429
430
431
432
433
434
435 public int getResponseTimeout()
436 {
437 return responseTimeout;
438 }
439
440
441
442
443
444
445
446 public String getInitialState()
447 {
448 return initialState;
449 }
450
451
452 public List<Transformer> getResponseTransformers()
453 {
454 List transformers = new LinkedList();
455 for (MessageProcessor processor : responseMessageProcessors)
456 {
457 if (processor instanceof Transformer)
458 {
459 transformers.add(processor);
460 }
461 }
462 return transformers;
463 }
464
465 public Object getProperty(Object key)
466 {
467 return properties.get(key);
468 }
469
470 public MuleContext getMuleContext()
471 {
472 return muleContext;
473 }
474
475 public RetryPolicyTemplate getRetryPolicyTemplate()
476 {
477 return retryPolicyTemplate;
478 }
479
480 public String getEndpointBuilderName()
481 {
482 return endpointBuilderName;
483 }
484
485 public boolean isProtocolSupported(String protocol)
486 {
487 return connector.supportsProtocol(protocol);
488 }
489
490 public boolean isDisableTransportTransformer()
491 {
492 return disableTransportTransformer;
493 }
494
495 public void dispose()
496 {
497 this.muleContext = null;
498 this.messageProcessors.clear();
499 this.messageProcessorChain = null;
500 }
501
502 public MessageProcessor getMessageProcessorChain(FlowConstruct flowContruct) throws MuleException
503 {
504 if (messageProcessorChain == null)
505 {
506 messageProcessorChain = createMessageProcessorChain(flowContruct);
507 }
508 return messageProcessorChain;
509 }
510
511 abstract protected MessageProcessor createMessageProcessorChain(FlowConstruct flowContruct) throws MuleException;
512 }