Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package com.gh.bmd.jrt.routine;
 
 
This utility class represents the entry point to the framework functionalities by acting as a factory of routine builders.

There are mainly two ways to create a routine object:

Routine by invocation customization
The first approach consists in implementing an invocation object.

Routine by method invocation
The second approach is based on the asynchronous invocation of a method of an existing class or object via reflection.
It is possible to annotate selected methods to be asynchronously invoked, or to simply select a method through its signature. It is also possible to build a proxy object whose methods will in turn asynchronously invoke the target object ones.
Note that a proxy object can be simply defined as an interface implemented by the target, but also as a completely unrelated one mirroring the target methods. In this way it is possible to apply the framework functionalities to objects defined by third party libraries which are not under direct control.
A mirror interface adds the possibility to override input and output parameters with output channels, so that data are transferred asynchronously, avoiding the need to block execution while waiting for them to be available.
Finally, it also possible to create a wrapper class to enable asynchronous invocation of methods, through annotation pre-processing and compile-time code generation. In order to activate the processing of annotations, it is simply necessary to include the "jroutine-processor" artifact or module in the project dependencies.

This class provides also a way to build standalone channel instances, which can be used to pass data without the need to start a routine invocation.

Some usage examples

Example 1: Asynchronously merge the output of two routines.

     

         final StandaloneChannel<Result> channel = JRoutine.standalone().buildChannel();

         channel.input()
                .pass(doSomething1.callAsync())
                .pass(doSomething2.callAsync())
                .close();
         channel.output()
                .eventually()
                .readAllInto(results);
     
 
Or simply:
     

         final OutputChannel<Result> output1 = doSomething1.callAsync();
         final OutputChannel<Result> output2 = doSomething2.callAsync();

         output1.eventually().readAllInto(results);
         output2.eventually().readAllInto(results);
     
 
(Note that, the order of the input or the output of the routine is not guaranteed unless the proper builder methods are called)

Example 2: Asynchronously concatenate the output of two routines.

     

         doSomething1.callAsync(doSomething2.callAsync())).eventually().readAllInto(results);
     
 

Example 3: Asynchronously get the output of two routines.

     

         public interface AsyncCallback {

             public void onResults(
                  @Pass(Result.class) OutputChannel<Result> result1,
                  @Pass(Result.class) OutputChannel<Result> result2);
         }

         final AsyncCallback callback = JRoutine.on(myCallback)
                                                .buildProxy(AsyncCallback.class);

         callback.onResults(doSomething1.callAsync(), doSomething2.callAsync());
     
 
Where the object myCallback implements a method public void onResults(Result result1, Result result2).

Example 4: Asynchronously feed a routine from a different thread.

     

         final StandaloneChannel<Result> channel = JRoutine.standalone().buildChannel();

         new Thread() {

             @Override
             public void run() {

                 channel.input().pass(new Result()).close();
             }

         }.start();

         final Routine<Result, Result> routine =
                  JRoutine.<Result>on(PassingInvocation.<Result>factoryOf())
                          .buildRoutine();

         routine.callAsync(channel.output()).eventually().readAllInto(results);
     
 

Created by davide on 9/7/14.

