Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.mockrunner.connector;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Arrays;
import javax.resource.ResourceException;
import javax.resource.cci.InteractionSpec;
import javax.resource.cci.Record;
import javax.resource.cci.Streamable;
import com.mockrunner.base.NestedApplicationException;
import com.mockrunner.mock.connector.cci.MockStreamableByteArrayRecord;
import com.mockrunner.util.common.StreamUtil;
/**
* This interaction implementor works with bytes arrays and streamable
* records. It takes a byte array for the request and a byte array or
* a Record instance for the response. If the request byte array
* is null, which is the default, the implementor accepts any
* request and returns the specified result. If a request byte array is specified,
* this implementor accepts only requests that are equal to the specified request
* byte array. 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 data and the response.
* Please check out the documentation of the various methods for details.
*/
public class StreamableRecordByteArrayInteraction implements InteractionImplementor
{
private boolean enabled;
private byte[] expectedRequest;
private byte[] 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 StreamableRecordByteArrayInteraction()
{
this(null, null, MockStreamableByteArrayRecord.class);
}
/**
* Sets the expected request to null and prepares
* the specified response data. The response class for the
* {@link #execute(InteractionSpec,Record)} method is set
* to the default {@link com.mockrunner.mock.connector.cci.MockStreamableByteArrayRecord}.
* It is allowed to pass null for the response data which is equivalent
* to an empty response.
* The specified response is returned for every request.
* @param responseData the response data
*/
public StreamableRecordByteArrayInteraction(byte[] responseData)
{
this(null, responseData, MockStreamableByteArrayRecord.class);
}
/**
* Sets the specified expected request data and prepares
* the specified response data. The response class for the
* {@link #execute(InteractionSpec,Record)} method is set
* to the default {@link com.mockrunner.mock.connector.cci.MockStreamableByteArrayRecord}.
* It is allowed to pass null for the request and response data
* 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 data.
* @param expectedRequest the expected request data
* @param responseData the response data
*/
public StreamableRecordByteArrayInteraction(byte[] expectedRequest, byte[] responseData)
{
this(expectedRequest, responseData, MockStreamableByteArrayRecord.class);
}
/**
* Sets the expected request to null and prepares
* the specified response data. The response class for the
* {@link #execute(InteractionSpec,Record)} method is set
* to the specified responseClass. The specified
* responseClass must implement Record
* and Streamable, otherwise an
* IllegalArgumentException will be thrown.
* It is allowed to pass null for the response data which is
* equivalent to an empty response.
* The specified response is returned for every request.
* @param responseData the response data
* @param responseClass the response Record class
* @throws IllegalArgumentException if the responseClass
* is not valid
*/
public StreamableRecordByteArrayInteraction(byte[] responseData, Class responseClass)
{
this(null, responseData, responseClass);
}
/**
* Sets the specified expected request data and prepares
* the specified response data. The response class for the
* {@link #execute(InteractionSpec,Record)} method is set
* to the specified responseClass. The specified
* responseClass must implement Record
* and Streamable, otherwise an
* IllegalArgumentException will be thrown.
* It is allowed to pass null for the request and response data
* 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 data.
* @param expectedRequest the expected request data
* @param responseData the response data
* @param responseClass the response Record class
* @throws IllegalArgumentException if the responseClass
* is not valid
*/
public StreamableRecordByteArrayInteraction(byte[] expectedRequest, byte[] responseData, Class responseClass)
{
setExpectedRequest(expectedRequest);
setResponse(responseData, responseClass);
this.enabled = true;
}
/**
* Sets the specified expected request data 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 byte data 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
* byte data is taken.
* The specified response is returned, if the actual request matches the specified expected
* request data.
* @param expectedRequest the expected request data
* @param responseRecord the response Record
*/
public StreamableRecordByteArrayInteraction(byte[] 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 byte data 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
* byte data is taken.
* The specified response is returned for every request.
* @param responseRecord the response Record
*/
public StreamableRecordByteArrayInteraction(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 data. The response is returned,
* if the actual request matches the specified expected request data.
* It is allowed to pass null for the request data
* which is equivalent to an empty expected request (i.e. every request
* is accepted).
* @param expectedRequest the expected request data
*/
public void setExpectedRequest(byte[] expectedRequest)
{
if(null == expectedRequest)
{
this.expectedRequest = null;
}
else
{
this.expectedRequest = (byte[])expectedRequest.clone();
}
}
/**
* Reads the expected request data from the specified InputStream.
* The response is returned, if the actual request matches the expected request data.
* It is allowed to pass null for the InputStream
* which is equivalent to an empty expected request (i.e. every request
* is accepted).
* @param expectedRequest the expected request
*/
public void setExpectedRequest(InputStream expectedRequest)
{
if(null == expectedRequest)
{
this.expectedRequest = null;
}
else
{
this.expectedRequest = StreamUtil.getStreamAsByteArray(expectedRequest);
}
}
/**
* Prepares the specified response data. The response class for the
* {@link #execute(InteractionSpec,Record)} method is set
* to the default {@link com.mockrunner.mock.connector.cci.MockStreamableByteArrayRecord}.
* It is allowed to pass null for the response data
* which is equivalent to an empty response.
* @param responseData the response data
*/
public void setResponse(byte[] responseData)
{
setResponse(responseData, MockStreamableByteArrayRecord.class);
}
/**
* Prepares the specified response data. The response class for the
* {@link #execute(InteractionSpec,Record)} method is set
* to the specified responseClass. The specified
* responseClass must implement Record
* and Streamable, otherwise an
* IllegalArgumentException will be thrown.
* It is allowed to pass null for the response data
* which is equivalent to an empty response.
* @param responseData the response data
* @param responseClass the response Record class
* @throws IllegalArgumentException if the responseClass
* is not valid
*/
public void setResponse(byte[] responseData, Class responseClass)
{
if(!isResponseClassAcceptable(responseClass))
{
throw new IllegalArgumentException("responseClass must implement " + Streamable.class.getName() + " and " + Record.class.getName());
}
if(null == responseData)
{
this.responseData = null;
}
else
{
this.responseData = (byte[])responseData.clone();
}
this.responseClass = responseClass;
}
/**
* Reads the response data from the specified InputStream.
* The response class for the {@link #execute(InteractionSpec,Record)} method
* is set to the default
* {@link com.mockrunner.mock.connector.cci.MockStreamableByteArrayRecord}.
* It is allowed to pass null for the InputStream
* which is equivalent to an empty response.
* @param responseData the response data
*/
public void setResponse(InputStream responseData)
{
setResponse(responseData, MockStreamableByteArrayRecord.class);
}
/**
* Reads the response data from the specified InputStream.
* The response class for the
* {@link #execute(InteractionSpec,Record)} method is set
* to the specified responseClass. The specified
* responseClass must implement Record
* and Streamable, otherwise an
* IllegalArgumentException will be thrown.
* It is allowed to pass null for the InputStream
* which is equivalent to an empty response.
* @param responseData the response data
* @param responseClass the response Record class
* @throws IllegalArgumentException if the responseClass
* is not valid
*/
public void setResponse(InputStream responseData, Class responseClass)
{
if(!isResponseClassAcceptable(responseClass))
{
throw new IllegalArgumentException("responseClass must implement " + Streamable.class.getName() + " and " + Record.class.getName());
}
if(null == responseData)
{
this.responseData = null;
}
else
{
this.responseData = StreamUtil.getStreamAsByteArray(responseData);
}
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 byte data 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
* byte data 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 Streamable
* 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 Streamable and must contain the same data as
* the specified expected request.
* 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 Streamable)
{
try
{
Streamable streamableRequest = (Streamable)request;
ByteArrayOutputStream stream = new ByteArrayOutputStream();
streamableRequest.write(stream);
stream.flush();
return Arrays.equals(expectedRequest, stream.toByteArray());
}
catch(Exception exc)
{
throw new NestedApplicationException(exc);
}
}
return false;
}
private boolean isResponseAcceptable(Record response)
{
return (null == response) || (response instanceof Streamable);
}
private boolean isResponseClassAcceptable(Class responseClass)
{
return (null == responseClass) || ((Streamable.class.isAssignableFrom(responseClass)) && (Record.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 byte array response will be ignored.
* If no Record object is specified, a Record object
* is created and filled with the specified byte response data. Use the
* setResponse methods that take a byte array or an InputStream
* to prepare response data. The created Record is of the the
* specified type (the setResponse methods that take a second
* Class parameter allows for specifying a type). If no type
* is specified, a {@link com.mockrunner.mock.connector.cci.MockStreamableByteArrayRecord}
* is created. If no response data is specified at all, an empty
* {@link com.mockrunner.mock.connector.cci.MockStreamableByteArrayRecord}
* 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;
Streamable response = null;
try
{
if(null == responseClass)
{
response = new MockStreamableByteArrayRecord();
}
else
{
response = (Streamable)responseClass.newInstance();
}
if(null != responseData)
{
response.read(new ByteArrayInputStream(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 byte response data. Use the setResponse methods that
* take a byte array or an InputStream to prepare response data.
* The response Record must implement Streamable
* (it does, otherwise the request would have been rejected by
* {@link #canHandle}). If no response data 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)
{
((Streamable)actualResponse).read(new ByteArrayInputStream(responseData));
}
}
catch(Exception exc)
{
ResourceException resExc = new ResourceException("execute() failed");
resExc.setLinkedException(exc);
throw resExc;
}
return true;
}
}