You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2016/08/01 16:03:32 UTC

[27/51] [abbrv] [partial] incubator-juneau git commit: Merge changes from GitHub repo.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/2c3a7cb5/com.ibm.team.juno.server/src/main/java/org/apache/juneau/server/RestResponse.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.server/src/main/java/org/apache/juneau/server/RestResponse.java b/com.ibm.team.juno.server/src/main/java/org/apache/juneau/server/RestResponse.java
deleted file mode 100755
index 8983868..0000000
--- a/com.ibm.team.juno.server/src/main/java/org/apache/juneau/server/RestResponse.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/***************************************************************************************************************************
- * 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.juneau.server;
-
-import java.io.*;
-import java.util.*;
-
-import javax.servlet.*;
-import javax.servlet.http.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.encoders.*;
-import org.apache.juneau.jena.*;
-import org.apache.juneau.json.*;
-import org.apache.juneau.serializer.*;
-import org.apache.juneau.urlencoding.*;
-import org.apache.juneau.xml.*;
-
-/**
- * Represents an HTTP response for a REST resource.
- * <p>
- * Essentially an extended {@link HttpServletResponse} with some special convenience methods
- * 	that allow you to easily output POJOs as responses.
- * </p>
- * <p>
- * Since this class extends {@link HttpServletResponse}, developers are free to use these
- * 	convenience methods, or revert to using lower level methods like any other servlet response.
- * </p>
- *
- * <h6 class='topic'>Examples</h6>
- * <p class='bcode'>
- * 	<ja>@RestMethod</ja>(name=<js>"GET"</js>)
- * 	<jk>public void</jk> doGet(RestRequest req, RestResponse res) {
- * 		res.setProperty(HtmlSerializerContext.<jsf>HTMLDOC_title</jsf>, <js>"My title"</js>)
- * 			.setOutput(<js>"Simple string response"</js>);
- * 	}
- * </p>
- * <p>
- * 	Refer to <a class='doclink' href='package-summary.html#TOC'>REST Servlet API</a> for information about using this class.
- * </p>
- *
- * @author jbognar
- */
-public final class RestResponse extends HttpServletResponseWrapper {
-
-	private final RestRequest request;
-	private Object output;                               // The POJO being sent to the output.
-	private boolean isNullOutput;                        // The output is null (as opposed to not being set at all)
-	private ObjectMap properties;                        // Response properties
-	SerializerGroup serializerGroup;
-	UrlEncodingSerializer urlEncodingSerializer;         // The serializer used to convert arguments passed into Redirect objects.
-	private EncoderGroup encoders;
-	private RestServlet servlet;
-	private ServletOutputStream os;
-
-	/**
-	 * Constructor.
-	 */
-	RestResponse(RestServlet servlet, RestRequest req, HttpServletResponse res) {
-		super(res);
-		this.request = req;
-		this.servlet = servlet;
-
-		for (Map.Entry<String,Object> e : servlet.getDefaultResponseHeaders().entrySet())
-			setHeader(e.getKey(), e.getValue().toString());
-
-		try {
-			String passThroughHeaders = req.getHeader("x-response-headers");
-			if (passThroughHeaders != null) {
-				ObjectMap m = servlet.getUrlEncodingParser().parseParameter(passThroughHeaders, ObjectMap.class);
-				for (Map.Entry<String,Object> e : m.entrySet())
-					setHeader(e.getKey(), e.getValue().toString());
-			}
-		} catch (Exception e1) {
-			throw new RestException(SC_BAD_REQUEST, "Invalid format for header 'x-response-headers'.  Must be in URL-encoded format.").initCause(e1);
-		}
-	}
-
-	/*
-	 * Called from RestServlet after a match has been made but before the guard or method invocation.
-	 */
-	@SuppressWarnings("hiding")
-	final void init(ObjectMap properties, String defaultCharset, SerializerGroup mSerializers, UrlEncodingSerializer mUrlEncodingSerializer, EncoderGroup encoders) {
-		this.properties = properties;
-		this.serializerGroup = mSerializers;
-		this.urlEncodingSerializer = mUrlEncodingSerializer;
-		this.encoders = encoders;
-
-		// Find acceptable charset
-		String h = request.getHeader("accept-charset");
-		String charset = null;
-		if (h == null)
-			charset = defaultCharset;
-		else for (MediaRange r : MediaRange.parse(h)) {
-			if (r.getQValue() > 0) {
-				if (r.getType().equals("*"))
-					charset = defaultCharset;
-				else if (RestServlet.availableCharsets.containsKey(r.getType()))
-					charset = r.getType();
-				if (charset != null)
-					break;
-			}
-		}
-
-		if (charset == null)
-			throw new RestException(SC_NOT_ACCEPTABLE, "No supported charsets in header ''Accept-Charset'': ''{0}''", request.getHeader("Accept-Charset"));
-		super.setCharacterEncoding(charset);
-	}
-
-	/**
-	 * Gets the serializer group for the response.
-	 *
-	 * @return The serializer group for the response.
-	 */
-	public SerializerGroup getSerializerGroup() {
-		return serializerGroup;
-	}
-
-	/**
-	 * Returns the media types that are valid for <code>Accept</code> headers on the request.
-	 *
-	 * @return The set of media types registered in the parser group of this request.
-	 */
-	public List<String> getSupportedMediaTypes() {
-		return serializerGroup.getSupportedMediaTypes();
-	}
-
-	/**
-	 * Returns the codings that are valid for <code>Accept-Encoding</code> and <code>Content-Encoding</code> headers on the request.
-	 *
-	 * @return The set of media types registered in the parser group of this request.
-	 * @throws RestServletException
-	 */
-	public List<String> getSupportedEncodings() throws RestServletException {
-		return servlet.getEncoders().getSupportedEncodings();
-	}
-
-	/**
-	 * Sets the HTTP output on the response.
-	 * <p>
-	 * 	Calling this method is functionally equivalent to returning the object in the REST Java method.
-	 * <p>
-	 * 	Can be of any of the following types:
-	 * 	<ul>
-	 * 	  <li> {@link InputStream}
-	 * 	  <li> {@link Reader}
-	 * 	  <li> Any serializable type defined in <a href='../core/package-summary.html#PojoCategories'>POJO Categories</a>
-	 * 	</ul>
-	 * <p>
-	 * 	If it's an {@link InputStream} or {@link Reader}, you must also specify the <code>Content-Type</code> using the {@link #setContentType(String)} method.
-	 *
-	 * @param output The output to serialize to the connection.
-	 * @return This object (for method chaining).
-	 */
-	public RestResponse setOutput(Object output) {
-		this.output = output;
-		this.isNullOutput = output == null;
-		return this;
-	}
-
-	/**
-	 * Add a serializer property to send to the serializers to override a default value.
-	 * <p>
-	 * Can be any value specified in the following classes:
-	 * <ul>
-	 * 	<li>{@link SerializerContext}
-	 * 	<li>{@link JsonSerializerContext}
-	 * 	<li>{@link XmlSerializerContext}
-	 * 	<li>{@link RdfSerializerContext}
-	 * </ul>
-	 *
-	 * @param key The setting name.
-	 * @param value The setting value.
-	 * @return This object (for method chaining).
-	 */
-	public RestResponse setProperty(String key, Object value) {
-		properties.put(key, value);
-		return this;
-	}
-
-	/**
-	 * Returns the properties set via {@link #setProperty(String, Object)}.
-	 *
-	 * @return A map of all the property values set.
-	 */
-	public ObjectMap getProperties() {
-		return properties;
-	}
-
-	/**
-	 * Shortcut method that allows you to use varargs to simplify setting array output.
-	 *
-	 * <dl>
-	 * 	<dt>Example:</dt>
-	 * 	<dd>
-	 * <p class='bcode'>
-	 * 	<jc>// Instead of...</jc>
-	 * 	response.setOutput(<jk>new</jk> Object[]{x,y,z});
-	 *
-	 * 	<jc>// ...call this...</jc>
-	 * 	response.setOutput(x,y,z);
-	 * </p>
-	 * 	</dd>
-	 * </dl>
-	 *
-	 * @param output The output to serialize to the connection.
-	 * @return This object (for method chaining).
-	 */
-	public RestResponse setOutputs(Object...output) {
-		this.output = output;
-		return this;
-	}
-
-	/**
-	 * Returns the output that was set by calling {@link #setOutput(Object)}.
-	 *
-	 * @return The output object.
-	 */
-	public Object getOutput() {
-		return output;
-	}
-
-	/**
-	 * Returns <jk>true</jk> if this response has any output associated with it.
-	 *
-	 * @return <jk>true</jk> if {@code setInput()} has been called.
-	 */
-	public boolean hasOutput() {
-		return output != null || isNullOutput;
-	}
-
-	/**
-	 * Sets the output to a plain-text message regardless of the content type.
-	 *
-	 * @param text The output text to send.
-	 * @return This object (for method chaining).
-	 * @throws IOException If a problem occurred trying to write to the writer.
-	 */
-	public RestResponse sendPlainText(String text) throws IOException {
-		setContentType("text/plain");
-		getNegotiatedWriter().write(text);
-		return this;
-	}
-
-	/**
-	 * Equivalent to {@link HttpServletResponse#getOutputStream()}, except
-	 * 	wraps the output stream if an {@link Encoder} was found that matched
-	 * 	the <code>Accept-Encoding</code> header.
-	 *
-	 * @return A negotiated output stream.
-	 * @throws IOException
-	 */
-	public ServletOutputStream getNegotiatedOutputStream() throws IOException {
-		if (os == null) {
-			Encoder encoder = null;
-
-			String ae = request.getHeader("Accept-Encoding");
-			if (! (ae == null || ae.isEmpty())) {
-				String match = encoders != null ? encoders.findMatch(ae) : null;
-				if (match == null) {
-					// Identity should always match unless "identity;q=0" or "*;q=0" is specified.
-					if (ae.matches(".*(identity|\\*)\\s*;\\s*q\\s*=\\s*(0(?!\\.)|0\\.0).*")) {
-						throw new RestException(SC_NOT_ACCEPTABLE,
-							"Unsupported encoding in request header ''Accept-Encoding'': ''{0}''\n\tSupported codings: {1}",
-							ae, encoders.getSupportedEncodings()
-						);
-					}
-				} else {
-					encoder = encoders.getEncoder(match);
-
-					// Some clients don't recognize identity as an encoding, so don't set it.
-					if (! match.equals("identity"))
-					setHeader("content-encoding", match);
-				}
-			}
-			os = getOutputStream();
-			if (encoder != null) {
-				final OutputStream os2 = encoder.getOutputStream(os);
-				os = new ServletOutputStream(){
-					@Override /* OutputStream */
-					public final void write(byte[] b, int off, int len) throws IOException {
-						os2.write(b, off, len);
-					}
-					@Override /* OutputStream */
-					public final void write(int b) throws IOException {
-						os2.write(b);
-					}
-					@Override /* OutputStream */
-					public final void flush() throws IOException {
-						os2.flush();
-					}
-					@Override /* OutputStream */
-					public final void close() throws IOException {
-						os2.close();
-					}
-				};
-			}
-		}
-		return os;
-	}
-
-	@Override /* ServletResponse */
-	public ServletOutputStream getOutputStream() throws IOException {
-		if (os == null)
-			os = super.getOutputStream();
-		return os;
-	}
-
-	/**
-	 * Returns <jk>true</jk> if {@link #getOutputStream()} has been called.
-	 *
-	 * @return <jk>true</jk> if {@link #getOutputStream()} has been called.
-	 */
-	public boolean getOutputStreamCalled() {
-		return os != null;
-	}
-
-	/**
-	 * Returns the writer to the response body.
-	 * This methods bypasses any specified encoders and returns a regular unbuffered writer.
-	 * Use the {@link #getNegotiatedWriter()} method if you want to use the matched encoder (if any).
-	 */
-	@Override /* ServletResponse */
-	public PrintWriter getWriter() throws IOException {
-		return getWriter(true);
-	}
-
-	/**
-	 * Convenience method meant to be used when rendering directly to a browser with no buffering.
-	 * Sets the header <js>"x-content-type-options=nosniff"</js> so that output is rendered
-	 * immediately on IE and Chrome without any buffering for content-type sniffing.
-	 *
-	 * @param contentType The value to set as the <code>Content-Type</code> on the response.
-	 * @return The raw writer.
-	 * @throws IOException
-	 */
-	public PrintWriter getDirectWriter(String contentType) throws IOException {
-		setContentType(contentType);
-		setHeader("x-content-type-options", "nosniff");
-		return getWriter();
-	}
-
-	/**
-	 * Equivalent to {@link HttpServletResponse#getWriter()}, except
-	 * 	wraps the output stream if an {@link Encoder} was found that matched
-	 * 	the <code>Accept-Encoding</code> header and sets the <code>Content-Encoding</code>
-	 * 	header to the appropriate value.
-	 *
-	 * @return The negotiated writer.
-	 * @throws IOException
-	 */
-	public PrintWriter getNegotiatedWriter() throws IOException {
-		return getWriter(false);
-	}
-
-	private PrintWriter getWriter(boolean raw) throws IOException {
-		// If plain text requested, override it now.
-		if (request.isPlainText()) {
-			setHeader("Content-Type", "text/plain");
-		}
-
-		try {
-			OutputStream out = (raw ? getOutputStream() : getNegotiatedOutputStream());
-			return new PrintWriter(new OutputStreamWriter(out, getCharacterEncoding()));
-		} catch (UnsupportedEncodingException e) {
-			String ce = getCharacterEncoding();
-			setCharacterEncoding("UTF-8");
-			throw new RestException(SC_NOT_ACCEPTABLE, "Unsupported charset in request header ''Accept-Charset'': ''{0}''", ce);
-		}
-	}
-
-	/**
-	 * Returns the <code>Content-Type</code> header stripped of the charset attribute if present.
-	 *
-	 * @return The <code>media-type</code> portion of the <code>Content-Type</code> header.
-	 */
-	public String getMediaType() {
-		String contentType = getContentType();
-		if (contentType == null)
-			return null;
-		int i = contentType.indexOf(';');
-		if (i == -1)
-			return contentType;
-		return contentType.substring(0, i).trim();
-
-	}
-
-	/**
-	 * Redirects to the specified URI.
-	 * <p>
-	 * Relative URIs are always interpreted as relative to the context root.
-	 * This is similar to how WAS handles redirect requests, and is different from how Tomcat
-	 * 	handles redirect requests.
-	 */
-	@Override /* ServletResponse */
-	public void sendRedirect(String uri) throws IOException {
-		char c = (uri.length() > 0 ? uri.charAt(0) : 0);
-		if (c != '/' && uri.indexOf("://") == -1)
-			uri = request.getContextPath() + '/' + uri;
-		super.sendRedirect(uri);
-	}
-
-	/**
-	 * Returns the URL-encoding serializer associated with this response.
-	 *
-	 * @return The URL-encoding serializer associated with this response.
-	 */
-	public UrlEncodingSerializer getUrlEncodingSerializer() {
-		return urlEncodingSerializer;
-	}
-
-	@Override /* ServletResponse */
-	public void setHeader(String name, String value) {
-		// Jetty doesn't set the content type correctly if set through this method.
-		// Tomcat/WAS does.
-		if (name.equalsIgnoreCase("Content-Type"))
-			super.setContentType(value);
-		else
-			super.setHeader(name, value);
-	}
-}