public class JRoutine {

    
Avoid direct instantiation.
    protected JRoutine() {
    }

    
Returns a routine builder wrapping the specified target class.

Parameters:
target the target class.
Returns:
the routine builder instance.
Throws:
java.lang.IllegalArgumentException if a duplicate name in the annotations is detected.
java.lang.NullPointerException if the specified target is null.
    @Nonnull
    public static ClassRoutineBuilder on(@Nonnull final Class<?> target) {
        return new DefaultClassRoutineBuilder(target);
    }

    
Returns a routine builder based on the specified invocation factory.

The invocation instance is created only when needed, by passing the specified arguments to the constructor. Note that the arguments objects should be immutable or, at least, never shared inside and outside the routine in order to avoid concurrency issues.

Parameters:
factory the invocation factory.
<INPUT> the input data type.
<OUTPUT> the output data type.
Returns:
the routine builder instance.
Throws:
java.lang.NullPointerException if the specified factory is null.
    @Nonnull
    public static <INPUT, OUTPUT> RoutineBuilder<INPUT, OUTPUT> on(
            @Nonnull final InvocationFactory<INPUT, OUTPUT> factory) {
        return new DefaultRoutineBuilder<INPUT, OUTPUT>(factory);
    }

    
Returns a routine builder based on the specified invocation class token.

The invocation instance is created through reflection only when needed.

Parameters:
token the invocation class token.
<INPUT> the input data type.
<OUTPUT> the output data type.
Returns:
the routine builder instance.
Throws:
java.lang.NullPointerException if the specified factory is null.
    @Nonnull
    public static <INPUT, OUTPUT> RoutineBuilder<INPUT, OUTPUT> on(
            @Nonnull final ClassToken<? extends Invocation<INPUT, OUTPUT>> token) {
        return on(Invocations.factoryOf(token));
    }

    
Returns a routine builder wrapping a weak reference to the specified target object.
Note that it is responsibility of the caller to retain a strong reference to the target instance to prevent it from being garbage collected.

Parameters:
target the target object.
Returns:
the routine builder instance.
Throws:
java.lang.IllegalArgumentException if a duplicate name in the annotations is detected.
java.lang.NullPointerException if the specified target is null.
    @Nonnull
    public static ObjectRoutineBuilder on(@Nonnull final Object target) {
        return new DefaultObjectRoutineBuilder(target);
    }

    
Returns a routine builder based on the specified function.
The inputs will be passed to the function only when the invocation completes, so, it is up to the caller to verify that the correct number of parameters is passed to the input channel in order to avoid unexpected behaviors.

Note that the function object must be stateless in order to avoid concurrency issues.

Parameters:
function the function instance.
<OUTPUT> the output data type.
Returns:
the builder instance.
Throws:
java.lang.NullPointerException if the specified function is null.
    @Nonnull
    public static <OUTPUT> RoutineBuilder<Void, OUTPUT> onFunction(
            @Nonnull final Function0<? extends OUTPUT> function) {
        return FunctionRoutineBuilder.fromFunction(function);
    }

    
Returns a routine builder based on the specified function.
The inputs will be passed to the function only when the invocation completes, so, it is up to the caller to verify that the correct number of parameters is passed to the input channel in order to avoid unexpected behaviors.

Note that the function object must be stateless in order to avoid concurrency issues.

Parameters:
function the function instance.
<INPUT> the input data type.
<OUTPUT> the output data type.
Returns:
the builder instance.
Throws:
java.lang.NullPointerException if the specified function is null.
    @Nonnull
    public static <INPUT, OUTPUT> RoutineBuilder<INPUT, OUTPUT> onFunction(
            @Nonnull final Function1<INPUT, ? extends OUTPUT> function) {
        return FunctionRoutineBuilder.fromFunction(function);
    }

    
Returns a routine builder based on the specified function.
The inputs will be passed to the function only when the invocation completes, so, it is up to the caller to verify that the correct number of parameters is passed to the input channel in order to avoid unexpected behaviors.

Note that the function object must be stateless in order to avoid concurrency issues.

Parameters:
function the function instance.
<INPUT> the input data type.
<INPUT1> the first parameter type.
<INPUT2> the second parameter type.
<OUTPUT> the output data type.
Returns:
the builder instance.
Throws:
java.lang.NullPointerException if the specified function is null.
    @Nonnull
    public static <INPUT, INPUT1 extends INPUT, INPUT2 extends INPUT, OUTPUT>
    RoutineBuilder<INPUT, OUTPUT> onFunction(
            @Nonnull final Function2<INPUT1, INPUT2, ? extends OUTPUT> function) {
        return FunctionRoutineBuilder.fromFunction(function);
    }

    
Returns a routine builder based on the specified function.
The inputs will be passed to the function only when the invocation completes, so, it is up to the caller to verify that the correct number of parameters is passed to the input channel in order to avoid unexpected behaviors.

Note that the function object must be stateless in order to avoid concurrency issues.

Parameters:
function the function instance.
<INPUT> the input data type.
<INPUT1> the first parameter type.
<INPUT2> the second parameter type.
<INPUT3> the third parameter type.
<OUTPUT> the output data type.
Returns:
the builder instance.
Throws:
java.lang.NullPointerException if the specified function is null.
    @Nonnull
    public static <INPUT, INPUT1 extends INPUT, INPUT2 extends INPUT, INPUT3 extends INPUT,
            OUTPUT> RoutineBuilder<INPUT, OUTPUT> onFunction(
            @Nonnull final Function3<INPUT1, INPUT2, INPUT3, ? extends OUTPUT> function) {
        return FunctionRoutineBuilder.fromFunction(function);
    }

    
Returns a routine builder based on the specified function.
The inputs will be passed to the function only when the invocation completes, so, it is up to the caller to verify that the correct number of parameters is passed to the input channel in order to avoid unexpected behaviors.

Note that the function object must be stateless in order to avoid concurrency issues.

Parameters:
function the function instance.
<INPUT> the input data type.
<INPUT1> the first parameter type.
<INPUT2> the second parameter type.
<INPUT3> the third parameter type.
<INPUT4> the fourth parameter type.
<OUTPUT> the output data type.
Returns:
the builder instance.
Throws:
java.lang.NullPointerException if the specified function is null.
    @Nonnull
    public static <INPUT, INPUT1 extends INPUT, INPUT2 extends INPUT, INPUT3 extends INPUT,
            INPUT4 extends INPUT, OUTPUT> RoutineBuilder<INPUT, OUTPUT> onFunction(
            @Nonnull final Function4<INPUT1, INPUT2, INPUT3, INPUT4, ? extends OUTPUT> function) {
        return FunctionRoutineBuilder.fromFunction(function);
    }

    
Returns a routine builder based on the specified function.
The inputs will be passed to the function only when the invocation completes, so, it is up to the caller to verify that the correct number of parameters is passed to the input channel in order to avoid unexpected behaviors.

Note that the function object must be stateless in order to avoid concurrency issues.

Parameters:
function the function instance.
<INPUT> the input data type.
<OUTPUT> the output data type.
Returns:
the builder instance.
Throws:
java.lang.NullPointerException if the specified function is null.
    @Nonnull
    public static <INPUT, OUTPUT> RoutineBuilder<INPUT, OUTPUT> onFunction(
            @Nonnull final FunctionN<INPUT, ? extends OUTPUT> function) {
        return FunctionRoutineBuilder.fromFunction(function);
    }

    
Returns a routine builder based on the specified procedure.
The inputs will be passed to the procedure only when the invocation completes, so, it is up to the caller to verify that the correct number of parameters is passed to the input channel in order to avoid unexpected behaviors.
The procedure output will be discarded.

Note that the procedure object must be stateless in order to avoid concurrency issues.

Parameters:
procedure the procedure instance.
Returns:
the builder instance.
Throws:
java.lang.NullPointerException if the specified procedure is null.
    @Nonnull
    public static RoutineBuilder<VoidVoidonProcedure(@Nonnull final Function0<Voidprocedure) {
        return FunctionRoutineBuilder.fromProcedure(procedure);
    }

    
Returns a routine builder based on the specified procedure.
The inputs will be passed to the procedure only when the invocation completes, so, it is up to the caller to verify that the correct number of parameters is passed to the input channel in order to avoid unexpected behaviors.
The procedure output will be discarded.

Note that the procedure object must be stateless in order to avoid concurrency issues.

Parameters:
procedure the procedure instance.
<INPUT> the input data type.
<INPUT1> the first parameter type.
Returns:
the builder instance.
Throws:
java.lang.NullPointerException if the specified procedure is null.
    @Nonnull
    public static <INPUT, INPUT1 extends INPUT> RoutineBuilder<INPUT, VoidonProcedure(
            @Nonnull final Function1<INPUT1, Voidprocedure) {
        return FunctionRoutineBuilder.fromProcedure(procedure);
    }

    
Returns a routine builder based on the specified procedure.
The inputs will be passed to the procedure only when the invocation completes, so, it is up to the caller to verify that the correct number of parameters is passed to the input channel in order to avoid unexpected behaviors.
The procedure output will be discarded.

Note that the procedure object must be stateless in order to avoid concurrency issues.

Parameters:
procedure the procedure instance.
<INPUT> the input data type.
<INPUT1> the first parameter type.
<INPUT2> the second parameter type.
Returns:
the builder instance.
Throws:
java.lang.NullPointerException if the specified procedure is null.
    @Nonnull
    public static <INPUT, INPUT1 extends INPUT, INPUT2 extends INPUT> RoutineBuilder<INPUT, Void>
            @Nonnull final Function2<INPUT1, INPUT2, Voidprocedure) {
        return FunctionRoutineBuilder.fromProcedure(procedure);
    }

    
