package com.bansheeproject; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import com.bansheeproject.engine.BansheeDispatcher; import com.bansheeproject.engine.ExceptionParameter; import com.bansheeproject.engine.InvocationContext; import com.bansheeproject.engine.ObjectParameter; import com.bansheeproject.engine.ServiceParameter; import com.bansheeproject.engine.StringParameter; import com.bansheeproject.engine.converters.ObjectConverter; import com.bansheeproject.engine.converters.ObjectConverterFactory; import com.bansheeproject.exceptions.ServiceInvokeException; import com.bansheeproject.features.Feature; import com.bansheeproject.features.ServiceTimeout; import com.bansheeproject.log.BansheeLogFactory; import com.bansheeproject.log.BansheeLogger; /** * It is an abstraction of a service invocation. * * @author Alexandre Saudate * @since 1.0 */ public abstract class WebServicesInvocationData { private ServiceParameter serviceParameter; private ServiceData serviceData; private Set<Feature> features; private List<ExceptionParameter> exceptionTypes = new ArrayList<ExceptionParameter>(); private ObjectConverter objectConverter; private boolean handleExceptionAsString; private static BansheeLogger logger = BansheeLogFactory.getDefaultLogger(WebServicesInvocationData.class); public WebServicesInvocationData(ServiceData serviceData) { if (serviceData == null) { logger.warn("Trying to instantiate a WebServicesInvocationData with null service data. Throwing exception.."); throw new IllegalArgumentException("Service data cannot be null"); } this.serviceData = serviceData; this.features = new HashSet<Feature>(); this.objectConverter = ObjectConverterFactory.newInstance().newObjectConverter(); } protected ServiceParameter getServiceParameter() { return serviceParameter; } protected void setServiceParameter(ServiceParameter serviceParameter) { if (serviceParameter == null) throw new IllegalArgumentException("Service Parameter cannot be null."); this.serviceParameter = serviceParameter; } public void setStringParameter (String stringParameter) { if (stringParameter == null) throw new IllegalArgumentException("Parameter cannot be null."); setServiceParameter(new StringParameter(stringParameter)); } public void setObjectParameter (Object objectParameter, Class expectedResponseType) { if (objectParameter == null) throw new IllegalArgumentException("Object parameter cannot be null."); setServiceParameter(new ObjectParameter(objectParameter, expectedResponseType, getObjectConverter())); } public void setObjectParameter (Object objectParameter, Class expectedResponseType, ObjectConverter objectConverter) { if (objectParameter == null) throw new IllegalArgumentException("Object parameter cannot be null."); if (objectConverter == null) throw new IllegalArgumentException("Object converter cannot be null."); setServiceParameter(new ObjectParameter(objectParameter, expectedResponseType, objectConverter)); } public ServiceData getServiceData() { return this.serviceData; } protected void addFeature (Feature feature) { logger.debug(new StringBuilder("Inserting feature: ").append(feature)); if (feature == null) throw new IllegalArgumentException("You cannot add a null feature."); features.add(feature); } public void clearFeatures () { features.clear(); } public Collection<Feature> getFeatureSet() { Set<Feature> feature = new HashSet<Feature>(features); return feature; } public ObjectConverter getObjectConverter() { return objectConverter; } public void setObjectConverter(ObjectConverter objectConverter) { logger.debug(new StringBuilder("Setting object converter: ").append(objectConverter)); if (objectConverter == null) throw new IllegalArgumentException("The object converter cannot be null."); this.objectConverter = objectConverter; } public void addExceptionType (Class<?> exceptionData) { logger.debug(new StringBuilder("Adding exception type: ").append(exceptionData)); if (exceptionData == null) { logger.warn("Exception data is null. Throwing exception..."); throw new IllegalArgumentException("The exception type cannot be null."); } exceptionTypes.add(new ExceptionParameter(exceptionData, getObjectConverter())); } public void addExceptionType (Class<?> exceptionData, ObjectConverter converter) { logger.debug(new StringBuilder("Adding exception type: ").append(exceptionData)); if (exceptionData == null) { logger.warn("Exception data is null. Throwing exception..."); throw new IllegalArgumentException("The exception type cannot be null."); } exceptionTypes.add(new ExceptionParameter(exceptionData, converter)); } protected void addExceptionParameter(ExceptionParameter exceptionParameter) { if (exceptionParameter == null) { throw new IllegalArgumentException("Exception parameter cannot be null."); } exceptionTypes.add(exceptionParameter); } public Collection<Class<?>> listExceptionTypes() { Set<Class<?>> exceptions = new HashSet<Class<?>>(); for (ExceptionParameter param : listExceptionParameters()) { exceptions.add(param.getExpectedResponseType()); } return exceptions; } protected Collection<ExceptionParameter> listExceptionParameters() { return exceptionTypes; } public void clearExceptionTypes() { exceptionTypes.clear(); } public boolean isHandleExceptionAsString() { return handleExceptionAsString; } public void setHandleExceptionAsString(boolean handleExceptionAsString) { this.handleExceptionAsString = handleExceptionAsString; } public void setTimeout (long timeoutValue) { addFeature(new ServiceTimeout(timeoutValue)); } public Response invoke() throws ServiceInvokeException { if (getServiceData() == null) { throw new IllegalArgumentException("Service data has not been set."); } BansheeDispatcher dispatcher = getServiceData().getDispatcher(); String requestObject = buildRequestObject(); InvocationContext context = buildInvocationContext(dispatcher, requestObject); for (Feature feature : getFeatureSet()) { feature.install(context); } try { dispatcher = context.getDispatcher(); String response = dispatcher.invoke(context.getRequestData()); Response responseObject = buildResponseObject(response); return responseObject; } catch (Exception ex) { try { return buildExceptionResponse(ex); } catch (Exception e) { throw new ServiceInvokeException(ex); } } } protected abstract InvocationContext buildInvocationContext (BansheeDispatcher dispatcher, String requestObject); public Response invokeOneWay() throws ServiceInvokeException { BansheeDispatcher dispatcher = getServiceData().getDispatcher(); String requestData = buildRequestObject(); InvocationContext context = buildInvocationContext(dispatcher, requestData); try { for (Feature feature : getFeatureSet()) { feature.install(context); } dispatcher.invokeOneWay(context.getRequestData()); return null; } catch (Exception ex) { try { return buildExceptionResponse(ex); } catch (Exception e) { throw new ServiceInvokeException(ex); } } } protected abstract String buildRequestObject(); protected abstract Response buildResponseObject(String responseData); protected abstract Response buildExceptionResponse (Exception ex) throws Exception; }