/**
* Copyright 2009-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.javacrumbs.smock.extended.client.connection;
import static net.javacrumbs.smock.common.XmlUtil.getEnvelopeSource;
import static net.javacrumbs.smock.common.XmlUtil.serialize;
import static net.javacrumbs.smock.common.XmlUtil.stringToBytes;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.LinkedList;
import java.util.List;
import net.javacrumbs.smock.common.EndpointInterceptorClientAdapter;
import net.javacrumbs.smock.common.InterceptingTemplate;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.context.DefaultMessageContext;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.EndpointInterceptor;
import org.springframework.ws.test.client.RequestMatcher;
import org.springframework.ws.test.client.ResponseActions;
import org.springframework.ws.test.client.ResponseCreator;
import org.springframework.ws.transport.WebServiceMessageReceiver;
/**
* Simulates connection to a server.
* @author Lukas Krecan
*/
public class MockConnection implements ResponseActions {
private static final String CONTENT_TYPE = "text/xml;charset=UTF-8";
private ResponseCreator responseCreator;
private final List<RequestMatcher> requestMatchers = new LinkedList<RequestMatcher>();
private final WebServiceMessageFactory messageFactory;
private final ByteArrayOutputStream requestStream = new ByteArrayOutputStream();
private URI uri;
private final EndpointInterceptor[] interceptors;
public MockConnection(RequestMatcher requestMatcher, WebServiceMessageFactory messageFactory, EndpointInterceptor[] interceptors)
{
requestMatchers.add(requestMatcher);
this.messageFactory = messageFactory;
this.interceptors = interceptors;
}
public ResponseActions andExpect(RequestMatcher requestMatcher) {
requestMatchers.add(requestMatcher);
return this;
}
public void andRespond(ResponseCreator responseCreator) {
this.responseCreator = responseCreator;
}
/**
* Validates request written to outputStream and serializes response generated by {@link ResponseCreator} to this stream.
* Applies interceptors on both request and response.
* @return
* @throws IOException
*/
public InputStream getInputStream() throws IOException {
final WebServiceMessage request = crateRequest();
MessageContext messageContext = new DefaultMessageContext(request, messageFactory);
InterceptingTemplate interceptingTemplate = new InterceptingTemplate(EndpointInterceptorClientAdapter.wrapEndpointInterceptors(interceptors));
try {
interceptingTemplate.interceptRequest(messageContext, new WebServiceMessageReceiver() {
public void receive(MessageContext context) throws Exception {
validate(request);
context.setResponse(responseCreator.createResponse(uri, request, messageFactory));
}
});
} catch (Exception e) {
throw new IllegalStateException("Error when processing request.",e);
}
return new ByteArrayInputStream(stringToBytes(serialize(getEnvelopeSource(messageContext.getResponse()))));
}
protected WebServiceMessage crateRequest() throws IOException {
return messageFactory.createWebServiceMessage(new ByteArrayInputStream(requestStream.toByteArray()));
}
/**
* Returns output stream to which a request can be written.
* @return
*/
public OutputStream getOutputStream() {
return requestStream;
}
public int getResponseCode() {
return 200;
}
public String getHeaderField(String key) {
if ("content-type".equals(key))
{
return CONTENT_TYPE;
}
return null;
}
protected void validate(WebServiceMessage request) throws IOException {
for (RequestMatcher requestMatcher: requestMatchers)
{
requestMatcher.match(uri, request);
}
}
public URI getUri() {
return uri;
}
public void setUri(URI uri) {
this.uri = uri;
}
}