All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.sling.api.servlets.HtmlResponse Maven / Gradle / Ivy

/*
 * 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.api.servlets;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.sling.api.request.ResponseUtil;

/**
 * Generator for a HTML status response that displays the changes made in a post
 * request. see HtmlResponse.html for the
 * format.
 *
 * @deprecated use org.apache.sling.servlets.post.HtmlResponse instead.
 */
@Deprecated
public class HtmlResponse {

    /**
     * some human readable title like: 200 Created /foo/bar
     */
    public static final String PN_TITLE = "title";

    /**
     * status code. more or less http response status codes
     */
    public static final String PN_STATUS_CODE = "status.code";

    /**
     * some human readable status message
     */
    public static final String PN_STATUS_MESSAGE = "status.message";

    /**
     * externally mapped location url of the modified path
     */
    public static final String PN_LOCATION = "location";

    /**
     * externally mapped location url of the parent of the modified path
     */
    public static final String PN_PARENT_LOCATION = "parentLocation";

    /**
     * the path of the modified item. this is usually the addressed resource or
     * in case of a creation request (eg: /foo/*) the path of the newly created
     * node.
     */
    public static final String PN_PATH = "path";

    /**
     * the referrer of the request
     */
    public static final String PN_REFERER = "referer";

    /**
     * Indicating whether request processing created new data. This property
     * is initialized to false and may be changed by calling
     * the {@link #setCreateRequest(boolean)} method.
     */
    public static final String PN_IS_CREATED = "isCreate";

    /**
     * human readable changelog
     */
    public static final String PN_CHANGE_LOG = "changeLog";

    /**
     * The Throwable caught while processing the request. This property is not
     * set unless the {@link #setError(Throwable)} method is called.
     */
    public static final String PN_ERROR = "error";

    /**
     * name of the html template
     */
    private static final String TEMPLATE_NAME = "HtmlResponse.html";

    /**
     * list of changes
     */
    private final StringBuilder changes = new StringBuilder();

    /**
     * Properties of the response
     */
    private final Map properties = new HashMap();

    /**
     * Creates a new html response with default settings, which is
     * null for almost all properties except the
     * {@link #isCreateRequest()} which defaults to false.
     */
    public HtmlResponse() {
        setCreateRequest(false);
    }

    // ---------- Settings for the response ------------------------------------

    /**
     * Returns the referer as from the 'referer' request header.
     * @return The referrer
     */
    public String getReferer() {
        return getProperty(PN_REFERER, String.class);
    }

    /**
     * Sets the referer property
     * @param referer The referrer to set
     */
    public void setReferer(String referer) {
        setProperty(PN_REFERER, referer);
    }

