com.mockrunner.connector.IndexedRecordInteraction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mockrunner-jca Show documentation
Show all versions of mockrunner-jca Show documentation
Mock classes for Java Connector Architecture
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
null and prepares * the specified responseList
for * the request and aList
or aRecord
instance for the response. * If the requestList
isnull
, 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 requestList
. The underlying lists are compared * as described in theList.equals
method. * If a request is accepted, this implementor replies with the specified * response. You can use the various constructors andset
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 tonull
, * i.e. an empty response is returned for every request. */ public IndexedRecordInteraction() { this(null, null, MockIndexedRecord.class); } /** * Sets the expected request tonull
and prepares * the specified responseList
. 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 passnull
for the responseList
* which is equivalent to an empty response. * The specified response is returned for every request. * @param responseList the responseList
*/ public IndexedRecordInteraction(List responseList) { this(null, responseList, MockIndexedRecord.class); } /** * Sets the specified expected requestList
and prepares * the specified responseList
. 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 passnull
for the request and responseList
* 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 requestList
ListList
. The response class for the * {@link #execute(InteractionSpec,Record)} method is set * to the specifiedresponseClass
. The specified *responseClass
must implementIndexedRecord
, * otherwise anIllegalArgumentException
will be thrown. * It is allowed to passnull
for the responseList
* which is equivalent to an empty response. * The specified response is returned for every request. * @param responseList the responseList
Record class * @throws IllegalArgumentException if theresponseClass
* is not valid */ public IndexedRecordInteraction(List responseList, Class responseClass) { this(null, responseList, responseClass); } /** * Sets the specified expected requestList
and prepares * the specified responseList
. The response class for the * {@link #execute(InteractionSpec,Record)} method is set * to the specifiedresponseClass
. The specified *responseClass
must implementIndexedRecord
, * otherwise anIllegalArgumentException
will be thrown. * It is allowed to passnull
for the request and responseList
* 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 requestList
* @param responseList the responseList
* @param responseClass the responseRecord
class * @throws IllegalArgumentException if theresponseClass
* is not valid */ public IndexedRecordInteraction(List expectedRequest, List responseList, Class responseClass) { setExpectedRequest(expectedRequest); setResponse(responseList, responseClass); this.enabled = true; } /** * Sets the specified expected requestList
and the response *Record
for the {@link #execute(InteractionSpec, Record)} * method. The responseRecord
is ignored for * {@link #execute(InteractionSpec,Record,Record)} but takes precedence * over the specified responseList
for {@link #execute(InteractionSpec, Record)}. * It is allowed to passnull
for the request and responseRecord
* which is equivalent to an empty expected request (i.e. every request is accepted) * or to no specified responseRecord
, 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 requestList
* @param responseRecord the responseRecord
*/ public IndexedRecordInteraction(List expectedRequest, Record responseRecord) { setExpectedRequest(expectedRequest); setResponse(responseRecord); this.enabled = true; } /** * Sets the expected request tonull
and prepares the response *Record
for the {@link #execute(InteractionSpec, Record)} * method. The responseRecord
is ignored for * {@link #execute(InteractionSpec,Record,Record)} but takes precedence * over the specified responseList
for {@link #execute(InteractionSpec, Record)}. * It is allowed to passnull
for the responseRecord
* which is equivalent to no specified responseRecord
, i.e. the specified response *List
is taken. * The specified response is returned for every request. * @param responseRecord the responseRecord
*/ 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 returnsfalse
, if this implementor is disabled. */ public void disable() { this.enabled = false; } /** * Sets the specified expected requestList
. The response is returned, * if the actual request matches the specified expected requestList
* according toList.equals
. * It is allowed to passnull
for the requestList
* which is equivalent to an empty expected request (i.e. every request * is accepted). * @param expectedRequest the expected requestList
*/ public void setExpectedRequest(List expectedRequest) { if(null == expectedRequest) { this.expectedRequest = null; } else { this.expectedRequest = new ArrayList(expectedRequest); } } /** * Prepares the specified responseList
. 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 passnull
for the responseList
* which is equivalent to an empty response. * @param responseList the responseList
List. The response class for the * {@link #execute(InteractionSpec,Record)} method is set * to the specifiedresponseClass
. The specified *responseClass
must implementIndexedRecord
, * otherwise anIllegalArgumentException
will be thrown. * It is allowed to passnull
for the responseList
* which is equivalent to an empty response. * @param responseList the responseList
* @param responseClass the responseRecord
class * @throws IllegalArgumentException if theresponseClass
* 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 responseRecord
for the * {@link #execute(InteractionSpec, Record)} method. The response *Record
is ignored for {@link #execute(InteractionSpec,Record,Record)} * but takes precedence over the specified responseList
for * {@link #execute(InteractionSpec, Record)}. * It is allowed to passnull
for the responseRecord
* which is equivalent to no specified responseRecord
, i.e. the specified response *List
is taken. * @param responseRecord the responseRecord
*/ public void setResponse(Record responseRecord) { this.responseRecord = responseRecord; } /** * Returnstrue
if this implementor is enabled and will handle the request. * This method returnstrue
if the following prerequisites are fulfilled:
* It is enabled.
* The responseRecord
must implementIndexedRecord
* or it must benull
(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 benull
(use the various *setExpectedRequest
methods) or the actual requestRecord
* must implementIndexedRecord
and must contain the same data as * the specified expected requestList
according toList.equals
.
* Otherwise,false
is returned. * @param interactionSpec theInteractionSpec
for the actual call * @param actualRequest the request for the actual call * @param actualResponse the response for the actual call, may benull
* @returntrue
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 theexecute
methods.
* This method returnsnull
, 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} returnsfalse
. *
* 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 responseList
will be ignored. * If noRecord
object is specified, aRecord
object * is created and filled with the specified responseList
data. Use the *setResponse
methods that take aList
* to prepare the responseList
. The createdRecord
is of the the * specified type (thesetResponse
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 responseList
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", exc); throw resExc; } return response; } /** * Second version of theexecute
methods.
* This method returnsfalse
, 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} returnsfalse
. *
* Otherwise, this method fills the responseRecord
with the * specified responseList
data. Use thesetResponse
methods that * take aList
to prepare the responseList
. * The responseRecord
must implementIndexedRecord
* (it does, otherwise the request would have been rejected by * {@link #canHandle}). If no responseList
is specified at all, * the responseRecord
is not touched buttrue
* is returned anyway * @param interactionSpec the interaction spec * @param actualRequest the actual request * @param actualResponse the actual response * @returntrue
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", exc); throw resExc; } return true; } }