org.apache.sling.testing.clients.SlingHttpResponse.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.sling.testing.clients.SlingHttpResponse.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to You 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 org.apache.sling.testing.clients;

import org.apache.http.*;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.*;
import java.util.regex.Pattern;

public class SlingHttpResponse implements CloseableHttpResponse {

    public static final String STATUS = "Status";
    public static final String MESSAGE = "Message";
    public static final String LOCATION = "Location";
    public static final String PARENT_LOCATION = "ParentLocation";
    public static final String PATH = "Path";
    public static final String REFERER = "Referer";
    public static final String CHANGE_LOG = "ChangeLog";

    private final CloseableHttpResponse httpResponse;
    private String content;

    public SlingHttpResponse(CloseableHttpResponse response) {
        this.httpResponse = response;
    }

    /**
     * <p>Get the {@code String} content of the response.</p>
     * <p>The content is cached so it is safe to call this method several times.</p>
     * <p><b>Attention!</b> Calling this method consumes the entity, so it cannot be used as an InputStream later</p>
     *
     * @return the content as String
     */
    public String getContent() {
        if (!this.isConsumed()) {
            try {
                this.content = EntityUtils.toString(this.getEntity());
                this.close();
            } catch (IOException e) {
                throw new RuntimeException("Could not read content from response", e);
            }
        }

        return content;
    }

    public boolean isConsumed() {
        return this.content != null || this.getEntity() == null;
    }

    /**
     * <p>Assert that response matches supplied status</p>
     *
     * @param expected the expected http status
     * @throws AssertionError if the response does not match the expected
     */
    public void checkStatus(int expected) throws ClientException {
        if (this.getStatusLine().getStatusCode() != expected) {
            throw new ClientException(this + " has wrong response status (" + this.getStatusLine().getStatusCode()
                    + "). Expected " + expected);
        }
    }

    /**
     * <p>Assert that response matches supplied content type (from Content-Type header)</p>
     *
     * @param expected the expected content type
     * @throws AssertionError if the response content type does not match the expected
     */
    public void checkContentType(String expected) throws ClientException {
        // Remove whatever follows semicolon in content-type
        String contentType = this.getEntity().getContentType().getValue();
        if (contentType != null) {
            contentType = contentType.split(";")[0].trim();
        }

        // check for match
        if (!contentType.equals(expected)) {
            throw new ClientException(this + " has wrong content type (" + contentType + "). Expected " + expected);
        }
    }

