001: /*
002: * $Id: AbstractEndpointBuilder.java 11362 2008-03-14 11:27:59Z tcarlson $
003: * --------------------------------------------------------------------------------------
004: * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
005: *
006: * The software in this package is published under the terms of the CPAL v1.0
007: * license, a copy of which has been included with this distribution in the
008: * LICENSE.txt file.
009: */
010:
011: package org.mule.endpoint;
012:
013: import org.mule.RegistryContext;
014: import org.mule.api.DefaultMuleException;
015: import org.mule.api.MuleContext;
016: import org.mule.api.config.MuleProperties;
017: import org.mule.api.endpoint.EndpointBuilder;
018: import org.mule.api.endpoint.EndpointException;
019: import org.mule.api.endpoint.EndpointURI;
020: import org.mule.api.endpoint.ImmutableEndpoint;
021: import org.mule.api.endpoint.InboundEndpoint;
022: import org.mule.api.endpoint.OutboundEndpoint;
023: import org.mule.api.lifecycle.InitialisationException;
024: import org.mule.api.registry.ServiceDescriptorFactory;
025: import org.mule.api.registry.ServiceException;
026: import org.mule.api.routing.filter.Filter;
027: import org.mule.api.security.EndpointSecurityFilter;
028: import org.mule.api.transaction.TransactionConfig;
029: import org.mule.api.transformer.Transformer;
030: import org.mule.api.transport.ConnectionStrategy;
031: import org.mule.api.transport.Connector;
032: import org.mule.config.i18n.CoreMessages;
033: import org.mule.config.i18n.Message;
034: import org.mule.transaction.MuleTransactionConfig;
035: import org.mule.transformer.TransformerUtils;
036: import org.mule.transport.AbstractConnector;
037: import org.mule.transport.service.TransportFactory;
038: import org.mule.transport.service.TransportFactoryException;
039: import org.mule.transport.service.TransportServiceDescriptor;
040: import org.mule.util.CharSetUtils;
041: import org.mule.util.ClassUtils;
042: import org.mule.util.MapCombiner;
043: import org.mule.util.ObjectNameHelper;
044:
045: import java.util.Collections;
046: import java.util.HashMap;
047: import java.util.LinkedList;
048: import java.util.List;
049: import java.util.Map;
050: import java.util.Properties;
051:
052: /**
053: * Abstract endpoint builder used for externalizing the complex creation logic of
054: * endpoints out of the endpoint instance itself. <br/> The use of a builder allows
055: * i) Endpoints to be configured once and created in a repeatable fashion (global
056: * endpoints), ii) Allow for much more extensibility in endpoint creation for
057: * transport specific endpoints, streaming endpoints etc.<br/>
058: */
059: public abstract class AbstractEndpointBuilder implements
060: EndpointBuilder {
061:
062: public static final String PROPERTY_REMOTE_SYNC = "remoteSync";
063: public static final String PROPERTY_REMOTE_SYNC_TIMEOUT = "remoteSyncTimeout";
064:
065: protected URIBuilder uriBuilder;
066: protected Connector connector;
067: protected List transformers;
068: protected List responseTransformers;
069: protected String name;
070: protected Map properties = new HashMap();
071: protected TransactionConfig transactionConfig;
072: protected Filter filter;
073: protected Boolean deleteUnacceptedMessages;
074: protected EndpointSecurityFilter securityFilter;
075: protected Boolean synchronous;
076: protected Boolean remoteSync;
077: protected Integer remoteSyncTimeout;
078: protected String initialState = ImmutableEndpoint.INITIAL_STATE_STARTED;
079: protected String encoding;
080: protected Integer createConnector;
081: protected ConnectionStrategy connectionStrategy;
082:
083: // not included in equality/hash
084: protected String registryId = null;
085: protected MuleContext muleContext;
086:
087: public InboundEndpoint buildInboundEndpoint()
088: throws EndpointException, InitialisationException {
089: return doBuildInboundEndpoint();
090: }
091:
092: public OutboundEndpoint buildOutboundEndpoint()
093: throws EndpointException, InitialisationException {
094: return doBuildOutboundEndpoint();
095: }
096:
097: protected void setPropertiesFromProperties(Map properties) {
098: synchronous = getBooleanProperty(properties,
099: MuleProperties.SYNCHRONOUS_PROPERTY, synchronous);
100: remoteSync = getBooleanProperty(properties,
101: PROPERTY_REMOTE_SYNC, remoteSync);
102: remoteSyncTimeout = getIntegerProperty(properties,
103: PROPERTY_REMOTE_SYNC_TIMEOUT, remoteSyncTimeout);
104: }
105:
106: public static Boolean getBooleanProperty(Map properties,
107: String name, Boolean dflt) {
108: if (properties.containsKey(name)) {
109: return Boolean.valueOf((String) properties.get(name));
110: } else {
111: return dflt;
112: }
113: }
114:
115: public static Integer getIntegerProperty(Map properties,
116: String name, Integer dflt) {
117: if (properties.containsKey(name)) {
118: return Integer.decode((String) properties.get(name));
119: } else {
120: return dflt;
121: }
122: }
123:
124: protected InboundEndpoint doBuildInboundEndpoint()
125: throws InitialisationException, EndpointException {
126: // use an explicit value here to avoid caching
127: Map properties = getProperties();
128: // this sets values used below, if they appear as properties
129: setPropertiesFromProperties(properties);
130:
131: if (uriBuilder == null) {
132: throw new NullPointerException(CoreMessages.objectIsNull(
133: "uriBuilder").getMessage());
134: }
135:
136: EndpointURI endpointURI = uriBuilder.getEndpoint();
137: endpointURI.initialise();
138:
139: Connector connector = getConnector();
140:
141: if (connector != null
142: && endpointURI != null
143: && !connector.supportsProtocol(endpointURI
144: .getFullScheme())) {
145: throw new IllegalArgumentException(CoreMessages
146: .connectorSchemeIncompatibleWithEndpointScheme(
147: connector.getProtocol(), endpointURI)
148: .getMessage());
149: }
150:
151: List transformers = getInboundTransformers(connector,
152: endpointURI);
153: List responseTransformers = getInboundEndpointResponseTransformers(
154: connector, endpointURI);
155:
156: boolean remoteSync = getRemoteSync(connector);
157: boolean synchronous;
158: if (remoteSync) {
159: synchronous = true;
160: } else {
161: synchronous = getSynchronous(connector, endpointURI);
162: }
163:
164: return new DefaultInboundEndpoint(connector, endpointURI,
165: transformers, responseTransformers,
166: getName(endpointURI), getProperties(),
167: getTransactionConfig(), getFilter(connector),
168: getDefaultDeleteUnacceptedMessages(connector),
169: getSecurityFilter(), synchronous, remoteSync,
170: getRemoteSyncTimeout(connector),
171: getInitialState(connector),
172: getEndpointEncoding(connector), muleContext,
173: getConnectionStrategy(connector));
174: }
175:
176: protected OutboundEndpoint doBuildOutboundEndpoint()
177: throws InitialisationException, EndpointException {
178: // use an explicit value here to avoid caching
179: Map properties = getProperties();
180: // this sets values used below, if they appear as properties
181: setPropertiesFromProperties(properties);
182:
183: if (uriBuilder == null) {
184: throw new NullPointerException(CoreMessages.objectIsNull(
185: "uriBuilder").getMessage());
186: }
187:
188: EndpointURI endpointURI = uriBuilder.getEndpoint();
189: endpointURI.initialise();
190:
191: Connector connector = getConnector();
192:
193: if (connector != null
194: && endpointURI != null
195: && !connector.supportsProtocol(endpointURI
196: .getFullScheme())) {
197: throw new IllegalArgumentException(CoreMessages
198: .connectorSchemeIncompatibleWithEndpointScheme(
199: connector.getProtocol(), endpointURI)
200: .getMessage());
201: }
202:
203: List transformers = getOutboundTransformers(connector,
204: endpointURI);
205: List responseTransformers = getOutboundEndpointResponseTransformers(
206: connector, endpointURI);
207:
208: boolean remoteSync = getRemoteSync(connector);
209: boolean synchronous;
210: if (remoteSync) {
211: synchronous = true;
212: } else {
213: synchronous = getSynchronous(connector, endpointURI);
214: }
215:
216: return new DefaultOutboundEndpoint(connector, endpointURI,
217: transformers, responseTransformers,
218: getName(endpointURI), getProperties(),
219: getTransactionConfig(), getFilter(connector),
220: getDefaultDeleteUnacceptedMessages(connector),
221: getSecurityFilter(), synchronous, remoteSync,
222: getRemoteSyncTimeout(connector),
223: getInitialState(connector),
224: getEndpointEncoding(connector), muleContext,
225: getConnectionStrategy(connector));
226:
227: }
228:
229: protected boolean getSynchronous(Connector connector,
230: EndpointURI endpointURI) {
231: return synchronous != null ? synchronous.booleanValue()
232: : getDefaultSynchronous(connector, endpointURI
233: .getScheme());
234: }
235:
236: protected boolean getDefaultSynchronous(Connector connector,
237: String protocol) {
238: if (connector != null && connector.isSyncEnabled(protocol)) {
239: return true;
240: } else {
241: return muleContext.getConfiguration()
242: .isDefaultSynchronousEndpoints();
243: }
244: }
245:
246: protected ConnectionStrategy getConnectionStrategy(
247: Connector connector) {
248: return connectionStrategy != null ? connectionStrategy
249: : getDefaultConnectionStrategy(connector);
250: }
251:
252: protected ConnectionStrategy getDefaultConnectionStrategy(
253: Connector connector) {
254: return muleContext.getDefaultConnectionStrategy();
255: }
256:
257: protected TransactionConfig getTransactionConfig() {
258: return transactionConfig != null ? transactionConfig
259: : getDefaultTransactionConfig();
260: }
261:
262: protected TransactionConfig getDefaultTransactionConfig() {
263: // TODO Do we need a new instance per endpoint, or can a single instance be
264: // shared?
265: return new MuleTransactionConfig();
266: }
267:
268: protected EndpointSecurityFilter getSecurityFilter() {
269: return securityFilter != null ? securityFilter
270: : getDefaultSecurityFilter();
271: }
272:
273: protected EndpointSecurityFilter getDefaultSecurityFilter() {
274: return null;
275: }
276:
277: protected Connector getConnector() throws EndpointException {
278: return connector != null ? connector : getDefaultConnector();
279: }
280:
281: protected Connector getDefaultConnector() throws EndpointException {
282: return getConnector(uriBuilder.getEndpoint(), muleContext);
283: }
284:
285: protected String getName(EndpointURI endpointURI) {
286: return name != null ? name : ObjectNameHelper
287: .getEndpointName(endpointURI);
288: }
289:
290: protected Map getProperties() {
291: // Add properties from builder, endpointURI and then seal (make unmodifiable)
292: LinkedList maps = new LinkedList();
293: // properties from url come first
294: if (null != uriBuilder) {
295: // properties from the URI itself
296: maps.addLast(uriBuilder.getEndpoint().getParams());
297: }
298: // properties on builder may override url
299: if (properties != null) {
300: maps.addLast(properties);
301: }
302: MapCombiner combiner = new MapCombiner();
303: combiner.setList(maps);
304: return Collections.unmodifiableMap(combiner);
305: }
306:
307: protected boolean getRemoteSync(Connector connector) {
308: return remoteSync != null ? remoteSync.booleanValue()
309: : getDefaultRemoteSync(connector);
310: }
311:
312: protected boolean getDefaultRemoteSync(Connector connector) {
313: return muleContext.getConfiguration().isDefaultRemoteSync();
314: }
315:
316: protected boolean getDeleteUnacceptedMessages(Connector connector) {
317: return deleteUnacceptedMessages != null ? deleteUnacceptedMessages
318: .booleanValue()
319: : getDefaultDeleteUnacceptedMessages(connector);
320:
321: }
322:
323: protected boolean getDefaultDeleteUnacceptedMessages(
324: Connector connector) {
325: return false;
326: }
327:
328: protected String getEndpointEncoding(Connector connector) {
329: return encoding != null ? encoding
330: : getDefaultEndpointEncoding(connector);
331: }
332:
333: protected String getDefaultEndpointEncoding(Connector connector) {
334: if (muleContext != null) {
335: return muleContext.getConfiguration().getDefaultEncoding();
336: } else {
337: return CharSetUtils.defaultCharsetName();
338: }
339: }
340:
341: protected Filter getFilter(Connector connector) {
342: return filter != null ? filter : getDefaultFilter(connector);
343:
344: }
345:
346: protected Filter getDefaultFilter(Connector connector) {
347: return null;
348: }
349:
350: protected String getInitialState(Connector connector) {
351: return initialState != null ? initialState
352: : getDefaultInitialState(connector);
353:
354: }
355:
356: protected String getDefaultInitialState(Connector connector) {
357: return ImmutableEndpoint.INITIAL_STATE_STARTED;
358: }
359:
360: protected int getRemoteSyncTimeout(Connector connector) {
361: return remoteSyncTimeout != null ? remoteSyncTimeout.intValue()
362: : getDefaultRemoteSyncTimeout(connector);
363:
364: }
365:
366: protected int getDefaultRemoteSyncTimeout(Connector connector) {
367: return muleContext.getConfiguration()
368: .getDefaultSynchronousEventTimeout();
369: }
370:
371: protected List getInboundTransformers(Connector connector,
372: EndpointURI endpointURI) throws TransportFactoryException {
373: // #1 Transformers set on builder
374: if (transformers != null) {
375: return transformers;
376: }
377:
378: // #2 Transformer specified on uri
379: List transformers = getTransformersFromString(endpointURI
380: .getTransformers());
381: if (transformers != null) {
382: return transformers;
383: }
384:
385: // #3 Default Transformer
386: return getDefaultInboundTransformers(connector);
387: }
388:
389: protected List getDefaultInboundTransformers(Connector connector)
390: throws TransportFactoryException {
391: try {
392: return TransformerUtils
393: .getDefaultInboundTransformers(getNonNullServiceDescriptor(
394: uriBuilder.getEndpoint()
395: .getSchemeMetaInfo(),
396: getOverrides(connector)));
397: } catch (Exception e) {
398: throw new TransportFactoryException(e);
399: }
400: }
401:
402: protected List getOutboundTransformers(Connector connector,
403: EndpointURI endpointURI) throws TransportFactoryException {
404: // #1 Transformers set on builder
405: if (transformers != null) {
406: return transformers;
407: }
408:
409: // #2 Transformer specified on uri
410: List transformers = getTransformersFromString(endpointURI
411: .getTransformers());
412: if (transformers != null) {
413: return transformers;
414: }
415:
416: // #3 Default Transformer
417: return getDefaultOutboundTransformers(connector);
418: }
419:
420: protected List getDefaultOutboundTransformers(Connector connector)
421: throws TransportFactoryException {
422: try {
423: return TransformerUtils
424: .getDefaultOutboundTransformers(getNonNullServiceDescriptor(
425: uriBuilder.getEndpoint()
426: .getSchemeMetaInfo(),
427: getOverrides(connector)));
428: } catch (Exception e) {
429: throw new TransportFactoryException(e);
430: }
431: }
432:
433: protected List getInboundEndpointResponseTransformers(
434: Connector connector, EndpointURI endpointURI)
435: throws TransportFactoryException {
436: // #1 Transformers set on builder
437: if (responseTransformers != null) {
438: return responseTransformers;
439: }
440:
441: // #2 Transformer specified on uri
442: List transformers = getTransformersFromString(endpointURI
443: .getResponseTransformers());
444: if (transformers != null) {
445: return transformers;
446: }
447:
448: // #3 Default Connector Response Transformer
449: return getDefaultResponseTransformers(connector);
450: }
451:
452: protected List getOutboundEndpointResponseTransformers(
453: Connector connector, EndpointURI endpointURI)
454: throws TransportFactoryException {
455: // #1 Transformers set on builder
456: if (responseTransformers != null) {
457: return responseTransformers;
458: }
459:
460: // #2 Transformer specified on uri
461: List transformers = getTransformersFromString(endpointURI
462: .getResponseTransformers());
463: if (transformers != null) {
464: return transformers;
465: }
466: return Collections.EMPTY_LIST;
467: }
468:
469: protected List getDefaultResponseTransformers(Connector connector)
470: throws TransportFactoryException {
471: try {
472: return TransformerUtils
473: .getDefaultResponseTransformers(getNonNullServiceDescriptor(
474: uriBuilder.getEndpoint()
475: .getSchemeMetaInfo(),
476: getOverrides(connector)));
477: } catch (Exception e) {
478: throw new TransportFactoryException(e);
479: }
480: }
481:
482: private List getTransformersFromString(String transformers)
483: throws TransportFactoryException {
484: try {
485: return TransformerUtils.getTransformers(transformers);
486: } catch (DefaultMuleException e) {
487: throw new TransportFactoryException(e);
488: }
489: }
490:
491: private Properties getOverrides(Connector connector) {
492: // Get connector specific overrides to set on the descriptor
493: Properties overrides = new Properties();
494: if (connector instanceof AbstractConnector) {
495: Map so = ((AbstractConnector) connector)
496: .getServiceOverrides();
497: if (so != null) {
498: overrides.putAll(so);
499: }
500: }
501: return overrides;
502: }
503:
504: private TransportServiceDescriptor getNonNullServiceDescriptor(
505: String scheme, Properties overrides)
506: throws ServiceException {
507: TransportServiceDescriptor sd = (TransportServiceDescriptor) RegistryContext
508: .getRegistry().lookupServiceDescriptor(
509: ServiceDescriptorFactory.PROVIDER_SERVICE_TYPE,
510: scheme, overrides);
511: if (null != sd) {
512: return sd;
513: } else {
514: throw new ServiceException(CoreMessages
515: .noServiceTransportDescriptor(scheme));
516: }
517: }
518:
519: private Connector getConnector(EndpointURI endpointURI,
520: MuleContext muleContext) throws EndpointException {
521: String scheme = uriBuilder.getEndpoint().getFullScheme();
522: Connector connector;
523: try {
524: if (uriBuilder.getEndpoint().getConnectorName() != null) {
525: connector = muleContext.getRegistry().lookupConnector(
526: uriBuilder.getEndpoint().getConnectorName());
527: if (connector == null) {
528: throw new TransportFactoryException(CoreMessages
529: .objectNotRegistered("Connector",
530: uriBuilder.getEndpoint()
531: .getConnectorName()));
532: }
533: } else {
534: connector = TransportFactory
535: .getConnectorByProtocol(scheme);
536: if (connector == null) {
537: connector = TransportFactory.createConnector(
538: endpointURI, muleContext);
539: muleContext.getRegistry().registerConnector(
540: connector);
541: }
542: }
543: } catch (Exception e) {
544: throw new TransportFactoryException(e);
545: }
546:
547: if (connector == null) {
548: Message m = CoreMessages.failedToCreateObjectWith(
549: "Endpoint", "endpointURI: " + endpointURI);
550: m.setNextMessage(CoreMessages.objectIsNull("connector"));
551: throw new TransportFactoryException(m);
552:
553: }
554: return connector;
555: }
556:
557: // Builder setters
558:
559: public void setConnector(Connector connector) {
560: this .connector = connector;
561:
562: }
563:
564: public void addTransformer(Transformer transformer) {
565: if (transformers == null) {
566: transformers = new LinkedList();
567: }
568: transformers.add(transformer);
569: }
570:
571: public void setTransformers(List transformers) {
572: this .transformers = transformers;
573: }
574:
575: public void setResponseTransformers(List responseTransformers) {
576: this .responseTransformers = responseTransformers;
577: }
578:
579: public void setName(String name) {
580: this .name = name;
581: }
582:
583: /**
584: * NOTE - this appends properties.
585: */
586: public void setProperties(Map properties) {
587: if (null == this .properties) {
588: this .properties = new HashMap();
589: }
590: this .properties.putAll(properties);
591: }
592:
593: /**
594: * Sets a property on the endpoint
595: *
596: * @param key the property key
597: * @param value the value of the property
598: */
599: public void setProperty(Object key, Object value) {
600: properties.put(key, value);
601: }
602:
603: public void setTransactionConfig(TransactionConfig transactionConfig) {
604: this .transactionConfig = transactionConfig;
605:
606: }
607:
608: public void setFilter(Filter filter) {
609: this .filter = filter;
610:
611: }
612:
613: public void setDeleteUnacceptedMessages(
614: boolean deleteUnacceptedMessages) {
615: this .deleteUnacceptedMessages = new Boolean(
616: deleteUnacceptedMessages);
617:
618: }
619:
620: public void setSecurityFilter(EndpointSecurityFilter securityFilter) {
621: this .securityFilter = securityFilter;
622:
623: }
624:
625: public void setSynchronous(boolean synchronous) {
626: this .synchronous = new Boolean(synchronous);
627:
628: }
629:
630: public void setRemoteSync(boolean remoteSync) {
631: this .remoteSync = new Boolean(remoteSync);
632:
633: }
634:
635: public void setRemoteSyncTimeout(int remoteSyncTimeout) {
636: this .remoteSyncTimeout = new Integer(remoteSyncTimeout);
637:
638: }
639:
640: public void setInitialState(String initialState) {
641: this .initialState = initialState;
642:
643: }
644:
645: public void setEncoding(String encoding) {
646: this .encoding = encoding;
647:
648: }
649:
650: public void setCreateConnector(int createConnector) {
651: this .createConnector = new Integer(createConnector);
652:
653: }
654:
655: public void setRegistryId(String registryId) {
656: this .registryId = registryId;
657:
658: }
659:
660: public void setMuleContext(MuleContext muleContext) {
661: this .muleContext = muleContext;
662:
663: }
664:
665: public void setConnectionStrategy(
666: ConnectionStrategy connectionStrategy) {
667: this .connectionStrategy = connectionStrategy;
668:
669: }
670:
671: public URIBuilder getEndpointBuilder() {
672: return uriBuilder;
673: }
674:
675: public void setURIBuilder(URIBuilder URIBuilder) {
676: this .uriBuilder = URIBuilder;
677:
678: }
679:
680: // TODO Equals() and hashCode() only needed for tests, move to tests
681: public int hashCode() {
682: return ClassUtils.hash(new Object[] { connectionStrategy,
683: connector, createConnector, deleteUnacceptedMessages,
684: encoding, uriBuilder, filter, initialState, name,
685: properties, remoteSync, remoteSyncTimeout,
686: responseTransformers, securityFilter, synchronous,
687: transactionConfig, transformers });
688: }
689:
690: // TODO Equals() and hashCode() only needed for tests, move to tests
691: public boolean equals(Object obj) {
692: if (this == obj)
693: return true;
694: if (obj == null || getClass() != obj.getClass())
695: return false;
696:
697: final AbstractEndpointBuilder other = (AbstractEndpointBuilder) obj;
698: return equal(connectionStrategy, other.connectionStrategy)
699: && equal(connector, other.connector)
700: && equal(createConnector, other.createConnector)
701: && equal(deleteUnacceptedMessages,
702: other.deleteUnacceptedMessages)
703: && equal(encoding, other.encoding)
704: && equal(uriBuilder, other.uriBuilder)
705: && equal(filter, other.filter)
706: && equal(initialState, other.initialState)
707: && equal(name, other.name)
708: && equal(properties, other.properties)
709: && equal(remoteSync, other.remoteSync)
710: && equal(remoteSyncTimeout, other.remoteSyncTimeout)
711: && equal(responseTransformers,
712: other.responseTransformers)
713: && equal(securityFilter, other.securityFilter)
714: && equal(synchronous, other.synchronous)
715: && equal(transactionConfig, other.transactionConfig)
716: && equal(transformers, other.transformers);
717: }
718:
719: protected static boolean equal(Object a, Object b) {
720: return ClassUtils.equal(a, b);
721: }
722:
723: public Object clone() throws CloneNotSupportedException {
724: EndpointBuilder builder = (EndpointBuilder) super.clone();
725: builder.setConnector(connector);
726: builder.setURIBuilder(uriBuilder);
727: builder.setTransformers(transformers);
728: builder.setResponseTransformers(responseTransformers);
729: builder.setName(name);
730: builder.setProperties(properties);
731: builder.setTransactionConfig(transactionConfig);
732: builder.setFilter(filter);
733: builder.setSecurityFilter(securityFilter);
734: builder.setInitialState(initialState);
735: builder.setEncoding(encoding);
736: builder.setRegistryId(registryId);
737: builder.setMuleContext(muleContext);
738: builder.setConnectionStrategy(connectionStrategy);
739:
740: if (deleteUnacceptedMessages != null) {
741: builder
742: .setDeleteUnacceptedMessages(deleteUnacceptedMessages
743: .booleanValue());
744: }
745: if (synchronous != null) {
746: builder.setSynchronous(synchronous.booleanValue());
747: }
748: if (remoteSync != null) {
749: builder.setRemoteSync(remoteSync.booleanValue());
750: }
751: if (remoteSyncTimeout != null) {
752: builder.setRemoteSyncTimeout(remoteSyncTimeout.intValue());
753: }
754:
755: return builder;
756: }
757:
758: }
|