001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.model;
018
019import java.util.concurrent.ExecutorService;
020import java.util.function.Supplier;
021
022import javax.xml.bind.annotation.XmlAccessType;
023import javax.xml.bind.annotation.XmlAccessorType;
024import javax.xml.bind.annotation.XmlAttribute;
025import javax.xml.bind.annotation.XmlRootElement;
026import javax.xml.bind.annotation.XmlTransient;
027
028import org.apache.camel.AggregationStrategy;
029import org.apache.camel.Expression;
030import org.apache.camel.Processor;
031import org.apache.camel.model.language.ExpressionDefinition;
032import org.apache.camel.spi.Metadata;
033
034/**
035 * Splits a single message into many sub-messages.
036 */
037@Metadata(label = "eip,routing")
038@XmlRootElement(name = "split")
039@XmlAccessorType(XmlAccessType.FIELD)
040public class SplitDefinition extends OutputExpressionNode implements ExecutorServiceAwareDefinition<SplitDefinition> {
041    @XmlTransient
042    private AggregationStrategy aggregationStrategy;
043    @XmlTransient
044    private ExecutorService executorService;
045    @XmlAttribute
046    @Metadata(javaType = "java.lang.Boolean")
047    private String parallelProcessing;
048    @XmlAttribute
049    private String strategyRef;
050    @XmlAttribute
051    private String strategyMethodName;
052    @XmlAttribute
053    @Metadata(javaType = "java.lang.Boolean")
054    private String strategyMethodAllowNull;
055    @XmlAttribute
056    private String executorServiceRef;
057    @XmlAttribute
058    @Metadata(javaType = "java.lang.Boolean")
059    private String streaming;
060    @XmlAttribute
061    @Metadata(javaType = "java.lang.Boolean")
062    private String stopOnException;
063    @XmlAttribute
064    @Metadata(defaultValue = "0", javaType = "java.lang.Long")
065    private String timeout;
066    @XmlAttribute
067    private String onPrepareRef;
068    @XmlTransient
069    private Processor onPrepare;
070    @XmlAttribute
071    @Metadata(javaType = "java.lang.Boolean")
072    private String shareUnitOfWork;
073    @XmlAttribute
074    @Metadata(javaType = "java.lang.Boolean")
075    private String parallelAggregate;
076    @XmlAttribute
077    @Metadata(javaType = "java.lang.Boolean")
078    private String stopOnAggregateException;
079
080    public SplitDefinition() {
081    }
082
083    public SplitDefinition(Expression expression) {
084        super(expression);
085    }
086
087    public SplitDefinition(ExpressionDefinition expression) {
088        super(expression);
089    }
090
091    @Override
092    public String toString() {
093        return "Split[" + getExpression() + " -> " + getOutputs() + "]";
094    }
095
096    @Override
097    public String getShortName() {
098        return "split";
099    }
100
101    @Override
102    public String getLabel() {
103        return "split[" + getExpression() + "]";
104    }
105
106    // Fluent API
107    // -------------------------------------------------------------------------
108
109    /**
110     * Sets the AggregationStrategy to be used to assemble the replies from the
111     * splitted messages, into a single outgoing message from the Splitter. By
112     * default Camel will use the original incoming message to the splitter
113     * (leave it unchanged). You can also use a POJO as the AggregationStrategy
114     */
115    public SplitDefinition aggregationStrategy(AggregationStrategy aggregationStrategy) {
116        setAggregationStrategy(aggregationStrategy);
117        return this;
118    }
119
120    /**
121     * Sets the AggregationStrategy to be used to assemble the replies from the
122     * splitted messages, into a single outgoing message from the Splitter. By
123     * default Camel will use the original incoming message to the splitter
124     * (leave it unchanged). You can also use a POJO as the AggregationStrategy
125     */
126    public SplitDefinition aggregationStrategy(Supplier<AggregationStrategy> aggregationStrategy) {
127        setAggregationStrategy(aggregationStrategy.get());
128        return this;
129    }
130
131    /**
132     * Sets a reference to the AggregationStrategy to be used to assemble the
133     * replies from the splitted messages, into a single outgoing message from
134     * the Splitter. By default Camel will use the original incoming message to
135     * the splitter (leave it unchanged). You can also use a POJO as the
136     * AggregationStrategy
137     */
138    public SplitDefinition aggregationStrategyRef(String aggregationStrategyRef) {
139        setStrategyRef(aggregationStrategyRef);
140        return this;
141    }
142
143    /**
144     * This option can be used to explicit declare the method name to use, when
145     * using POJOs as the AggregationStrategy.
146     *
147     * @param methodName the method name to call
148     * @return the builder
149     */
150    public SplitDefinition aggregationStrategyMethodName(String methodName) {
151        setStrategyMethodName(methodName);
152        return this;
153    }
154
155    /**
156     * If this option is false then the aggregate method is not used if there
157     * was no data to enrich. If this option is true then null values is used as
158     * the oldExchange (when no data to enrich), when using POJOs as the
159     * AggregationStrategy
160     *
161     * @return the builder
162     */
163    public SplitDefinition aggregationStrategyMethodAllowNull() {
164        return aggregationStrategyMethodAllowNull(true);
165    }
166
167    /**
168     * If this option is false then the aggregate method is not used if there
169     * was no data to enrich. If this option is true then null values is used as
170     * the oldExchange (when no data to enrich), when using POJOs as the
171     * AggregationStrategy
172     *
173     * @return the builder
174     */
175    public SplitDefinition aggregationStrategyMethodAllowNull(boolean aggregationStrategyMethodAllowNull) {
176        return aggregationStrategyMethodAllowNull(Boolean.toString(aggregationStrategyMethodAllowNull));
177    }
178
179    /**
180     * If this option is false then the aggregate method is not used if there
181     * was no data to enrich. If this option is true then null values is used as
182     * the oldExchange (when no data to enrich), when using POJOs as the
183     * AggregationStrategy
184     *
185     * @return the builder
186     */
187    public SplitDefinition aggregationStrategyMethodAllowNull(String aggregationStrategyMethodAllowNull) {
188        setStrategyMethodAllowNull(aggregationStrategyMethodAllowNull);
189        return this;
190    }
191
192    /**
193     * If enabled then processing each splitted messages occurs concurrently.
194     * Note the caller thread will still wait until all messages has been fully
195     * processed, before it continues. Its only processing the sub messages from
196     * the splitter which happens concurrently.
197     *
198     * @return the builder
199     */
200    public SplitDefinition parallelProcessing() {
201        return parallelProcessing(true);
202    }
203
204    /**
205     * If enabled then processing each splitted messages occurs concurrently.
206     * Note the caller thread will still wait until all messages has been fully
207     * processed, before it continues. Its only processing the sub messages from
208     * the splitter which happens concurrently.
209     *
210     * @return the builder
211     */
212    public SplitDefinition parallelProcessing(boolean parallelProcessing) {
213        return parallelProcessing(Boolean.toString(parallelProcessing));
214    }
215
216    /**
217     * If enabled then processing each splitted messages occurs concurrently.
218     * Note the caller thread will still wait until all messages has been fully
219     * processed, before it continues. Its only processing the sub messages from
220     * the splitter which happens concurrently.
221     *
222     * @return the builder
223     */
224    public SplitDefinition parallelProcessing(String parallelProcessing) {
225        setParallelProcessing(parallelProcessing);
226        return this;
227    }
228
229    /**
230     * If enabled then the aggregate method on AggregationStrategy can be called
231     * concurrently. Notice that this would require the implementation of
232     * AggregationStrategy to be implemented as thread-safe. By default this is
233     * false meaning that Camel synchronizes the call to the aggregate method.
234     * Though in some use-cases this can be used to archive higher performance
235     * when the AggregationStrategy is implemented as thread-safe.
236     *
237     * @return the builder
238     */
239    public SplitDefinition parallelAggregate() {
240        return parallelAggregate(true);
241    }
242
243    /**
244     * If enabled then the aggregate method on AggregationStrategy can be called
245     * concurrently. Notice that this would require the implementation of
246     * AggregationStrategy to be implemented as thread-safe. By default this is
247     * false meaning that Camel synchronizes the call to the aggregate method.
248     * Though in some use-cases this can be used to archive higher performance
249     * when the AggregationStrategy is implemented as thread-safe.
250     *
251     * @return the builder
252     */
253    public SplitDefinition parallelAggregate(boolean parallelAggregate) {
254        return parallelAggregate(Boolean.toString(parallelAggregate));
255    }
256
257    /**
258     * If enabled then the aggregate method on AggregationStrategy can be called
259     * concurrently. Notice that this would require the implementation of
260     * AggregationStrategy to be implemented as thread-safe. By default this is
261     * false meaning that Camel synchronizes the call to the aggregate method.
262     * Though in some use-cases this can be used to archive higher performance
263     * when the AggregationStrategy is implemented as thread-safe.
264     *
265     * @return the builder
266     */
267    public SplitDefinition parallelAggregate(String parallelAggregate) {
268        setParallelAggregate(parallelAggregate);
269        return this;
270    }
271
272    /**
273     * If enabled, unwind exceptions occurring at aggregation time to the error
274     * handler when parallelProcessing is used. Currently, aggregation time
275     * exceptions do not stop the route processing when parallelProcessing is
276     * used. Enabling this option allows to work around this behavior. The
277     * default value is <code>false</code> for the sake of backward
278     * compatibility.
279     *
280     * @return the builder
281     */
282    public SplitDefinition stopOnAggregateException() {
283        return stopOnAggregateException(true);
284    }
285
286    /**
287     * If enabled, unwind exceptions occurring at aggregation time to the error
288     * handler when parallelProcessing is used. Currently, aggregation time
289     * exceptions do not stop the route processing when parallelProcessing is
290     * used. Enabling this option allows to work around this behavior. The
291     * default value is <code>false</code> for the sake of backward
292     * compatibility.
293     *
294     * @return the builder
295     */
296    public SplitDefinition stopOnAggregateException(boolean stopOnAggregateException) {
297        return stopOnAggregateException(Boolean.toString(stopOnAggregateException));
298    }
299
300    /**
301     * If enabled, unwind exceptions occurring at aggregation time to the error
302     * handler when parallelProcessing is used. Currently, aggregation time
303     * exceptions do not stop the route processing when parallelProcessing is
304     * used. Enabling this option allows to work around this behavior. The
305     * default value is <code>false</code> for the sake of backward
306     * compatibility.
307     *
308     * @return the builder
309     */
310    public SplitDefinition stopOnAggregateException(String stopOnAggregateException) {
311        setStopOnAggregateException(stopOnAggregateException);
312        return this;
313    }
314
315    /**
316     * When in streaming mode, then the splitter splits the original message
317     * on-demand, and each splitted message is processed one by one. This
318     * reduces memory usage as the splitter do not split all the messages first,
319     * but then we do not know the total size, and therefore the
320     * {@link org.apache.camel.Exchange#SPLIT_SIZE} is empty.
321     * <p/>
322     * In non-streaming mode (default) the splitter will split each message
323     * first, to know the total size, and then process each message one by one.
324     * This requires to keep all the splitted messages in memory and therefore
325     * requires more memory. The total size is provided in the
326     * {@link org.apache.camel.Exchange#SPLIT_SIZE} header.
327     * <p/>
328     * The streaming mode also affects the aggregation behavior. If enabled then
329     * Camel will process replies out-of-order, eg in the order they come back.
330     * If disabled, Camel will process replies in the same order as the messages
331     * was splitted.
332     *
333     * @return the builder
334     */
335    public SplitDefinition streaming() {
336        return streaming(true);
337    }
338
339    /**
340     * When in streaming mode, then the splitter splits the original message
341     * on-demand, and each splitted message is processed one by one. This
342     * reduces memory usage as the splitter do not split all the messages first,
343     * but then we do not know the total size, and therefore the
344     * {@link org.apache.camel.Exchange#SPLIT_SIZE} is empty.
345     * <p/>
346     * In non-streaming mode (default) the splitter will split each message
347     * first, to know the total size, and then process each message one by one.
348     * This requires to keep all the splitted messages in memory and therefore
349     * requires more memory. The total size is provided in the
350     * {@link org.apache.camel.Exchange#SPLIT_SIZE} header.
351     * <p/>
352     * The streaming mode also affects the aggregation behavior. If enabled then
353     * Camel will process replies out-of-order, eg in the order they come back.
354     * If disabled, Camel will process replies in the same order as the messages
355     * was splitted.
356     *
357     * @return the builder
358     */
359    public SplitDefinition streaming(boolean streaming) {
360        return streaming(Boolean.toString(streaming));
361    }
362
363    /**
364     * When in streaming mode, then the splitter splits the original message
365     * on-demand, and each splitted message is processed one by one. This
366     * reduces memory usage as the splitter do not split all the messages first,
367     * but then we do not know the total size, and therefore the
368     * {@link org.apache.camel.Exchange#SPLIT_SIZE} is empty.
369     * <p/>
370     * In non-streaming mode (default) the splitter will split each message
371     * first, to know the total size, and then process each message one by one.
372     * This requires to keep all the splitted messages in memory and therefore
373     * requires more memory. The total size is provided in the
374     * {@link org.apache.camel.Exchange#SPLIT_SIZE} header.
375     * <p/>
376     * The streaming mode also affects the aggregation behavior. If enabled then
377     * Camel will process replies out-of-order, eg in the order they come back.
378     * If disabled, Camel will process replies in the same order as the messages
379     * was splitted.
380     *
381     * @return the builder
382     */
383    public SplitDefinition streaming(String streaming) {
384        setStreaming(streaming);
385        return this;
386    }
387
388    /**
389     * Will now stop further processing if an exception or failure occurred
390     * during processing of an {@link org.apache.camel.Exchange} and the caused
391     * exception will be thrown.
392     * <p/>
393     * Will also stop if processing the exchange failed (has a fault message) or
394     * an exception was thrown and handled by the error handler (such as using
395     * onException). In all situations the splitter will stop further
396     * processing. This is the same behavior as in pipeline, which is used by
397     * the routing engine.
398     * <p/>
399     * The default behavior is to <b>not</b> stop but continue processing till
400     * the end
401     *
402     * @return the builder
403     */
404    public SplitDefinition stopOnException() {
405        return stopOnException(true);
406    }
407
408    /**
409     * Will now stop further processing if an exception or failure occurred
410     * during processing of an {@link org.apache.camel.Exchange} and the caused
411     * exception will be thrown.
412     * <p/>
413     * Will also stop if processing the exchange failed (has a fault message) or
414     * an exception was thrown and handled by the error handler (such as using
415     * onException). In all situations the splitter will stop further
416     * processing. This is the same behavior as in pipeline, which is used by
417     * the routing engine.
418     * <p/>
419     * The default behavior is to <b>not</b> stop but continue processing till
420     * the end
421     *
422     * @return the builder
423     */
424    public SplitDefinition stopOnException(boolean stopOnException) {
425        return stopOnException(Boolean.toString(stopOnException));
426    }
427
428    /**
429     * Will now stop further processing if an exception or failure occurred
430     * during processing of an {@link org.apache.camel.Exchange} and the caused
431     * exception will be thrown.
432     * <p/>
433     * Will also stop if processing the exchange failed (has a fault message) or
434     * an exception was thrown and handled by the error handler (such as using
435     * onException). In all situations the splitter will stop further
436     * processing. This is the same behavior as in pipeline, which is used by
437     * the routing engine.
438     * <p/>
439     * The default behavior is to <b>not</b> stop but continue processing till
440     * the end
441     *
442     * @return the builder
443     */
444    public SplitDefinition stopOnException(String stopOnException) {
445        setStopOnException(stopOnException);
446        return this;
447    }
448
449    /**
450     * To use a custom Thread Pool to be used for parallel processing. Notice if
451     * you set this option, then parallel processing is automatic implied, and
452     * you do not have to enable that option as well.
453     */
454    @Override
455    public SplitDefinition executorService(ExecutorService executorService) {
456        setExecutorService(executorService);
457        return this;
458    }
459
460    /**
461     * Refers to a custom Thread Pool to be used for parallel processing. Notice
462     * if you set this option, then parallel processing is automatic implied,
463     * and you do not have to enable that option as well.
464     */
465    @Override
466    public SplitDefinition executorServiceRef(String executorServiceRef) {
467        setExecutorServiceRef(executorServiceRef);
468        return this;
469    }
470
471    /**
472     * Uses the {@link Processor} when preparing the
473     * {@link org.apache.camel.Exchange} to be send. This can be used to
474     * deep-clone messages that should be send, or any custom logic needed
475     * before the exchange is send.
476     *
477     * @param onPrepare the processor
478     * @return the builder
479     */
480    public SplitDefinition onPrepare(Processor onPrepare) {
481        setOnPrepare(onPrepare);
482        return this;
483    }
484
485    /**
486     * Uses the {@link Processor} when preparing the
487     * {@link org.apache.camel.Exchange} to be send. This can be used to
488     * deep-clone messages that should be send, or any custom logic needed
489     * before the exchange is send.
490     *
491     * @param onPrepareRef reference to the processor to lookup in the
492     *            {@link org.apache.camel.spi.Registry}
493     * @return the builder
494     */
495    public SplitDefinition onPrepareRef(String onPrepareRef) {
496        setOnPrepareRef(onPrepareRef);
497        return this;
498    }
499
500    /**
501     * Sets a total timeout specified in millis, when using parallel processing.
502     * If the Splitter hasn't been able to split and process all the sub
503     * messages within the given timeframe, then the timeout triggers and the
504     * Splitter breaks out and continues. Notice if you provide a
505     * TimeoutAwareAggregationStrategy then the timeout method is invoked before
506     * breaking out. If the timeout is reached with running tasks still
507     * remaining, certain tasks for which it is difficult for Camel to shut down
508     * in a graceful manner may continue to run. So use this option with a bit
509     * of care.
510     *
511     * @param timeout timeout in millis
512     * @return the builder
513     */
514    public SplitDefinition timeout(long timeout) {
515        return timeout(Long.toString(timeout));
516    }
517
518    /**
519     * Sets a total timeout specified in millis, when using parallel processing.
520     * If the Splitter hasn't been able to split and process all the sub
521     * messages within the given timeframe, then the timeout triggers and the
522     * Splitter breaks out and continues. Notice if you provide a
523     * TimeoutAwareAggregationStrategy then the timeout method is invoked before
524     * breaking out. If the timeout is reached with running tasks still
525     * remaining, certain tasks for which it is difficult for Camel to shut down
526     * in a graceful manner may continue to run. So use this option with a bit
527     * of care.
528     *
529     * @param timeout timeout in millis
530     * @return the builder
531     */
532    public SplitDefinition timeout(String timeout) {
533        setTimeout(timeout);
534        return this;
535    }
536
537    /**
538     * Shares the {@link org.apache.camel.spi.UnitOfWork} with the parent and
539     * each of the sub messages. Splitter will by default not share unit of work
540     * between the parent exchange and each splitted exchange. This means each
541     * splitted exchange has its own individual unit of work.
542     *
543     * @return the builder.
544     */
545    public SplitDefinition shareUnitOfWork() {
546        return shareUnitOfWork(true);
547    }
548
549    /**
550     * Shares the {@link org.apache.camel.spi.UnitOfWork} with the parent and
551     * each of the sub messages. Splitter will by default not share unit of work
552     * between the parent exchange and each splitted exchange. This means each
553     * splitted exchange has its own individual unit of work.
554     *
555     * @return the builder.
556     */
557    public SplitDefinition shareUnitOfWork(boolean shareUnitOfWork) {
558        return shareUnitOfWork(Boolean.toString(shareUnitOfWork));
559    }
560
561    /**
562     * Shares the {@link org.apache.camel.spi.UnitOfWork} with the parent and
563     * each of the sub messages. Splitter will by default not share unit of work
564     * between the parent exchange and each splitted exchange. This means each
565     * splitted exchange has its own individual unit of work.
566     *
567     * @return the builder.
568     */
569    public SplitDefinition shareUnitOfWork(String shareUnitOfWork) {
570        setShareUnitOfWork(shareUnitOfWork);
571        return this;
572    }
573
574    // Properties
575    // -------------------------------------------------------------------------
576
577    /**
578     * Expression of how to split the message body, such as as-is, using a
579     * tokenizer, or using an xpath.
580     */
581    @Override
582    public void setExpression(ExpressionDefinition expression) {
583        // override to include javadoc what the expression is used for
584        super.setExpression(expression);
585    }
586
587    public AggregationStrategy getAggregationStrategy() {
588        return aggregationStrategy;
589    }
590
591    /**
592     * Sets the AggregationStrategy to be used to assemble the replies from the
593     * splitted messages, into a single outgoing message from the Splitter. By
594     * default Camel will use the original incoming message to the splitter
595     * (leave it unchanged). You can also use a POJO as the AggregationStrategy
596     */
597    public void setAggregationStrategy(AggregationStrategy aggregationStrategy) {
598        this.aggregationStrategy = aggregationStrategy;
599    }
600
601    public String getParallelProcessing() {
602        return parallelProcessing;
603    }
604
605    public void setParallelProcessing(String parallelProcessing) {
606        this.parallelProcessing = parallelProcessing;
607    }
608
609    public String getStreaming() {
610        return streaming;
611    }
612
613    public void setStreaming(String streaming) {
614        this.streaming = streaming;
615    }
616
617    public String getParallelAggregate() {
618        return parallelAggregate;
619    }
620
621    public void setParallelAggregate(String parallelAggregate) {
622        this.parallelAggregate = parallelAggregate;
623    }
624
625    public String getStopOnAggregateException() {
626        return this.stopOnAggregateException;
627    }
628
629    public void setStopOnAggregateException(String stopOnAggregateException) {
630        this.stopOnAggregateException = stopOnAggregateException;
631    }
632
633    public String getStopOnException() {
634        return stopOnException;
635    }
636
637    public void setStopOnException(String stopOnException) {
638        this.stopOnException = stopOnException;
639    }
640
641    @Override
642    public ExecutorService getExecutorService() {
643        return executorService;
644    }
645
646    @Override
647    public void setExecutorService(ExecutorService executorService) {
648        this.executorService = executorService;
649    }
650
651    public String getStrategyRef() {
652        return strategyRef;
653    }
654
655    /**
656     * Sets a reference to the AggregationStrategy to be used to assemble the
657     * replies from the splitted messages, into a single outgoing message from
658     * the Splitter. By default Camel will use the original incoming message to
659     * the splitter (leave it unchanged). You can also use a POJO as the
660     * AggregationStrategy
661     */
662    public void setStrategyRef(String strategyRef) {
663        this.strategyRef = strategyRef;
664    }
665
666    public String getStrategyMethodName() {
667        return strategyMethodName;
668    }
669
670    /**
671     * This option can be used to explicit declare the method name to use, when
672     * using POJOs as the AggregationStrategy.
673     */
674    public void setStrategyMethodName(String strategyMethodName) {
675        this.strategyMethodName = strategyMethodName;
676    }
677
678    public String getStrategyMethodAllowNull() {
679        return strategyMethodAllowNull;
680    }
681
682    /**
683     * If this option is false then the aggregate method is not used if there
684     * was no data to enrich. If this option is true then null values is used as
685     * the oldExchange (when no data to enrich), when using POJOs as the
686     * AggregationStrategy
687     */
688    public void setStrategyMethodAllowNull(String strategyMethodAllowNull) {
689        this.strategyMethodAllowNull = strategyMethodAllowNull;
690    }
691
692    @Override
693    public String getExecutorServiceRef() {
694        return executorServiceRef;
695    }
696
697    @Override
698    public void setExecutorServiceRef(String executorServiceRef) {
699        this.executorServiceRef = executorServiceRef;
700    }
701
702    public String getTimeout() {
703        return timeout;
704    }
705
706    public void setTimeout(String timeout) {
707        this.timeout = timeout;
708    }
709
710    public String getOnPrepareRef() {
711        return onPrepareRef;
712    }
713
714    public void setOnPrepareRef(String onPrepareRef) {
715        this.onPrepareRef = onPrepareRef;
716    }
717
718    public Processor getOnPrepare() {
719        return onPrepare;
720    }
721
722    public void setOnPrepare(Processor onPrepare) {
723        this.onPrepare = onPrepare;
724    }
725
726    public String getShareUnitOfWork() {
727        return shareUnitOfWork;
728    }
729
730    public void setShareUnitOfWork(String shareUnitOfWork) {
731        this.shareUnitOfWork = shareUnitOfWork;
732    }
733
734}