Returns a routine builder based on the specified procedure.
The inputs will be passed to the procedure only when the invocation completes, so, it is up to the caller to verify that the correct number of parameters is passed to the input channel in order to avoid unexpected behaviors.
The procedure output will be discarded.

Note that the procedure object must be stateless in order to avoid concurrency issues.

Parameters:
procedure the procedure instance.
<INPUT> the input data type.
<INPUT1> the first parameter type.
<INPUT2> the second parameter type.
<INPUT3> the third parameter type.
Returns:
the builder instance.
Throws:
java.lang.NullPointerException if the specified procedure is null.
    @Nonnull
    public static <INPUT, INPUT1 extends INPUT, INPUT2 extends INPUT, INPUT3 extends INPUT>
            @Nonnull final Function3<INPUT1, INPUT2, INPUT3, Voidprocedure) {
        return FunctionRoutineBuilder.fromProcedure(procedure);
    }

    
Returns a routine builder based on the specified procedure.
The inputs will be passed to the procedure only when the invocation completes, so, it is up to the caller to verify that the correct number of parameters is passed to the input channel in order to avoid unexpected behaviors.
The procedure output will be discarded.

Note that the procedure object must be stateless in order to avoid concurrency issues.

Parameters:
procedure the procedure instance.
<INPUT> the input data type.
<INPUT1> the first parameter type.
<INPUT2> the second parameter type.
<INPUT3> the third parameter type.
<INPUT4> the fourth parameter type.
Returns:
the builder instance.
Throws:
java.lang.NullPointerException if the specified procedure is null.
    @Nonnull
    public static <INPUT, INPUT1 extends INPUT, INPUT2 extends INPUT, INPUT3 extends INPUT,
            INPUT4 extends INPUT> RoutineBuilder<INPUT, VoidonProcedure(
            @Nonnull final Function4<INPUT1, INPUT2, INPUT3, INPUT4, Voidprocedure) {
        return FunctionRoutineBuilder.fromProcedure(procedure);
    }

    
Returns a routine builder based on the specified procedure.
The inputs will be passed to the procedure only when the invocation completes, so, it is up to the caller to verify that the correct number of parameters is passed to the input channel in order to avoid unexpected behaviors.
The procedure output will be discarded.

Note that the procedure object must be stateless in order to avoid concurrency issues.

Parameters:
procedure the procedure instance.
<INPUT> the input data type.
Returns:
the builder instance.
Throws:
java.lang.NullPointerException if the specified procedure is null.
    @Nonnull
    public static <INPUT> RoutineBuilder<INPUT, VoidonProcedure(
            @Nonnull final FunctionN<INPUT, Voidprocedure) {
        return FunctionRoutineBuilder.fromProcedure(procedure);
    }

    
Returns a standalone channel builder.

Returns:
the standalone channel builder instance.
    @Nonnull
    public static StandaloneChannelBuilder standalone() {
        return new DefaultStandaloneChannelBuilder();
    }
New to GrepCode? Check out our FAQ X