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