You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by jo...@apache.org on 2010/05/04 02:20:04 UTC
svn commit: r940681 - in
/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets:
http/HttpResponseBuilder.java rewrite/MutableContent.java
Author: johnh
Date: Tue May 4 00:20:03 2010
New Revision: 940681
URL: http://svn.apache.org/viewvc?rev=940681&view=rev
Log:
HttpResponseBuilder-as-MutableContent.
Makes HttpResponseBuilder extend MutableContent. The underlying semantics of the class remain the same -- two new mutation APIs are added as well. By default, HTML parsing is not supported (ie. with new HttpResponseBuilder().getDocument()), which is status quo.
This change is a step toward updating the HTTP object rewriter interface with HttpResponseBuilder as mutation object.
Modified:
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponseBuilder.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/MutableContent.java
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponseBuilder.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponseBuilder.java?rev=940681&r1=940680&r2=940681&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponseBuilder.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpResponseBuilder.java Tue May 4 00:20:03 2010
@@ -26,6 +26,11 @@ import org.apache.commons.lang.ArrayUtil
import org.apache.commons.lang.StringUtils;
import org.apache.shindig.common.util.CharsetUtil;
import org.apache.shindig.common.util.DateUtil;
+import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.parse.GadgetHtmlParser;
+import org.apache.shindig.gadgets.rewrite.MutableContent;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
import java.nio.charset.Charset;
import java.util.Collection;
@@ -36,28 +41,32 @@ import java.util.Map;
/**
* Constructs HttpResponse objects.
*/
-public class HttpResponseBuilder {
+public class HttpResponseBuilder extends MutableContent {
private int httpStatusCode = HttpResponse.SC_OK;
private final Multimap<String, String> headers = HttpResponse.newHeaderMultimap();
- private byte[] responseBytes = ArrayUtils.EMPTY_BYTE_ARRAY;
private final Map<String, String> metadata = Maps.newHashMap();
- public HttpResponseBuilder() {}
+ public HttpResponseBuilder() {
+ super(unsupportedParser(), (String)null);
+ this.setResponse(null);
+ }
public HttpResponseBuilder(HttpResponseBuilder builder) {
+ super(unsupportedParser(), builder.create());
httpStatusCode = builder.httpStatusCode;
headers.putAll(builder.headers);
metadata.putAll(builder.metadata);
- responseBytes = builder.responseBytes;
}
public HttpResponseBuilder(HttpResponse response) {
+ this(unsupportedParser(), response);
+ }
+
+ public HttpResponseBuilder(GadgetHtmlParser parser, HttpResponse response) {
+ super(parser, response);
httpStatusCode = response.getHttpStatusCode();
-
headers.putAll(response.getHeaders());
-
metadata.putAll(response.getMetadata());
- responseBytes = response.getResponseAsBytes();
}
/**
@@ -71,7 +80,7 @@ public class HttpResponseBuilder {
* @param body The response string. Converted to UTF-8 bytes and copied when set.
*/
public HttpResponseBuilder setResponseString(String body) {
- responseBytes = CharsetUtil.getUtf8Bytes(body);
+ setContentBytes(CharsetUtil.getUtf8Bytes(body));
setEncoding(CharsetUtil.UTF8);
return this;
}
@@ -103,8 +112,9 @@ public class HttpResponseBuilder {
if (responseBytes == null) {
responseBytes = ArrayUtils.EMPTY_BYTE_ARRAY;
}
- this.responseBytes = new byte[responseBytes.length];
- System.arraycopy(responseBytes, 0, this.responseBytes, 0, responseBytes.length);
+ byte[] newBytes = new byte[responseBytes.length];
+ System.arraycopy(responseBytes, 0, newBytes, 0, responseBytes.length);
+ setContentBytes(newBytes);
return this;
}
@@ -115,23 +125,15 @@ public class HttpResponseBuilder {
if (responseBytes == null) {
responseBytes = ArrayUtils.EMPTY_BYTE_ARRAY;
}
- this.responseBytes = responseBytes;
+ setContentBytes(responseBytes);
return this;
}
- /**
- * @param httpStatusCode The HTTP response status, defined on HttpResponse.
- */
public HttpResponseBuilder setHttpStatusCode(int httpStatusCode) {
this.httpStatusCode = httpStatusCode;
return this;
}
- /**
- * Add a single header to the response. If a value for the given name is already set, a second
- * value is added. If you wish to overwrite any possible values for a header, use
- * {@link #setHeader(String, String)}.
- */
public HttpResponseBuilder addHeader(String name, String value) {
if (name != null) {
headers.put(name, value);
@@ -139,9 +141,6 @@ public class HttpResponseBuilder {
return this;
}
- /**
- * Sets a single header value, overwriting any previously set headers with the same name.
- */
public HttpResponseBuilder setHeader(String name, String value) {
if (name != null) {
headers.replaceValues(name, Lists.newArrayList(value));
@@ -149,9 +148,13 @@ public class HttpResponseBuilder {
return this;
}
- /**
- * Adds an entire map of headers to the response.
- */
+ public String getHeader(String name) {
+ if (name != null && headers.containsKey(name)) {
+ return headers.get(name).iterator().next();
+ }
+ return null;
+ }
+
public HttpResponseBuilder addHeaders(Map<String, String> headers) {
for (Map.Entry<String,String> entry : headers.entrySet()) {
this.headers.put(entry.getKey(), entry.getValue());
@@ -159,9 +162,6 @@ public class HttpResponseBuilder {
return this;
}
- /**
- * Adds all headers in the provided multimap to the response.
- */
public HttpResponseBuilder addAllHeaders(Map<String, ? extends List<String>> headers) {
for (Map.Entry<String,? extends List<String>> entry : headers.entrySet()) {
this.headers.putAll(entry.getKey(), entry.getValue());
@@ -169,18 +169,10 @@ public class HttpResponseBuilder {
return this;
}
- /**
- * Remove all headers with the given name from the response.
- *
- * @return Any values that were removed from the response.
- */
public Collection<String> removeHeader(String name) {
return headers.removeAll(name);
}
- /**
- * @param cacheTtl The time to live for this response, in seconds.
- */
public HttpResponseBuilder setCacheTtl(int cacheTtl) {
headers.removeAll("Pragma");
headers.removeAll("Expires");
@@ -188,10 +180,6 @@ public class HttpResponseBuilder {
return this;
}
- /**
- * @param expirationTime The expiration time for this response, in
- * milliseconds since the Unix epoch.
- */
public HttpResponseBuilder setExpirationTime(long expirationTime) {
headers.removeAll("Cache-Control");
headers.removeAll("Pragma");
@@ -210,17 +198,11 @@ public class HttpResponseBuilder {
return this;
}
- /**
- * Adds a new piece of metadata to the response.
- */
public HttpResponseBuilder setMetadata(String key, String value) {
metadata.put(key, value);
return this;
}
- /**
- * Merges the given Map of metadata into the existing metadata.
- */
public HttpResponseBuilder setMetadata(Map<String, String> metadata) {
this.metadata.putAll(metadata);
return this;
@@ -233,12 +215,28 @@ public class HttpResponseBuilder {
Map<String, String> getMetadata() {
return metadata;
}
-
+
byte[] getResponse() {
- return responseBytes;
+ // Supported to avoid copying data unnecessarily.
+ return getRawContentBytes();
}
public int getHttpStatusCode() {
return httpStatusCode;
}
+
+ private static GadgetHtmlParser unsupportedParser() {
+ return new GadgetHtmlParser(null) {
+ @Override
+ protected Document parseDomImpl(String source) throws GadgetException {
+ throw new UnsupportedOperationException("Using HttpResponseBuilder in non-rewriting context");
+ }
+
+ @Override
+ protected DocumentFragment parseFragmentImpl(String source)
+ throws GadgetException {
+ throw new UnsupportedOperationException("Using HttpResponseBuilder in non-rewriting context");
+ }
+ };
+ }
}
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/MutableContent.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/MutableContent.java?rev=940681&r1=940680&r2=940681&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/MutableContent.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/MutableContent.java Tue May 4 00:20:03 2010
@@ -18,6 +18,7 @@
package org.apache.shindig.gadgets.rewrite;
import org.apache.commons.io.IOUtils;
+import org.apache.shindig.common.util.CharsetUtil;
import org.apache.shindig.gadgets.GadgetException;
import org.apache.shindig.gadgets.http.HttpResponse;
import org.apache.shindig.gadgets.parse.GadgetHtmlParser;
@@ -118,7 +119,7 @@ public class MutableContent {
document = null;
contentSource = null;
contentBytes = null;
- numChanges++;
+ incrementNumChanges();
}
}
@@ -127,6 +128,10 @@ public class MutableContent {
* @return Active content as InputStream.
*/
public InputStream getContentBytes() {
+ return new ByteArrayInputStream(getRawContentBytes());
+ }
+
+ protected byte[] getRawContentBytes() {
if (contentBytes == null) {
if (contentSource != null) {
try {
@@ -136,25 +141,20 @@ public class MutableContent {
// Doesn't occur; responseBytes wrapped as a ByteArrayInputStream.
}
} else if (content != null) {
- try {
- contentBytes = content.getBytes("UTF8");
- } catch (UnsupportedEncodingException e) {
- // Doesn't happen.
- }
+ contentBytes = CharsetUtil.getUtf8Bytes(content);
} else if (document != null) {
- try {
- contentBytes = HtmlSerialization.serialize(document).getBytes("UTF8");
- } catch (UnsupportedEncodingException e) {
- // Doesn't happen.
- }
+ CharsetUtil.getUtf8Bytes(HtmlSerialization.serialize(document));
}
}
- return new ByteArrayInputStream(contentBytes);
+ return contentBytes;
}
/**
* Sets the object's contentBytes as the given raw input.
* Note, this operation may clear the document if the content has changed.
+ * Also note, it's mandated that the new bytes array will NOT be modified
+ * by the caller of this API. The array is not copied, for performance reasons.
+ * If the caller may modify a byte array, it MUST pass in a new copy.
* @param newBytes New content.
*/
public void setContentBytes(byte[] newBytes) {
@@ -163,7 +163,7 @@ public class MutableContent {
document = null;
contentSource = null;
content = null;
- numChanges++;
+ incrementNumChanges();
}
}
@@ -176,7 +176,7 @@ public class MutableContent {
content = null;
contentSource = null;
contentBytes = null;
- numChanges++;
+ incrementNumChanges();
}
}
@@ -207,6 +207,10 @@ public class MutableContent {
public int getNumChanges() {
return numChanges;
}
+
+ protected void incrementNumChanges() {
+ ++numChanges;
+ }
/**
* True if current state has a parsed document. Allows rewriters to switch mode based on