All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mockrunner.connector.IndexedRecordInteraction Maven / Gradle / Ivy

There is a newer version: 2.0.7
Show newest version
package com.mockrunner.connector;

import java.util.ArrayList;
import java.util.List;

import javax.resource.ResourceException;
import javax.resource.cci.IndexedRecord;
import javax.resource.cci.InteractionSpec;
import javax.resource.cci.Record;

import com.mockrunner.base.NestedApplicationException;
import com.mockrunner.mock.connector.cci.MockIndexedRecord;

/**
 * This interaction implementor works with indexed records. It takes a List for 
 * the request and a List or a Record instance for the response. 
 * If the request List is null, which is the default, 
 * the implementor accepts any  request and returns the specified result. If a request 
 * List is specified, this implementor accepts only requests that contain the same
 * data as the specified expected request List. The underlying lists are compared
 * as described in the List.equals method.
 * If a request is accepted, this implementor replies with the specified
 * response. You can use the various constructors and set methods
 * to configure the expected request and the response.
* Please check out the documentation of the various methods for details. */ public class IndexedRecordInteraction implements InteractionImplementor { private boolean enabled; private List expectedRequest; private List responseData; private Class responseClass; private Record responseRecord; /** * Sets the expected request and the response to null, * i.e. an empty response is returned for every request. */ public IndexedRecordInteraction() { this(null, null, MockIndexedRecord.class); } /** * Sets the expected request to null and prepares * the specified response List. The response class for the * {@link #execute(InteractionSpec,Record)} method is set * to the default {@link com.mockrunner.mock.connector.cci.MockIndexedRecord}. * It is allowed to pass null for the response List * which is equivalent to an empty response. * The specified response is returned for every request. * @param responseList the response List */ public IndexedRecordInteraction(List responseList) { this(null, responseList, MockIndexedRecord.class); } /** * Sets the specified expected request List and prepares * the specified response List. The response class for the * {@link #execute(InteractionSpec,Record)} method is set * to the default {@link com.mockrunner.mock.connector.cci.MockIndexedRecord}. * It is allowed to pass null for the request and response List * which is equivalent to an empty expected request (i.e. every request is accepted) * or to an empty response respectively. * The specified response is returned, if the actual request matches the specified expected * request. * @param expectedRequest the expected request ListList
null and prepares * the specified response List. The response class for the * {@link #execute(InteractionSpec,Record)} method is set * to the specified responseClass. The specified * responseClass must implement IndexedRecord, * otherwise an IllegalArgumentException will be thrown. * It is allowed to pass null for the response List * which is equivalent to an empty response. * The specified response is returned for every request. * @param responseList the response ListRecord class * @throws IllegalArgumentException if the responseClass * is not valid */ public IndexedRecordInteraction(List responseList, Class responseClass) { this(null, responseList, responseClass); } /** * Sets the specified expected request List and prepares * the specified response List. The response class for the * {@link #execute(InteractionSpec,Record)} method is set * to the specified responseClass. The specified * responseClass must implement IndexedRecord, * otherwise an IllegalArgumentException will be thrown. * It is allowed to pass null for the request and response List * which is equivalent to an empty expected request (i.e. every request is accepted) * or to an empty response respectively. * The specified response is returned, if the actual request matches the specified expected * request. * @param expectedRequest the expected request List * @param responseList the response List * @param responseClass the response Record class * @throws IllegalArgumentException if the responseClass * is not valid */ public IndexedRecordInteraction(List expectedRequest, List responseList, Class responseClass) { setExpectedRequest(expectedRequest); setResponse(responseList, responseClass); this.enabled = true; } /** * Sets the specified expected request List and the response * Record for the {@link #execute(InteractionSpec, Record)} * method. The response Record is ignored for * {@link #execute(InteractionSpec,Record,Record)} but takes precedence * over the specified response List for {@link #execute(InteractionSpec, Record)}. * It is allowed to pass null for the request and response Record * which is equivalent to an empty expected request (i.e. every request is accepted) * or to no specified response Record, i.e. the specified response * List is taken. * The specified response is returned, if the actual request matches the specified expected * request. * @param expectedRequest the expected request List * @param responseRecord the response Record */ public IndexedRecordInteraction(List expectedRequest, Record responseRecord) { setExpectedRequest(expectedRequest); setResponse(responseRecord); this.enabled = true; } /** * Sets the expected request to null and prepares the response * Record for the {@link #execute(InteractionSpec, Record)} * method. The response Record is ignored for * {@link #execute(InteractionSpec,Record,Record)} but takes precedence * over the specified response List for {@link #execute(InteractionSpec, Record)}. * It is allowed to pass null for the response Record * which is equivalent to no specified response Record, i.e. the specified response * List is taken. * The specified response is returned for every request. * @param responseRecord the response Record */ public IndexedRecordInteraction(Record responseRecord) { this(null, responseRecord); } /** * Enables this implementor. */ public void enable() { this.enabled = true; } /** * Disables this implementor. {@link #canHandle(InteractionSpec, Record, Record)} * always returns false, if this implementor is disabled. */ public void disable() { this.enabled = false; } /** * Sets the specified expected request List. The response is returned, * if the actual request matches the specified expected request List * according to List.equals. * It is allowed to pass null for the request List * which is equivalent to an empty expected request (i.e. every request * is accepted). * @param expectedRequest the expected request List */ public void setExpectedRequest(List expectedRequest) { if(null == expectedRequest) { this.expectedRequest = null; } else { this.expectedRequest = new ArrayList(expectedRequest); } } /** * Prepares the specified response List. The response class for the * {@link #execute(InteractionSpec,Record)} method is set * to the default {@link com.mockrunner.mock.connector.cci.MockIndexedRecord}. * It is allowed to pass null for the response List * which is equivalent to an empty response. * @param responseList the response ListList. The response class for the * {@link #execute(InteractionSpec,Record)} method is set * to the specified responseClass. The specified * responseClass must implement IndexedRecord, * otherwise an IllegalArgumentException will be thrown. * It is allowed to pass null for the response List * which is equivalent to an empty response. * @param responseList the response List * @param responseClass the response Record class * @throws IllegalArgumentException if the responseClass * is not valid */ public void setResponse(List responseList, Class responseClass) { if(!isResponseClassAcceptable(responseClass)) { throw new IllegalArgumentException("responseClass must implement " + IndexedRecord.class.getName()); } if(null == responseList) { this.responseData = null; } else { this.responseData = new ArrayList(responseList); } this.responseClass = responseClass; } /** * Prepares the response Record for the * {@link #execute(InteractionSpec, Record)} method. The response * Record is ignored for {@link #execute(InteractionSpec,Record,Record)} * but takes precedence over the specified response List for * {@link #execute(InteractionSpec, Record)}. * It is allowed to pass null for the response Record * which is equivalent to no specified response Record, i.e. the specified response * List is taken. * @param responseRecord the response Record */ public void setResponse(Record responseRecord) { this.responseRecord = responseRecord; } /** * Returns true if this implementor is enabled and will handle the request. * This method returns true if the following prerequisites are fulfilled:

* It is enabled.

* The response Record must implement IndexedRecord * or it must be null (which is the case, if the actual request * targets the {@link #execute(InteractionSpec,Record)} method instead of * {@link #execute(InteractionSpec,Record,Record)}).

* The expected request must be null (use the various * setExpectedRequest methods) or the actual request Record * must implement IndexedRecord and must contain the same data as * the specified expected request List according to List.equals.

* Otherwise, false is returned. * @param interactionSpec the InteractionSpec for the actual call * @param actualRequest the request for the actual call * @param actualResponse the response for the actual call, may be null * @return true if this implementor will handle the request and * will return the specified response, false otherwise */ public boolean canHandle(InteractionSpec interactionSpec, Record actualRequest, Record actualResponse) { if(!enabled) return false; if(!isResponseAcceptable(actualResponse)) return false; return doesRequestMatch(actualRequest); } private boolean doesRequestMatch(Record request) { if(null == expectedRequest) return true; if(null == request) return false; if(request instanceof IndexedRecord) { try { IndexedRecord indexedRequest = (IndexedRecord)request; if(indexedRequest.size() != expectedRequest.size()) return false; for(int ii = 0; ii < indexedRequest.size(); ii++) { Object actualValue = indexedRequest.get(ii); Object expectedValue = expectedRequest.get(ii); if(!areObjectsEquals(actualValue, expectedValue)) { return false; } } return true; } catch(Exception exc) { throw new NestedApplicationException(exc); } } return false; } private boolean areObjectsEquals(Object object1, Object object2) { if(null == object1 && null == object2) return true; if(null == object1) return false; return object1.equals(object2); } private boolean isResponseAcceptable(Record response) { return (null == response) || (response instanceof IndexedRecord); } private boolean isResponseClassAcceptable(Class responseClass) { return (null == responseClass) || (IndexedRecord.class.isAssignableFrom(responseClass)); } /** * First version of the execute methods.

* This method returns null, if the request does not match * according to the contract of {@link #canHandle}. This never happens under * normal conditions since the {@link InteractionHandler} does not call * execute, if {@link #canHandle} returns false. *

* Otherwise, this method returns the specified response. If a response * Record object is specified (use {@link #setResponse(Record)}), * it always takes precedence, i.e. the response List will be ignored. * If no Record object is specified, a Record object * is created and filled with the specified response List data. Use the * setResponse methods that take a List * to prepare the response List. The created Record is of the the * specified type (the setResponse method that takes a second * Class parameter allows for specifying a type). If no type * is specified, a {@link com.mockrunner.mock.connector.cci.MockIndexedRecord} * is created. If no response List is specified at all, an empty * {@link com.mockrunner.mock.connector.cci.MockIndexedRecord} * will be returned. * @param interactionSpec the interaction spec * @param actualRequest the actual request * @return the response according to the current request */ public Record execute(InteractionSpec interactionSpec, Record actualRequest) throws ResourceException { if(!canHandle(interactionSpec, actualRequest, null)) return null; if(null != responseRecord) return responseRecord; IndexedRecord response = null; try { if(null == responseClass) { response = new MockIndexedRecord(); } else { response = (IndexedRecord)responseClass.newInstance(); } if(null != responseData) { response.addAll(responseData); } } catch(Exception exc) { ResourceException resExc = new ResourceException("execute() failed"); resExc.setLinkedException(exc); throw resExc; } return (Record)response; } /** * Second version of the execute methods.

* This method returns false, if the request does not match * according to the contract of {@link #canHandle}. This never happens under * normal conditions since the {@link InteractionHandler} does not call * execute, if {@link #canHandle} returns false. *

* Otherwise, this method fills the response Record with the * specified response List data. Use the setResponse methods that * take a List to prepare the response List. * The response Record must implement IndexedRecord * (it does, otherwise the request would have been rejected by * {@link #canHandle}). If no response List is specified at all, * the response Record is not touched but true * is returned anyway * @param interactionSpec the interaction spec * @param actualRequest the actual request * @param actualResponse the actual response * @return true under normal conditions */ public boolean execute(InteractionSpec interactionSpec, Record actualRequest, Record actualResponse) throws ResourceException { if(!canHandle(interactionSpec, actualRequest, actualResponse)) return false; try { if(null != responseData && null != actualResponse) { ((IndexedRecord)actualResponse).clear(); ((IndexedRecord)actualResponse).addAll(responseData); } } catch(Exception exc) { ResourceException resExc = new ResourceException("execute() failed"); resExc.setLinkedException(exc); throw resExc; } return true; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy