// none found
if (updateMethods.size() == 0)
{
String message = "Subscriber object does not provide a public method by name 'update'";
throw new EPSubscriberException(message);
}
// match to parameters
boolean isMapArrayDelivery = false;
boolean isObjectArrayDelivery = false;
boolean isSingleRowMap = false;
boolean isSingleRowObjectArr = false;
boolean isTypeArrayDelivery = false;
// find an exact-matching method: no conversions and not even unboxing/boxing
for (Method method : updateMethods)
{
Class[] parameters = method.getParameterTypes();
if (parameters.length == selectClauseTypes.length) {
boolean fits = true;
for (int i = 0; i < parameters.length; i++) {
if ((selectClauseTypes[i] != null) && (selectClauseTypes[i] != parameters[i])) {
fits = false;
break;
}
}
if (fits) {
subscriptionMethod = method;
break;
}
}
}
// when not yet resolved, find an exact-matching method with boxing/unboxing
if (subscriptionMethod == null) {
for (Method method : updateMethods)
{
Class[] parameters = method.getParameterTypes();
if (parameters.length == selectClauseTypes.length) {
boolean fits = true;
for (int i = 0; i < parameters.length; i++) {
Class boxedExpressionType = JavaClassHelper.getBoxedType(selectClauseTypes[i]);
Class boxedParameterType = JavaClassHelper.getBoxedType(parameters[i]);
if ((boxedExpressionType != null) && (boxedExpressionType != boxedParameterType)) {
fits = false;
break;
}
}
if (fits) {
subscriptionMethod = method;
break;
}
}
}
}
// when not yet resolved, find assignment-compatible methods that may require widening (including Integer to Long etc.)
boolean checkWidening = false;
if (subscriptionMethod == null) {
for (Method method : updateMethods) {
Class[] parameters = method.getParameterTypes();
if (parameters.length == selectClauseTypes.length) {
boolean fits = true;
for (int i = 0; i < parameters.length; i++) {
Class boxedExpressionType = JavaClassHelper.getBoxedType(selectClauseTypes[i]);
Class boxedParameterType = JavaClassHelper.getBoxedType(parameters[i]);
if ((boxedExpressionType != null) && (!JavaClassHelper.isAssignmentCompatible(boxedExpressionType, boxedParameterType))) {
fits = false;
break;
}
}
if (fits) {
subscriptionMethod = method;
checkWidening = true;
break;
}
}
}
}
// when not yet resolved, find first-fit wildcard method
if (subscriptionMethod == null) {
for (Method method : updateMethods)
{
Class[] parameters = method.getParameterTypes();
if ((parameters.length == 1) && (parameters[0] == Map.class))
{
isSingleRowMap = true;
subscriptionMethod = method;
break;
}
if ((parameters.length == 1) && (parameters[0] == Object[].class))
{
isSingleRowObjectArr = true;
subscriptionMethod = method;
break;
}
if ((parameters.length == 2) && (parameters[0] == Map[].class) && (parameters[1] == Map[].class))
{
subscriptionMethod = method;
isMapArrayDelivery = true;
break;
}
if ((parameters.length == 2) && (parameters[0] == Object[][].class) && (parameters[1] == Object[][].class))
{
subscriptionMethod = method;
isObjectArrayDelivery = true;
break;
}
// Handle uniform underlying or column type array dispatch
if ((parameters.length == 2) && (parameters[0].equals(parameters[1])) && (parameters[0].isArray())
&& (selectClauseTypes.length == 1))
{
Class componentType = parameters[0].getComponentType();
if (JavaClassHelper.isAssignmentCompatible(selectClauseTypes[0], componentType))
{
subscriptionMethod = method;
isTypeArrayDelivery = true;
break;
}
}
if ((parameters.length == 0) && (selectClauseTypes.length == 1) && (selectClauseTypes[0] == null)) {
subscriptionMethod = method;
}
}
}
if (subscriptionMethod == null)
{
if (updateMethods.size() > 1)
{
String parametersDesc = JavaClassHelper.getParameterAsString(selectClauseTypes);
String message = "No suitable subscriber method named 'update' found, expecting a method that takes " +
selectClauseTypes.length + " parameter of type " + parametersDesc;
throw new EPSubscriberException(message);
}
else
{
Class[] parameters = updateMethods.get(0).getParameterTypes();
String parametersDesc = JavaClassHelper.getParameterAsString(selectClauseTypes);
if (parameters.length != selectClauseTypes.length)
{
if (selectClauseTypes.length > 0) {
String message = "No suitable subscriber method named 'update' found, expecting a method that takes " +
selectClauseTypes.length + " parameter of type " + parametersDesc;
throw new EPSubscriberException(message);
}
else {
String message = "No suitable subscriber method named 'update' found, expecting a method that takes no parameters";
throw new EPSubscriberException(message);
}
}
for (int i = 0; i < parameters.length; i++)
{
Class boxedExpressionType = JavaClassHelper.getBoxedType(selectClauseTypes[i]);
Class boxedParameterType = JavaClassHelper.getBoxedType(parameters[i]);
if ((boxedExpressionType != null) && (!JavaClassHelper.isAssignmentCompatible(boxedExpressionType, boxedParameterType)))
{
String message = "Subscriber method named 'update' for parameter number " + (i + 1) + " is not assignable, " +
"expecting type '" + JavaClassHelper.getParameterAsString(selectClauseTypes[i]) + "' but found type '"
+ JavaClassHelper.getParameterAsString(parameters[i]) + "'";
throw new EPSubscriberException(message);
}
}
}
}