    /**
     * Returns the absolute path of the item upon which the request operated.
     * 

* If the {@link #setPath(String)} method has not been called yet, this * method returns null. * @return The path or {@code null}. */ public String getPath() { return getProperty(PN_PATH, String.class); } /** * Sets the absolute path of the item upon which the request operated. * @param path The path */ public void setPath(String path) { setProperty(PN_PATH, path); } /** * Returns true if this was a create request. *

* Before calling the {@link #setCreateRequest(boolean)} method, this method * always returns false. * @return {@code true} if this is a create request */ public boolean isCreateRequest() { return getProperty(PN_IS_CREATED, Boolean.class); } /** * Sets whether the request was a create request or not. * @param isCreateRequest flag for the create request */ public void setCreateRequest(boolean isCreateRequest) { setProperty(PN_IS_CREATED, isCreateRequest); } /** * Returns the location of the modification. this is the externalized form * of the current path. * * @return the location of the modification. */ public String getLocation() { return getProperty(PN_LOCATION, String.class); } /** * Set the location * @param location The location */ public void setLocation(String location) { setProperty(PN_LOCATION, location); } /** * Returns the parent location of the modification. this is the externalized * form of the parent node of the current path. * * @return the location of the modification. */ public String getParentLocation() { return getProperty(PN_PARENT_LOCATION, String.class); } /** * Set the parent location * @param parentLocation The parent location */ public void setParentLocation(String parentLocation) { setProperty(PN_PARENT_LOCATION, parentLocation); } /** * Sets the title of the response message * * @param title the title */ public void setTitle(String title) { setProperty(PN_TITLE, title); } /** * sets the response status code properties * * @param code the code * @param message the message */ public void setStatus(int code, String message) { setProperty(PN_STATUS_CODE, code); setProperty(PN_STATUS_MESSAGE, message); } /** * Returns the status code of this instance. If the status code has never * been set by calling the {@link #setStatus(int, String)} method, the * status code is determined by checking if there was an error. If there * was an error, the response is assumed to be unsuccessful and 500 is returned. * If there is no error, the response is assumed to be successful and 200 is returned. * @return The status code */ public int getStatusCode() { Integer status = getProperty(PN_STATUS_CODE, Integer.class); if (status == null) { if (getError() != null) { //if there was an error status = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; } else { status = HttpServletResponse.SC_OK; } } return status; } /** * Get the status message * @return The status message */ public String getStatusMessage() { return getProperty(PN_STATUS_MESSAGE, String.class); } /** * Returns any recorded error or null * * @return an error or null */ public Throwable getError() { return getProperty(PN_ERROR, Throwable.class); } /** * Set the error * @param error The error */ public void setError(Throwable error) { setProperty(PN_ERROR, error); } /** * Returns true if no {@link #getError() error} is set and if * the {@link #getStatusCode() status code} is one of the 2xx codes. * @return {@code true} if successful */ public boolean isSuccessful() { return getError() == null && (getStatusCode() / 100) == 2; } // ---------- ChangeLog ---------------------------------------------------- /** * Records a 'modified' change * * @param path path of the item that was modified */ public void onModified(String path) { onChange("modified", path); } /** * Records a 'created' change * * @param path path of the item that was created */ public void onCreated(String path) { onChange("created", path); } /** * Records a 'deleted' change * * @param path path of the item that was deleted */ public void onDeleted(String path) { if (path != null) { onChange("deleted", path); } } /** * Records a 'moved' change. *

* Note: the moved change only records the * basic move command. the implied changes on the moved properties and sub * nodes are not recorded. * * @param srcPath source path of the node that was moved * @param dstPath destination path of the node that was moved. */ public void onMoved(String srcPath, String dstPath) { onChange("moved", srcPath, dstPath); } /** * Records a 'copied' change. *

* Note: the copy change only records the * basic copy command. the implied changes on the copied properties and sub * nodes are not recorded. * * @param srcPath source path of the node that was copied * @param dstPath destination path of the node that was copied. */ public void onCopied(String srcPath, String dstPath) { onChange("copied", srcPath, dstPath); } /** * Records a generic change of the given type. *

* The change is added to the internal list of changes with the syntax of a * method call, where the type is the method name and the * arguments are the string arguments to the method enclosed in * double quotes. For example, the the call * *

     * onChange("sameple", "arg1", "arg2");
     * 
* * is aded as * *
     * sample("arg1", "arg2")
     * 
* * to the internal list of changes. * * @param type The type of the modification * @param arguments The arguments to the modifications */ public void onChange(String type, String... arguments) { changes.append(type); String delim = "("; for (String a : arguments) { changes.append(delim); changes.append('\"'); changes.append(a); changes.append('\"'); delim = ", "; } changes.append(");
"); } // ---------- Response Generation ------------------------------------------ /** * prepares the response properties */ private void prepare() { String path = getPath(); if (getProperty(PN_STATUS_CODE) == null) { if (getError() != null) { setStatus(500, getError().toString()); setTitle("Error while processing " + path); } else { if (isCreateRequest()) { setStatus(201, "Created"); setTitle("Content created " + path); } else { setStatus(200, "OK"); setTitle("Content modified " + path); } } } String referer = getReferer(); if (referer == null) { referer = ""; } setReferer(referer); // get changelog changes.insert(0, "
");
        changes.append("
"); setProperty(PN_CHANGE_LOG, changes.toString()); } /** * Sets a generic response property with the given * * @param name name of the property * @param value value of the property */ public void setProperty(String name, Object value) { properties.put(name, value); } /** * Returns the generic response property with the given name and type or * null if no such property exists or the property is not of * the requested type. * * @param name The property name * @param The type to get * @param type The type to get * @return The property value or {@code null}. */ @SuppressWarnings("unchecked") public Type getProperty(String name, Class type) { Object value = getProperty(name); if (type.isInstance(value)) { return (Type) value; } return null; } /** * Returns the generic response property with the given name and type or * null if no such property exists. * @param name The property name * @return The property value or {@code null}. */ public Object getProperty(String name) { return properties.get(name); } /** * Writes the response to the given writer and replaces all ${var} patterns * by the value of the respective property. if the property is not defined * the pattern is not modified. * * @param response to send to * @param setStatus whether to set the status code on the response * @throws IOException if an i/o exception occurs */ public void send(HttpServletResponse response, boolean setStatus) throws IOException { prepare(); if (setStatus) { Object status = getProperty(PN_STATUS_CODE); if (status instanceof Number) { int statusCode = ((Number) status).intValue(); response.setStatus(statusCode); // special treatment of 201/CREATED: Requires Location if (statusCode == HttpServletResponse.SC_CREATED) { response.setHeader("Location", getLocation()); } } } response.setContentType("text/html"); response.setCharacterEncoding("UTF-8"); Writer out = response.getWriter(); InputStream template = getClass().getResourceAsStream(TEMPLATE_NAME); Reader in = new BufferedReader(new InputStreamReader(template)); StringBuffer varBuffer = new StringBuffer(); int state = 0; int read; while ((read = in.read()) >= 0) { char c = (char) read; switch (state) { // initial case 0: if (c == '$') { state = 1; } else { out.write(c); } break; // $ read case 1: if (c == '{') { state = 2; } else { state = 0; out.write('$'); out.write(c); } break; // { read case 2: if (c == '}') { state = 0; Object prop = properties.get(varBuffer.toString()); if (prop != null) { out.write(ResponseUtil.escapeXml(prop.toString())); } varBuffer.setLength(0); } else { varBuffer.append(c); } } } in.close(); out.flush(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy