Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.sf.staccatocommons.dynamic.Dynamic Maven / Gradle / Ivy
/*
Copyright (c) 2011, The Staccato-Commons Team
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
*/
package net.sf.staccatocommons.dynamic;
import net.sf.staccatocommons.defs.Thunk;
import net.sf.staccatocommons.restrictions.check.NonNull;
/**
* {@link Dynamic}s are wrapper objects that are capable of receiving any
* message, and determine on runtime which method of the wrapped objecy will be
* actually evaluated.
*
* If there is no method matching the message, errors will not occur in compile
* time, but in runtime - a {@link MessageNotUnderstoodException} will be thrown
*
* @author flbulgarelli
*
*/
public interface Dynamic extends Thunk {
/**
* Sends a message to this {@link Dynamic}, and returns the message result
*
* If there is no method matching for the given selector and argument count
* and types, the message is said to not being understood and a
* {@link MessageNotUnderstoodException} is thrown
*
* If there exists more than one method matching the given selector and
* arguments count and types, Dynamic makes no assumptions about which one
* will be evaluated.
*
* @param
* @param selector
* the message name
* @param args
* the message arguments
* @return the message result
* @throws MessageNotUnderstoodException
* if this dynamic object does not understand the given message
* @throws MethodEvaluationException
* if a matching method exists, but its evaluation threw a an
* exception. The original exception is its cause
*/
T send(@NonNull final String selector, @NonNull final Object... args);
/**
* Sends a message to this {@link Dynamic}, as defined by
* {@link #send(String, Object...)}, and returns the message result wrapped as
* a dynamic, or Dynamics.null_()
, if the result was
* null
.
*
* If the message is not understood, instead of throwing an exception, this
* method returns the null dynamic.
*
* This method makes chaining dynamic methods easier. Example:
*
*
* Dynamics.from(anObject).$("getFoo").$("getBar").$("getBaz").value()
*
*
* This will return the messages chain result, or null, if any message of the
* chain returned null or was not understood
*
* @param selector
* @param args
* @return the null dynamic if the message was not understood or if answered
* null
. The message result, wrapped as a Dynamic,
* otherwise.
* @throws MethodEvaluationException
* if a matching method exists, but its evaluation threw a an
* exception. The original exception is its cause
* @see Dynamics#null_()
*/
@NonNull
Dynamic chainingSend(@NonNull String selector, @NonNull Object... args);
/**
* Synonym for {@link #chainingSend(String, Object...)}
*
* @param selector
* @param args
* @return {@link #chainingSend(String, Object...)}
*/
@NonNull
Dynamic $(@NonNull String selector, @NonNull Object... args);
/**
* Asynchronously sends a message to this dynamic object by returning a thunk
* that, when evaluated, performs the actual message passing
*
* @param
* @param selector
* the message selector
* @param args
* the message arguments
* @return a thunk that, when evaluted, will send the given message
*/
@NonNull
Thunk delayedSend(@NonNull final String selector, @NonNull final Object... args);
/**
* "casts" this dynamic to the desired type, by returning the wrapped value,
* if it can be casted to the given class, or by returning a proxy that
* forwards messages to {@link #send(String, Object...)}, otherwise.
*
* Methods must throw {@link ClassCastException} if the
* actual returned value of the dynamic can not be cast the the returned value
* of the method, and {@link NullPointerException} if null is returned when a
* primitive return type is expected
*
* @param
* @param clazz
* @return a new proxy of the given type, that forwards messages to this
* {@link Dynamic}
*/
@NonNull
T as(@NonNull Class clazz);
/**
* "casts" this dynamic to the desired type, by returning the wrapped value,
* if it can be casted to the given class, or by returning a proxy that
* forwards messages to {@link #chainingSend(String, Object...)}, casting with
* {@link #chainingAs(Class)} the result to the desired method return type,
* otherwise.
*
* Methods must throw {@link NullPointerException} if null is
* returned when a primitive return type is expected
*
* @param
* @param clazz
* @return a new proxy of the given type, that forwards messages to this
* {@link Dynamic}
*/
@NonNull
T chainingAs(@NonNull Class clazz);
/**
* The wrapped value
*/
Object value();
}