    /**
     * <p>For each regular expression, assert that at least one line of the response matches the expression</p>
     * <p>The regular expressions are automatically prefixed and suffixed with .* it order to partial-match the lines</p>
     *
     * @param regexp list of regular expressions
     * @throws AssertionError if the response content does not match one of the regexp
     */
    public void checkContentRegexp(String... regexp) throws ClientException {
        for (String expr : regexp) {
            final Pattern p = Pattern.compile(".*" + expr + ".*");
            final Scanner scanner = new Scanner(this.getContent());
            boolean matched = false;
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                if (p.matcher(line).matches()) {
                    matched = true;
                    break;
                }
            }

            if (!matched) {
                throw new ClientException("Pattern " + p + " didn't match any line in content");
            }
        }
    }

    /**
     * <p>Assert that all the provided {@code Strings} are contained in the response</p>
     *
     * @param expected list of expected strings
     */
    public void checkContentContains(String... expected) throws ClientException {
        for (String s : expected) {
            if (!this.getContent().contains(s)) {
                throw new ClientException(
                        "Content does not contain string " + s + ". Content is: \n\n" + getContent());
            }
        }
    }

    /**
     * Get status from Sling Response
     *
     * @return Sling Status
     */
    public String getSlingStatus() {
        String searchPattern = "id=\"" + STATUS + "\">";
        return extractFromHTMLResponse(searchPattern);
    }

    /**
     * Get status from Sling Response as integer
     *
     * @return Sling Status
     */
    public int getSlingStatusAsInt() throws NumberFormatException {
        String strStatus = getSlingStatus();
        return Integer.parseInt(strStatus);
    }

    /**
     * Get message from Sling Response
     *
     * @return Sling Message
     */
    public String getSlingMessage() {
        String searchPattern = "id=\"" + MESSAGE + "\">";
        return extractFromHTMLResponse(searchPattern);
    }

    /**
     * Get copy paths from message
     *
     * @return copy paths as String Array
     */
    public String[] getSlingCopyPaths() {
        String copyPaths = getSlingMessage();
        StringTokenizer tokenizer = new StringTokenizer(copyPaths);
        List<String> copies = new ArrayList<String>();
        while (tokenizer.hasMoreElements()) {
            copies.add(tokenizer.nextToken());
        }
        return copies.toArray(new String[copies.size()]);
    }

    /**
     * Get location from Sling Response
     *
     * @return Sling Location
     */
    public String getSlingLocation() {
        String searchPattern = "id=\"" + LOCATION + "\">";
        return extractFromHTMLResponse(searchPattern);
    }

    /**
     * Get parent location from Sling Response
     *
     * @return Sling Parent Location
     */
    public String getSlingParentLocation() {
        String searchPattern = "id=\"" + PARENT_LOCATION + "\">";
        return extractFromHTMLResponse(searchPattern);
    }

    /**
     * Get path from Sling Response
     *
     * @return Sling Path
     */
    public String getSlingPath() {
        String searchPattern = "id=\"" + PATH + "\">";
        return extractFromHTMLResponse(searchPattern);
    }

    /**
     * Get referer from Sling Response
     *
     * @return Sling Referer
     */
    public String getSlingReferer() {
        String searchPattern = "id=\"" + REFERER + "\">";
        return extractFromHTMLResponse(searchPattern);
    }

    /**
     * Get change log from Sling Response
     *
     * @return Sling Change Log
     */
    public String getSlingChangeLog() {
        String searchPattern = "id=\"" + CHANGE_LOG + "\">";
        return extractFromHTMLResponse(searchPattern);
    }

    /**
     * Extract information from response
     *
     * @param searchPattern search pattern to look for
     * @return Sling information
     */
    protected String extractFromHTMLResponse(String searchPattern) {
        String tmpResponse = null;
        int start = getContent().indexOf(searchPattern);
        if (start > 0) {
            start += searchPattern.length();
            tmpResponse = getContent().substring(start);
            int end = tmpResponse.indexOf("<");
            tmpResponse = tmpResponse.substring(0, end);
        }
        return tmpResponse;
    }

    // HttpResponse delegated methods

    @Override
    public StatusLine getStatusLine() {
        return httpResponse.getStatusLine();
    }

    @Override
    public void setStatusLine(StatusLine statusline) {
        httpResponse.setStatusLine(statusline);
    }

    @Override
    public void setStatusLine(ProtocolVersion ver, int code) {
        httpResponse.setStatusLine(ver, code);
    }

    @Override
    public void setStatusLine(ProtocolVersion ver, int code, String reason) {
        httpResponse.setStatusLine(ver, code, reason);
    }

    @Override
    public void setStatusCode(int code) throws IllegalStateException {
        httpResponse.setStatusCode(code);
    }

    @Override
    public void setReasonPhrase(String reason) throws IllegalStateException {
        httpResponse.setReasonPhrase(reason);
    }

    @Override
    public HttpEntity getEntity() {
        return httpResponse.getEntity();
    }

    @Override
    public void setEntity(HttpEntity entity) {
        httpResponse.setEntity(entity);
    }

    @Override
    public Locale getLocale() {
        return httpResponse.getLocale();
    }

    @Override
    public void setLocale(Locale loc) {
        httpResponse.setLocale(loc);
    }

    @Override
    public ProtocolVersion getProtocolVersion() {
        return httpResponse.getProtocolVersion();
    }

    @Override
    public boolean containsHeader(String name) {
        return httpResponse.containsHeader(name);
    }

    @Override
    public Header[] getHeaders(String name) {
        return httpResponse.getHeaders(name);
    }

    @Override
    public Header getFirstHeader(String name) {
        return httpResponse.getFirstHeader(name);
    }

    @Override
    public Header getLastHeader(String name) {
        return httpResponse.getLastHeader(name);
    }

    @Override
    public Header[] getAllHeaders() {
        return httpResponse.getAllHeaders();
    }

    @Override
    public void addHeader(Header header) {
        httpResponse.addHeader(header);
    }

    @Override
    public void addHeader(String name, String value) {
        httpResponse.addHeader(name, value);
    }

    @Override
    public void setHeader(Header header) {
        httpResponse.setHeader(header);
    }

    @Override
    public void setHeader(String name, String value) {
        httpResponse.setHeader(name, value);
    }

    @Override
    public void setHeaders(Header[] headers) {
        httpResponse.setHeaders(headers);
    }

    @Override
    public void removeHeader(Header header) {
        httpResponse.removeHeader(header);
    }

    @Override
    public void removeHeaders(String name) {
        httpResponse.removeHeaders(name);
    }

    @Override
    public HeaderIterator headerIterator() {
        return httpResponse.headerIterator();
    }

    @Override
    public HeaderIterator headerIterator(String name) {
        return httpResponse.headerIterator(name);
    }

    @SuppressWarnings("deprecation")
    @Override
    public HttpParams getParams() {
        return httpResponse.getParams();
    }

    @SuppressWarnings("deprecation")
    @Override
    public void setParams(HttpParams params) {
        httpResponse.setParams(params);
    }

    @Override
    public void close() throws IOException {
        httpResponse.close();
    }
}