com.github.dm.jrt.object.JRoutineObject Maven / Gradle / Ivy
/*
* Copyright 2016 Davide Maestroni
*
* 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.github.dm.jrt.object;
import com.github.dm.jrt.core.util.ConstantConditions;
import com.github.dm.jrt.object.builder.ObjectRoutineBuilder;
import org.jetbrains.annotations.NotNull;
/**
* This utility class provides an additional way to build a routine, 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 library functionality 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.
*
* Some usage examples
*
* Example 1: Asynchronously get the output of two routines.
*
*
*
* public interface AsyncCallback {
*
* public void onResults(
* @AsyncInput(Result.class) Channel<?, Result> result1,
* @AsyncInput(Result.class) Channel<?, Result> result2);
* }
*
* final AsyncCallback callback = JRoutineObject.with(instance(myCallback))
* .buildProxy(AsyncCallback.class);
* callback.onResults(routine1.call(), routine2.call());
*
*
* Where the object myCallback
implements a method
* public void onResults(Result result1, Result result2)
.
*
* Created by davide-maestroni on 09/07/2014.
*
* @see
* Annotations
*/
public class JRoutineObject {
/**
* Avoid explicit instantiation.
*/
protected JRoutineObject() {
ConstantConditions.avoid();
}
/**
* Returns a routine builder wrapping 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.
*
* Note also that the invocation input data will be cached, and the results will be produced
* only after the invocation channel is closed, so be sure to avoid streaming inputs in order to
* prevent starvation or out of memory errors.
*
* @param target the invocation target.
* @return the routine builder instance.
* @throws java.lang.IllegalArgumentException if the specified object class represents an
* interface.
*/
@NotNull
public static ObjectRoutineBuilder with(@NotNull final InvocationTarget> target) {
return new DefaultObjectRoutineBuilder(target);
}
}