/*******************************************************************************
*
* Copyright (c) 2010-2011 Sonatype, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*
*
*
*
*******************************************************************************/
package org.hudsonci.utils.hamcrest;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
public class URLRespondsWithStatusMatcher extends TypeSafeMatcher<URL> {
private int statusCode = -2; // since -1 means the response was non-http-valid
private int timeout = 0; // negative timeout would throw iae, default infinite
private int receivedStatusCode = 0;
private boolean timedOut = false;
private Exception e;
private String urlString;
public URLRespondsWithStatusMatcher(final int statusCode) {
this(statusCode, 0);
}
public URLRespondsWithStatusMatcher(final int statusCode, final int timeout) {
if (timeout < 0) {
throw new IllegalArgumentException("timeout cannot be negative");
}
if (statusCode < -1) {
throw new IllegalArgumentException("status code cannot be less than negative one");
}
this.statusCode = statusCode;
this.timeout = timeout;
}
public void describeTo(Description description) {
if (timedOut) {
description.appendValue(urlString).appendText(" to connect within ").appendValue(timeout).appendText("ms");
} else if (e != null) {
description.appendValue(urlString).appendText(" to successfully connect");
} else {
description.appendValue(urlString).appendText(" to respond with ").appendValue(statusCode);
}
}
@Override
protected void describeMismatchSafely(URL item, Description mismatchDescription) {
if (timedOut) {
mismatchDescription.appendText("took longer.");
if (this.e != null) {
mismatchDescription.appendText(this.e.getMessage());
}
} else if (e != null) {
mismatchDescription.appendText("got ").appendValue(this.e);
// description.appendText("got exception ").appendValue(e);
} else {
mismatchDescription.appendText("was ").appendValue(receivedStatusCode);
}
}
@Override
protected boolean matchesSafely(URL item) {
this.urlString = item.toString();
try {
URL url = new URL(item.toString());
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
if (timeout > -1) {
urlConnection.setConnectTimeout(timeout);
urlConnection.setReadTimeout(timeout);
}
urlConnection.setUseCaches(false);
urlConnection.connect();
this.receivedStatusCode = urlConnection.getResponseCode();
} catch (SocketTimeoutException ste) {
timedOut = true;
this.e = ste;
} catch (IOException ioe) {
this.e = ioe;
} catch (Exception e) {
this.e = e;
}
return (!timedOut && e == null && this.receivedStatusCode == this.statusCode);
}
}