org.apache.sling.testing.tools.http.RequestDocumentor.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.sling.testing.tools.http.RequestDocumentor.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.tools.http;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.Header;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;

/** Generate RESTful API documentation based on actual requests
 *  executed during integration tests, enhanced with user-supplied
 *  bits of documentation. 
 */
public class RequestDocumentor {
    public static final String OUTPUT_BASE = "./target/" + RequestDocumentor.class.getSimpleName();
    private final String name;

    public RequestDocumentor(String name) {
        this.name = name;
    }

    public String toString() {
        return getClass().getSimpleName() + " (" + name + ")";
    }

    void generateDocumentation(RequestExecutor executor, String[] metadata) throws IOException {
        final File f = getOutputFile();
        final File dir = f.getParentFile();
        dir.mkdirs();
        if (!dir.isDirectory()) {
            throw new IOException("Failed to create output folder " + dir.getAbsolutePath());
        }
        final PrintWriter pw = new PrintWriter(new FileWriter(f, true));
        try {
            System.out.println("Appending documentation of " + executor + " to " + f.getAbsolutePath());
            documentRequest(pw, executor, metadata);
        } finally {
            pw.flush();
            pw.close();
        }
    }

    protected File getOutputFile() {
        return new File(OUTPUT_BASE + "/" + name + ".txt");
    }

    protected void documentRequest(PrintWriter pw, RequestExecutor executor, String[] metadataArray)
            throws IOException {
        // Convert metadata to more convenient Map 
        final Map<String, String> m = new HashMap<String, String>();
        if (metadataArray.length % 2 != 0) {
            throw new IllegalArgumentException("Metadata array must be of even size, got " + metadataArray.length);
        }
        for (int i = 0; i < metadataArray.length; i += 2) {
            m.put(metadataArray[i], metadataArray[i + 1]);
        }

        // TODO use velocity or other templates? Just a rough prototype for now
        // Also need to filter overly long input/output, binary etc.
        pw.println();
        pw.println("====================================================================================");
        pw.print("=== ");
        pw.print(m.get("title"));
        pw.println(" ===");
        pw.println(m.get("description"));

        pw.print("\n=== ");
        pw.print("REQUEST");
        pw.println(" ===");

        pw.print("Method: ");
        pw.println(executor.getRequest().getMethod());
        pw.print("URI: ");
        pw.println(executor.getRequest().getURI());

        final Header[] allHeaders = executor.getRequest().getAllHeaders();
        if (allHeaders != null && allHeaders.length > 0) {
            pw.println("Headers:");
            for (Header h : allHeaders) {
                pw.print(h.getName());
                pw.print(":");
                pw.println(h.getValue());
            }
        }

        if (executor.getRequest() instanceof HttpEntityEnclosingRequestBase) {
            final HttpEntityEnclosingRequestBase heb = (HttpEntityEnclosingRequestBase) executor.getRequest();
            if (heb.getEntity() != null) {
                pw.print("Content-Type:");
                pw.println(heb.getEntity().getContentType().getValue());
                pw.println("Content:");
                final InputStream is = heb.getEntity().getContent();
                final byte[] buffer = new byte[16384];
                int count = 0;
                while ((count = is.read(buffer, 0, buffer.length)) > 0) {
                    // TODO encoding??
                    pw.write(new String(buffer, 0, count));
                }
                pw.println();
            }
        }

        pw.print("\n=== ");
        pw.print("RESPONSE");
        pw.println(" ===");
        pw.print("Content-Type:");
        pw.println(executor.getResponse().getEntity().getContentType().getValue());
        pw.println("Content:");
        pw.println(executor.getContent());

        pw.println("====================================================================================");
    }
}