View Javadoc

1   /*
2    * $Id: BridgeBuilder.java 22654 2011-08-12 07:32:57Z mike.schilling $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.construct.builder;
12  
13  import java.util.Arrays;
14  
15  import org.mule.MessageExchangePattern;
16  import org.mule.api.MuleContext;
17  import org.mule.api.MuleException;
18  import org.mule.api.endpoint.EndpointBuilder;
19  import org.mule.api.endpoint.InboundEndpoint;
20  import org.mule.api.endpoint.OutboundEndpoint;
21  import org.mule.api.processor.MessageProcessor;
22  import org.mule.api.transaction.TransactionConfig;
23  import org.mule.api.transaction.TransactionException;
24  import org.mule.api.transaction.TransactionFactory;
25  import org.mule.api.transformer.Transformer;
26  import org.mule.config.i18n.MessageFactory;
27  import org.mule.construct.Bridge;
28  import org.mule.transaction.MuleTransactionConfig;
29  import org.mule.transaction.XaTransactionFactory;
30  import org.mule.util.ClassUtils;
31  import org.mule.util.StringUtils;
32  
33  public class BridgeBuilder extends
34      AbstractFlowConstructWithSingleInboundAndOutboundEndpointBuilder<BridgeBuilder, Bridge>
35  {
36      protected MessageExchangePattern exchangePattern = MessageExchangePattern.REQUEST_RESPONSE;
37      protected boolean transacted = false;
38  
39      @Override
40      protected MessageExchangePattern getInboundMessageExchangePattern()
41      {
42          return exchangePattern;
43      }
44  
45      @Override
46      protected MessageExchangePattern getOutboundMessageExchangePattern()
47      {
48          return exchangePattern;
49      }
50  
51      public BridgeBuilder exchangePattern(MessageExchangePattern exchangePattern)
52      {
53          this.exchangePattern = exchangePattern;
54          return this;
55      }
56  
57      public BridgeBuilder transacted(boolean transacted)
58      {
59          this.transacted = transacted;
60          return this;
61      }
62  
63      public BridgeBuilder transformers(Transformer... transformers)
64      {
65          this.transformers = Arrays.asList((MessageProcessor[]) transformers);
66          return this;
67      }
68  
69      public BridgeBuilder responseTransformers(Transformer... responseTransformers)
70      {
71          this.responseTransformers = Arrays.asList((MessageProcessor[]) responseTransformers);
72          return this;
73      }
74  
75      @Override
76      protected void doConfigureInboundEndpointBuilder(MuleContext muleContext, EndpointBuilder endpointBuilder)
77      {
78          if (transacted)
79          {
80              MuleTransactionConfig transactionConfig = new MuleTransactionConfig(TransactionConfig.ACTION_BEGIN_OR_JOIN);
81              transactionConfig.setMuleContext(muleContext);
82              endpointBuilder.setTransactionConfig(transactionConfig);
83          }
84      }
85  
86      @Override
87      protected void doConfigureOutboundEndpointBuilder(MuleContext muleContext, EndpointBuilder endpointBuilder)
88      {
89          if (transacted)
90          {
91              MuleTransactionConfig transactionConfig = new MuleTransactionConfig(TransactionConfig.ACTION_ALWAYS_JOIN);
92              transactionConfig.setMuleContext(muleContext);
93              endpointBuilder.setTransactionConfig(transactionConfig);
94          }
95      }
96  
97      @Override
98      protected Bridge buildFlowConstruct(MuleContext muleContext) throws MuleException
99      {
100         InboundEndpoint inboundEndpoint = getOrBuildInboundEndpoint(muleContext);
101         OutboundEndpoint outboundEndpoint = getOrBuildOutboundEndpoint(muleContext);
102 
103         if (transacted)
104         {
105             setTransactionFactoriesIfNeeded(inboundEndpoint, outboundEndpoint);
106         }
107 
108         return new Bridge(name, muleContext, inboundEndpoint, outboundEndpoint, transformers,
109             responseTransformers, exchangePattern, transacted);
110     }
111 
112     private void setTransactionFactoriesIfNeeded(InboundEndpoint inboundEndpoint,
113                                                  OutboundEndpoint outboundEndpoint) throws MuleException
114     {
115         String inboundProtocol = inboundEndpoint.getConnector().getProtocol();
116         String outboundProtocol = outboundEndpoint.getConnector().getProtocol();
117 
118         boolean needXA = !inboundProtocol.equals(outboundProtocol);
119 
120         TransactionConfig inboundTransactionConfig = inboundEndpoint.getTransactionConfig();
121 
122         if (inboundTransactionConfig.getFactory() == null)
123         {
124             TransactionFactory transactionFactory = needXA
125                                                           ? new XaTransactionFactory()
126                                                           : getTransactionFactory(inboundProtocol);
127 
128             inboundTransactionConfig.setFactory(transactionFactory);
129         }
130 
131         TransactionConfig outboundTransactionConfig = outboundEndpoint.getTransactionConfig();
132 
133         if (outboundTransactionConfig.getFactory() == null)
134         {
135             TransactionFactory transactionFactory = needXA
136                                                           ? new XaTransactionFactory()
137                                                           : getTransactionFactory(outboundProtocol);
138             outboundTransactionConfig.setFactory(transactionFactory);
139         }
140     }
141 
142     /**
143      * Very simplistic attempt to locate a protocol specific transaction factory.
144      */
145     private TransactionFactory getTransactionFactory(String protocol) throws MuleException
146     {
147         String protocolTransactionFactoryClassName = "org.mule.transport." + StringUtils.lowerCase(protocol)
148                                                      + "." + StringUtils.capitalize(protocol)
149                                                      + "TransactionFactory";
150 
151         if (!ClassUtils.isClassOnPath(protocolTransactionFactoryClassName, getClass()))
152         {
153             throw new TransactionException(
154                 MessageFactory.createStaticMessage("Failed to locate a transaction factory for protocol: "
155                                                    + protocol));
156         }
157 
158         try
159         {
160             return (TransactionFactory) ClassUtils.instanciateClass(protocolTransactionFactoryClassName);
161         }
162         catch (Exception e)
163         {
164             throw new TransactionException(
165                 MessageFactory.createStaticMessage("Failed to instantiate a transaction factory for protocol: "
166                                                    + protocol), e);
167         }
168     }
169 }