Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
BERSERK - a BusinEss Runtime and SEcurity Resources Kit
Copyright (C) 2003 Gon?alo Luiz
This library 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; either
version 2.1 of the License, or (at your option) any later version.
This library 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.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
To contact Gon?alo Luiz use the following e-mail address (use an @ instead of the _):
gedl_mega.ist.utl.pt
*/
package pt.utl.ist.berserk.logic.serviceManager;
/**
* The abstract class that invokes an arbitrary method of a service. The
* subclasses of this class define the semantic of the invocation,
* e.g., none or transactional.
*
* @author Joao Pereira
* @version revision by Gon?alo Luiz (gedl \AT/ rnl \DOT/ ist \DOT/ utl \DOT/ pt) at October the 8th, 2003
**/
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import pt.utl.ist.berserk.logic.filterManager.IFilterBroker;
import pt.utl.ist.berserk.logic.serviceManager.exceptions.InvalidServiceException;
import pt.utl.ist.berserk.logic.serviceManager.exceptions.ServiceManagerException;
public abstract class ServiceInvoker
{
/**
* The service will simply be invoked
*/
public static final int NONE =
0;
/**
* The service will be invoked in a transactional environment provided by the used <code>ITransactionBroker</code>
* @see pt.utl.ist.berserk.storage.ITransactionBroker
*/
public static final int TRANSACTIONAL =
1;
/**
* Returns the instance of the ServiceInvoker class that handles the
* invocation of services with the specified semantic type.
* @param type the desired type invoker
* @return the ServiceInvoker that will handle the actuall invocation.
* @throws ServiceManagerException
**/
public static final ServiceInvoker getInvoker
(int type
) throws ServiceManagerException
{
switch (type
)
{
case NONE :
return SimpleServiceInvoker.
invocador;
case TRANSACTIONAL :
return TransactionalServiceInvoker.
invocador;
default :
throw new InvalidServiceException
("Invalid service invocation type: " + type
);
}
}
/**
* Returns the instance of the ServiceInvoker class that handles the
* invocation of transactional (or not) services.
* @param transactional wether the service should be invoked on a transactional environment
* @return the ServiceInvoker that will handle the actuall invocation.
* @throws ServiceManagerException
*/
public static final ServiceInvoker getInvoker
(boolean transactional
)
{
if (transactional
)
return TransactionalServiceInvoker.
invocador;
else
return SimpleServiceInvoker.
invocador;
}
/**
* Does the invocation of the service. It invokes the method called
* methodName of servico with parameters argumentos.
*
* @param service is the instance of IService to be executed.
* @param methodName is the name of the method to invoke.
* @param argumentos is the set of arguments to be used in the invocation
* of the service.
*
* @return the result of the invocation.
*
* @throws ServiceManagerException if something goes wrong.
* @throws ExecutedServiceException if the called service throws an exception
**/
final protected 5+0%2Fdocs%2Fapi+Object">Object doInvocation
(IService service,
1.5.0/docs/api/java/lang/String.html">String methodName,
5+0%2Fdocs%2Fapi+Object">Object arguments
[]) throws ServiceManagerException,
1.5.0/docs/api/java/lang/Throwable.html">Throwable
{
// The Java reflexion mewchanism does not handle the case where an angument type
// is null. In this case, the method is not found. To overcame this problem,
// we lookup all methods of the service with the desired name. If these is a single
// method, we call that method. Otherwise, we try to get the desired method given
// the types of the arguments. Notice that this may not work, if at least one of the
// arguments is null.
1.5.0/docs/api/java/lang/reflect/Method.html">Method method =
null;
int methodPos = -
1;
int i =
0;
try
{
1.5.0/docs/api/java/lang/reflect/Method.html">Method methods
[] = service.
getClass().
getMethods();
if (methods
!=
null)
for (i =
0; i
< methods.
length; i++
)
{
if (methods
[i
].
getName().
equals(methodName
))
if (methodPos == -1
)
methodPos = i
;
else
{
methodPos = -
2;
break;
}
}
if (methodPos
>= 0
)
method = methods
[methodPos
];
if (methodPos == -
1) // not found
throw new ServiceManagerException
(
"Cannot invoke service: "
+ service.
getClass()
+
". Method "
+ methodName
+
" does not exist.");
}
catch (1.5.0/docs/api/java/lang/SecurityException.html">SecurityException e
)
{
throw new ServiceManagerException
(
"Cannot execute method "
+ methodName
+
" of service: "
+ service.
getClass()
+
": "
+ e
);
}
if (methodPos == -
2)
{ // found, but there are several methods with the same name
try
{
1.5.0/docs/api/java/lang/Class.html">Class types
[] =
new 1.5.0/docs/api/java/lang/Class.html">Class[arguments
!=
null ? arguments.
length : 0
];
for (i =
0; i
< types.
length; i++
)
types
[i
] = arguments
[i
].
getClass();
method = service.
getClass().
getDeclaredMethod(methodName, types
);
}
catch (1.5.0/docs/api/java/lang/NoSuchMethodException.html">NoSuchMethodException e
)
{
throw new ServiceManagerException
(
"Cannot execute method run of service: " + service.
getClass() +
": " + e
);
}
catch (1.5.0/docs/api/java/lang/SecurityException.html">SecurityException e
)
{
throw new ServiceManagerException
(
"Cannot execute method run of service: " + service.
getClass() +
": " + e
);
}
}
// execute the service.
try
{
return method.
invoke(service, arguments
);
}
catch (1.5.0/docs/api/java/lang/IllegalAccessException.html">IllegalAccessException e
)
{
throw new ServiceManagerException
(
"Cannot access method run of service: " + service.
getClass() +
": " + e
);
}
catch (1.5.0/docs/api/java/lang/IllegalArgumentException.html">IllegalArgumentException e
)
{
throw new ServiceManagerException
(
"Cannot execute method run of service: " + service.
getClass() +
": " + e
);
}
catch (1.5.0/docs/api/java/lang/reflect/InvocationTargetException.html">InvocationTargetException e
)
{
{
throw e.
getTargetException();
}
}
}
/**
* Invokes the specified method on the specified <code>IService</code> class.
* @param requester the itentity that requests the service
* @param service the <code>IService</code> instance that will assure the execution of the service
* @param methodName the method that will be invoked on the provided <code>IService</code> instance.
* @param arguments the arguments that will be provided to filters and to the service
* @param filterBroker the <code>IFilterBroker</code> that will process this service's filter chains (if any)
* @return the return object of the service execution
* @throws ServiceManagerException if something goes wrong
* @throws ExecutedServiceException if the called service throws an exception
*/
public abstract 5+0%2Fdocs%2Fapi+Object">Object invoke
(
5+0%2Fdocs%2Fapi+Object">Object requester,
IService service,
1.5.0/docs/api/java/lang/String.html">String methodName,
5+0%2Fdocs%2Fapi+Object">Object arguments
[],
1.5.0/docs/api/java/lang/String.html">String names
[],
IFilterBroker filterBroker
)
throws ServiceManagerException,
1.5.0/docs/api/java/lang/Throwable.html">Throwable;
}