You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by et...@apache.org on 2008/02/09 15:07:24 UTC
svn commit: r620115 - in /incubator/shindig/trunk/java/gadgets/src:
main/java/org/apache/shindig/gadgets/
main/java/org/apache/shindig/gadgets/http/
main/java/org/apache/shindig/util/ test/java/org/apache/shindig/gadgets/
Author: etnu
Date: Sat Feb 9 06:07:23 2008
New Revision: 620115
URL: http://svn.apache.org/viewvc?rev=620115&view=rev
Log:
Implemented ideas discussed on SHINDIG-46 with some additional changes. Cleaned up file loading and xml parsing routines to eliminate redundant code. Added qualifiers to test fixtures that were causing periodic build breakages.
Added:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/util/InputStreamConsumer.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/RemoteContentTest.java
Removed:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Utf8InputStream.java
Modified:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpecParser.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsFeatureLoader.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsLibrary.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/MessageBundleParser.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/MessageBundleSubstituter.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContent.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SpecParserException.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingServlet.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/RpcServlet.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/EasyMockTestCase.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetSpecParserTest.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetSpecTestFixture.java
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java?rev=620115&r1=620114&r2=620115&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java Sat Feb 9 06:07:23 2008
@@ -322,10 +322,9 @@
return;
}
- byte[] xml = null;
+ RemoteContent xml = null;
try {
- xml = fetcher.fetch(
- gadgetId.getURI().toURL(), wc.context.getOptions()).getByteArray();
+ xml = fetcher.fetch(gadgetId.getURI().toURL(), wc.context.getOptions());
} catch (MalformedURLException e) {
throw new GadgetException(
GadgetException.Code.FAILED_TO_RETRIEVE_CONTENT,
@@ -333,7 +332,7 @@
}
GadgetSpecParser specParser = new GadgetSpecParser();
- GadgetSpec spec = specParser.parse(gadgetId, xml);
+ GadgetSpec spec = specParser.parse(gadgetId, xml.getResponseAsString());
wc.gadget = new Gadget(gadgetId, spec, prefs);
// This isn't a separate job because if it is we'd just need another
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpecParser.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpecParser.java?rev=620115&r1=620114&r2=620115&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpecParser.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpecParser.java Sat Feb 9 06:07:23 2008
@@ -23,6 +23,7 @@
import org.xml.sax.SAXException;
import java.io.IOException;
+import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -47,28 +48,28 @@
* content.
*
* @param id Gadget.ID object that resulted in the provided data
- * @param xml The raw input xml
+ * @param xml The raw input xml.
* @return A new GadgetSpec
* @throws SpecParserException If {@code data} does not represent a valid
* {@code GadgetSpec}
*/
- public GadgetSpec parse(GadgetView.ID id, byte[] xml)
+ public GadgetSpec parse(GadgetView.ID id, String xml)
throws SpecParserException {
- if (null == xml || xml.length == 0) {
- throw new SpecParserException("Empty XML document.");
+ if (xml.length() == 0) {
+ throw new SpecParserException(GadgetException.Code.EMPTY_XML_DOCUMENT);
}
Document doc;
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- InputSource is = new InputSource(new Utf8InputStream(xml));
+ InputSource is = new InputSource(new StringReader(xml));
doc = factory.newDocumentBuilder().parse(is);
} catch (SAXException e) {
- throw new SpecParserException("Malformed XML document.");
+ throw new SpecParserException(e.getMessage());
} catch (ParserConfigurationException e) {
- throw new SpecParserException("Malformed XML document.");
+ throw new SpecParserException(e.getMessage());
} catch (IOException e) {
- throw new SpecParserException("Malformed XML document.");
+ throw new SpecParserException(e.getMessage());
}
ParsedGadgetSpec spec = new ParsedGadgetSpec();
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsFeatureLoader.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsFeatureLoader.java?rev=620115&r1=620114&r2=620115&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsFeatureLoader.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsFeatureLoader.java Sat Feb 9 06:07:23 2008
@@ -13,14 +13,13 @@
*/
package org.apache.shindig.gadgets;
+import org.apache.shindig.util.InputStreamConsumer;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
-import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@@ -186,14 +185,18 @@
* @param path Location of the resource list.
* @return A list of resources from the list.
*/
- private String[] readResourceList(String path) {
+ private String[] readResourceList(String path) throws IOException {
ClassLoader cl = JsFeatureLoader.class.getClassLoader();
InputStream is = cl.getResourceAsStream(path);
if (is == null) {
logger.warning("Unable to locate resource: " + path);
return new String[0];
} else {
- String names = new String(load(is));
+ String names = InputStreamConsumer.readToString(is);
+ if (names == null) {
+ logger.warning("Unable to load resource: " + path);
+ return new String[0];
+ }
return names.split("\n");
}
}
@@ -214,10 +217,9 @@
ClassLoader cl = JsFeatureLoader.class.getClassLoader();
InputStream is = cl.getResourceAsStream(name);
if (is != null) {
- byte[] content = load(is);
int lastSlash = name.lastIndexOf('/');
String base = (lastSlash == -1) ? name : name.substring(0, lastSlash + 1);
- feature = parse(content, base, true);
+ feature = parse(is, base, true);
}
} catch (GadgetException ge) {
logger.warning("Failed to load resource: " + name);
@@ -239,8 +241,8 @@
ParsedFeature feature = null;
if (file.canRead()) {
try {
- byte[] content = load(new FileInputStream(file));
- feature = parse(content, file.getParent() + '/', false);
+ feature = parse(
+ new FileInputStream(file), file.getParent() + '/', false);
} catch (IOException e) {
logger.warning("Error reading file: " + file.getAbsolutePath());
} catch (GadgetException ge) {
@@ -282,22 +284,18 @@
/**
* Parses the input into a dom tree.
- * @param xml
+ * @param is
* @param path The path the file was loaded from.
* @param isResource True if the file was a resource.
* @return A dom tree representing the feature.
* @throws GadgetException
*/
- private ParsedFeature parse(byte[] xml, String path, boolean isResource)
+ private ParsedFeature parse(InputStream is, String path, boolean isResource)
throws GadgetException {
- if (null == xml || xml.length == 0) {
- throw new GadgetException(GadgetException.Code.EMPTY_XML_DOCUMENT);
- }
Document doc;
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- InputSource is = new InputSource(new Utf8InputStream(xml));
doc = factory.newDocumentBuilder().parse(is);
} catch (SAXException e) {
throw new GadgetException(GadgetException.Code.MALFORMED_XML_DOCUMENT, e);
@@ -387,26 +385,6 @@
}
}
}
- }
-
- /**
- * Loads content from the specified stream.
- * @param is
- * @return The contents of the file.
- */
- private byte[] load(InputStream is) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte[] buf = new byte[8192];
- int read;
- try {
- while ((read = is.read(buf)) > 0) {
- baos.write(buf, 0, read);
- }
- } catch (IOException e) {
- return new byte[0];
- }
-
- return baos.toByteArray();
}
}
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsLibrary.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsLibrary.java?rev=620115&r1=620114&r2=620115&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsLibrary.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsLibrary.java Sat Feb 9 06:07:23 2008
@@ -13,12 +13,12 @@
*/
package org.apache.shindig.gadgets;
-import java.io.ByteArrayOutputStream;
+import org.apache.shindig.util.InputStreamConsumer;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
import java.util.logging.Logger;
/**
@@ -130,12 +130,11 @@
FileInputStream fis = null;
try {
fis = new FileInputStream(fileName);
+ return InputStreamConsumer.readToString(fis);
} catch (IOException e) {
throw new RuntimeException(
String.format("Error reading file %s", fileName), e);
}
-
- return loadFromInputStream(fis, fileName, "file");
}
/**
@@ -144,44 +143,21 @@
* @return The contents of the named resource.
*/
private static String loadResource(String name) {
- InputStream stream =
- JsLibrary.class.getClassLoader().getResourceAsStream(name);
- if (stream == null) {
+ try {
+ InputStream stream =
+ JsLibrary.class.getClassLoader().getResourceAsStream(name);
+ if (stream == null) {
+ throw new RuntimeException(
+ String.format("Could not find resource %s", name));
+ }
+ return InputStreamConsumer.readToString(stream);
+ } catch (IOException e) {
throw new RuntimeException(
String.format("Could not find resource %s", name));
}
- return loadFromInputStream(stream, name, "resource");
}
- /**
- * Loads content from the given input stream.
- * @param is
- * @param name
- * @param type
- * @return The contents of the stream.
- */
- private static String loadFromInputStream(InputStream is, String name,
- String type) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte[] buf = new byte[8192];
- int read = 0;
- try {
- while ((read = is.read(buf)) > 0) {
- baos.write(buf, 0, read);
- }
- } catch (IOException e) {
- throw new RuntimeException(
- String.format("Error reading %s %s", type, name), e);
- }
- String ret = null;
- try {
- ret = new String(baos.toByteArray(), "UTF8");
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException("Unexpected error: UTF8 encoding unsupported");
- }
- return ret;
- }
/**
* @param type
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/MessageBundleParser.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/MessageBundleParser.java?rev=620115&r1=620114&r2=620115&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/MessageBundleParser.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/MessageBundleParser.java Sat Feb 9 06:07:23 2008
@@ -21,6 +21,7 @@
import org.xml.sax.SAXException;
import java.io.IOException;
+import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
@@ -52,15 +53,15 @@
* @return Message bundle resulting from the parse
* @throws GadgetException If the bundle is empty or malformed
*/
- public MessageBundle parse(byte[] xml) throws GadgetException {
- if (null == xml || xml.length == 0) {
+ public MessageBundle parse(String xml) throws GadgetException {
+ if (xml.length() == 0) {
throw new GadgetException(GadgetException.Code.EMPTY_XML_DOCUMENT);
}
Document doc;
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- InputSource is = new InputSource(new Utf8InputStream(xml));
+ InputSource is = new InputSource(new StringReader(xml));
doc = factory.newDocumentBuilder().parse(is);
} catch (SAXException e) {
throw new GadgetException(GadgetException.Code.MALFORMED_XML_DOCUMENT);
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/MessageBundleSubstituter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/MessageBundleSubstituter.java?rev=620115&r1=620114&r2=620115&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/MessageBundleSubstituter.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/MessageBundleSubstituter.java Sat Feb 9 06:07:23 2008
@@ -82,20 +82,18 @@
// We definitely need a bundle, now we need to fetch it.
bundle = context.getMessageBundleCache().get(uri.toString());
if (bundle == null) {
- byte[] data = null;
+ RemoteContent data = null;
try {
- data = context.getHttpFetcher().fetch(
- uri.toURL(), context.getOptions()).getByteArray();
+ data = context.getHttpFetcher().fetch(uri.toURL(),
+ context.getOptions());
} catch (MalformedURLException e) {
throw new GadgetException(
GadgetException.Code.FAILED_TO_RETRIEVE_CONTENT,
String.format("Malformed message bundle URL: %s",
uri.toString()));
}
- if (data.length > 0) {
- bundle = parser.parse(data);
- context.getMessageBundleCache().put(uri.toString(), bundle);
- }
+ bundle = parser.parse(data.getResponseAsString());
+ context.getMessageBundleCache().put(uri.toString(), bundle);
}
}
}
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContent.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContent.java?rev=620115&r1=620114&r2=620115&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContent.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContent.java Sat Feb 9 06:07:23 2008
@@ -13,6 +13,7 @@
*/
package org.apache.shindig.gadgets;
+import java.io.UnsupportedEncodingException;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
@@ -23,20 +24,27 @@
* Represents the results of an HTTP content retrieval operation.
*/
public class RemoteContent {
- private int httpStatusCode = -1;
- private byte[] resultBody = new byte[0];
- private Map<String, List<String>> headers;
+ private final int httpStatusCode;
+ private static final String DEFAULT_ENCODING = "UTF-8";
+ private final String encoding;
+
+ // Used to lazily convert to a string representation of the input.
+ private String responseString = null;
+ private final byte[] responseBytes;
+ private final Map<String, List<String>> headers;
/**
* @param httpStatusCode
* @param resultBody
* @param headers May be null.
*/
- public RemoteContent(int httpStatusCode, byte[] resultBody,
+ public RemoteContent(int httpStatusCode, byte[] responseBytes,
Map<String, List<String>> headers) {
this.httpStatusCode = httpStatusCode;
- if (resultBody != null) {
- this.resultBody = resultBody;
+ if (responseBytes == null) {
+ this.responseBytes = new byte[0];
+ } else {
+ this.responseBytes = responseBytes;
}
Map<String, List<String>> tempHeaders = new HashMap<String, List<String>>();
@@ -52,6 +60,26 @@
}
this.headers = Collections.unmodifiableMap(tempHeaders);
+ this.encoding = detectEncoding();
+ }
+
+ /**
+ * Attempts to determine the encoding of the body. If it can't be determined,
+ * we use DEFAULT_ENCODING instead.
+ * @return The detected encoding or DEFAULT_ENCODING.
+ */
+ private String detectEncoding() {
+ String contentType = getHeader("Content-Type");
+ if (contentType != null) {
+ String[] parts = contentType.split(";");
+ if (parts.length == 2) {
+ int offset = parts[1].indexOf("charset=");
+ if (offset != -1) {
+ return parts[1].substring(offset + 8);
+ }
+ }
+ }
+ return DEFAULT_ENCODING;
}
public int getHttpStatusCode() {
@@ -59,7 +87,35 @@
}
public byte[] getByteArray() {
- return resultBody;
+ return responseBytes;
+ }
+
+ public String getEncoding() {
+ return encoding;
+ }
+
+ /**
+ * Attempts to convert the response body to a string using the Content-Type
+ * header. If no Content-Type header is specified (or it doesn't include an
+ * encoding), we will assume it is UTF-8.
+ *
+ * @return The body as a string.
+ */
+ public String getResponseAsString() {
+ if (responseString == null) {
+ try {
+ String response = new String(responseBytes, encoding);
+ // Strip BOM.
+ if (response.length() > 0 && response.codePointAt(0) == 0xFEFF) {
+ responseString = response.substring(1);
+ } else {
+ responseString = response;
+ }
+ } catch (UnsupportedEncodingException e) {
+ responseString = "Unable to convert from encoding: " + encoding;
+ }
+ }
+ return responseString;
}
/**
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SpecParserException.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SpecParserException.java?rev=620115&r1=620114&r2=620115&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SpecParserException.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SpecParserException.java Sat Feb 9 06:07:23 2008
@@ -17,21 +17,14 @@
* Exceptions for Gadget Spec parsing.
*/
public class SpecParserException extends GadgetException {
- private String message;
-
/**
* @param message
*/
public SpecParserException(String message) {
- super(GadgetException.Code.MALFORMED_XML_DOCUMENT);
- this.message = message;
+ super(GadgetException.Code.MALFORMED_XML_DOCUMENT, message);
}
- /**
- * @return The message for this exception.
- */
- @Override
- public String getMessage() {
- return message;
+ public SpecParserException(GadgetException.Code code) {
+ super(code);
}
}
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingServlet.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingServlet.java?rev=620115&r1=620114&r2=620115&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingServlet.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingServlet.java Sat Feb 9 06:07:23 2008
@@ -231,7 +231,7 @@
markup.append("<script>gadgets.util.runOnLoadHandlers();</script>");
markup.append("</body></html>");
- resp.getOutputStream().print(markup.toString());
+ resp.getWriter().print(markup.toString());
}
private void outputUrlGadget(Gadget gadget,
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java?rev=620115&r1=620114&r2=620115&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java Sat Feb 9 06:07:23 2008
@@ -73,10 +73,11 @@
String output;
try {
// Use raw param as key as URL may have to be decoded
- String json = new JSONObject().put(request.getParameter("url"), new JSONObject()
- .put("body", new String(results.getByteArray()))
- .put("rc", results.getHttpStatusCode())
- ).toString();
+ JSONObject resp = new JSONObject()
+ .put("body", results.getResponseAsString())
+ .put("rc", results.getHttpStatusCode());
+ String json = new JSONObject()
+ .put(request.getParameter("url"), new JSONObject()).toString();
output = UNPARSEABLE_CRUFT + json;
} catch (JSONException e) {
output = "";
@@ -153,7 +154,7 @@
* @return A URL object of the URL
* @throws ServletException if the URL fails security checks or is malformed.
*/
- private URL extractAndValidateUrl(HttpServletRequest request)
+ private URL extractAndValidateUrl(HttpServletRequest request)
throws ServletException {
String url = request.getParameter("url");
if (url == null) {
@@ -164,8 +165,8 @@
URI origin = new URI(request.getParameter("url"));
if (origin.getScheme() == null) {
// No scheme, assume it was double-encoded.
- origin = new URI(
- URLDecoder.decode(request.getParameter("url"), request.getCharacterEncoding()));
+ origin = new URI(URLDecoder.decode(request.getParameter("url"),
+ request.getCharacterEncoding()));
if (origin.getScheme() == null) {
throw new ServletException("Invalid URL " + origin.toString());
}
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/RpcServlet.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/RpcServlet.java?rev=620115&r1=620114&r2=620115&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/RpcServlet.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/RpcServlet.java Sat Feb 9 06:07:23 2008
@@ -82,6 +82,8 @@
JsonRpcRequest req = new JsonRpcRequest(postBody);
JSONObject out = req.process(state);
response.setStatus(HttpServletResponse.SC_OK);
+ response.setContentType("application/json; charset=utf-8");
+ response.setHeader("Content-Disposition", "attachment;filename=rpc.txt");
response.getWriter().write(out.toString());
} catch (UnsupportedEncodingException e) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/util/InputStreamConsumer.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/util/InputStreamConsumer.java?rev=620115&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/util/InputStreamConsumer.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/util/InputStreamConsumer.java Sat Feb 9 06:07:23 2008
@@ -0,0 +1,63 @@
+/*
+ * Licensed 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.shindig.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Used to consume an entire input stream. Don't use this for network
+ * streams or any other stream that doesn't have a known length. This is
+ * intended for reading resources from jars and the local file system only.
+ */
+public class InputStreamConsumer {
+
+ /**
+ * Loads content and returns it as a raw byte array.
+ * @param is
+ * @return The contents of the stream.
+ * @throws IOException on stream reading error.
+ */
+ public static byte[] readToByteArray(InputStream is) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buf = new byte[8192];
+ int read = 0;
+
+ while ((read = is.read(buf)) > 0) {
+ baos.write(buf, 0, read);
+ }
+
+ return baos.toByteArray();
+ }
+
+ /**
+ * Loads content from the given input stream as a UTF-8-encoded string.
+ *
+ * @param is
+ * @return The contents of the stream.
+ * @throws IOException on stream reading error.
+ */
+ public static String readToString(InputStream is) throws IOException {
+ byte[] bytes = readToByteArray(is);
+ try {
+ return new String(bytes, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // UTF-8 is required by the Java spec.
+ throw new RuntimeException("UTF-8 not supported!", e);
+ }
+ }
+}
Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/EasyMockTestCase.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/EasyMockTestCase.java?rev=620115&r1=620114&r2=620115&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/EasyMockTestCase.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/EasyMockTestCase.java Sat Feb 9 06:07:23 2008
@@ -1,19 +1,19 @@
-/*
- * $Id$
+/**
+ * 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
*
- * Copyright 2007 The Apache Software Foundation
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Licensed 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.
+ * 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.shindig.gadgets;
Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetSpecParserTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetSpecParserTest.java?rev=620115&r1=620114&r2=620115&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetSpecParserTest.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetSpecParserTest.java Sat Feb 9 06:07:23 2008
@@ -41,11 +41,11 @@
BasicGadgetId id = new BasicGadgetId();
id.uri = new URI("http://example.org/text.xml");
id.moduleId = 1;
- byte[] xml = ("<?xml version=\"1.0\"?>" +
+ String xml = "<?xml version=\"1.0\"?>" +
"<Module>" +
"<ModulePrefs title=\"Hello, world!\"/>" +
"<Content type=\"html\">Hello!</Content>" +
- "</Module>").getBytes();
+ "</Module>";
GadgetSpec spec = parser.parse(id, xml);
assertEquals("Hello!", spec.getContentData());
@@ -56,7 +56,7 @@
BasicGadgetId id = new BasicGadgetId();
id.uri = new URI("http://example.org/text.xml");
id.moduleId = 1;
- byte[] xml = ("<?xml version=\"1.0\"?>" +
+ String xml = "<?xml version=\"1.0\"?>" +
"<Module>" +
"<ModulePrefs title=\"Test Enum\">" +
"<UserPref name=\"test\" datatype=\"enum\">" +
@@ -65,7 +65,7 @@
"</UserPref>" +
"</ModulePrefs>" +
"<Content type=\"html\">Hello!</Content>" +
- "</Module>").getBytes();
+ "</Module>";
GadgetSpec spec = parser.parse(id, xml);
List<GadgetSpec.UserPref> prefs = spec.getUserPrefs();
Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetSpecTestFixture.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetSpecTestFixture.java?rev=620115&r1=620114&r2=620115&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetSpecTestFixture.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetSpecTestFixture.java Sat Feb 9 06:07:23 2008
@@ -1,19 +1,19 @@
-/*
- * $Id$
- *
- * Copyright 2007 The Apache Software Foundation
- *
- * Licensed 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
+/**
+ * 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
+ * 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.
+ * 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.shindig.gadgets;
@@ -29,22 +29,22 @@
* Contains useful static objects for testing classes that deal with GadgetSpecs.
*/
public class GadgetSpecTestFixture {
- static final Locale EN_US_LOCALE = new Locale("en", "US");
+ public static final Locale EN_US_LOCALE = new Locale("en", "US");
private static final String DATETIME_TITLE = "Hello, World!";
private static final String DATETIME_CONTENT = "Goodbye, World!";
- static final String DATETIME_URI_STRING = "http://www.google.com/ig/modules/datetime.xml";
- static final URI DATETIME_URI;
- static final int DATETIME_MODULE_ID = 1;
- static final GadgetView.ID DATETIME_ID;
- static final String DATETIME_XML = "<?xml version=\"1.0\"?>" +
+ public static final String DATETIME_URI_STRING = "http://www.google.com/ig/modules/datetime.xml";
+ public static final URI DATETIME_URI;
+ public static final int DATETIME_MODULE_ID = 1;
+ public static final GadgetView.ID DATETIME_ID;
+ public static final String DATETIME_XML = "<?xml version=\"1.0\"?>" +
"<Module>" +
" <ModulePrefs title=\"" + DATETIME_TITLE + "\"/>" +
" <Content type=\"html\">" + DATETIME_CONTENT + "</Content>" +
"</Module>";
- static final GadgetSpec DATETIME_SPEC =
+ public static final GadgetSpec DATETIME_SPEC =
new GadgetSpec() {
public GadgetSpec copy() {
throw new UnsupportedOperationException();
Added: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/RemoteContentTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/RemoteContentTest.java?rev=620115&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/RemoteContentTest.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/RemoteContentTest.java Sat Feb 9 06:07:23 2008
@@ -0,0 +1,89 @@
+/**
+ * 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.shindig.gadgets;
+
+import junit.framework.TestCase;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+public class RemoteContentTest extends TestCase {
+ private Map<String, List<String>> headers;
+
+ @Override
+ public void setUp() {
+ headers = new HashMap<String, List<String>>();
+ }
+
+ private void addHeader(String name, String value) {
+ java.util.List<String> existing = headers.get(name);
+ if (existing == null) {
+ existing = new LinkedList<String>();
+ headers.put(name, existing);
+ }
+ existing.add(value);
+ }
+
+ public void testGetEncoding() throws Exception {
+ addHeader("Content-Type", "text/plain; charset=TEST-CHARACTER-SET");
+ RemoteContent content = new RemoteContent(200, new byte[0], headers);
+ assertEquals("TEST-CHARACTER-SET", content.getEncoding());
+ }
+
+ public void testEncodingDetectionUtf8WithBom() throws Exception {
+ // Input is UTF-8 with BOM.
+ byte[] data = new byte[] {
+ (byte)0xEF, (byte)0xBB, (byte)0xBF, 'h', 'e', 'l', 'l', 'o'
+ };
+ addHeader("Content-Type", "text/plain; charset=UTF-8");
+ RemoteContent content = new RemoteContent(200, data, headers);
+ assertEquals("hello", content.getResponseAsString());
+ }
+
+ public void testEncodingDetectionLatin1() throws Exception {
+ // Input is a basic latin-1 string with 1 non-UTF8 compatible char.
+ byte[] data = new byte[] {
+ 'h', (byte)0xE9, 'l', 'l', 'o'
+ };
+ addHeader("Content-Type", "text/plain; charset=iso-8859-1");
+ RemoteContent content = new RemoteContent(200, data, headers);
+ assertEquals("h\u00E9llo", content.getResponseAsString());
+ }
+
+ public void testEncodingDetectionBig5() throws Exception {
+ byte[] data = new byte[] {
+ (byte)0xa7, (byte)0x41, (byte)0xa6, (byte)0x6e
+ };
+ addHeader("Content-Type", "text/plain; charset=BIG5");
+ RemoteContent content = new RemoteContent(200, data, headers);
+ String resp = content.getResponseAsString();
+ assertEquals("\u4F60\u597D", content.getResponseAsString());
+ }
+
+ public void testPreserveBinaryData() {
+ byte[] data = new byte[] {
+ (byte)0x00, (byte)0xDE, (byte)0xEA, (byte)0xDB, (byte)0xEE, (byte)0xF0
+ };
+ addHeader("Content-Type", "application/octet-stream");
+ RemoteContent content = new RemoteContent(200, data, headers);
+ assertEquals(data, content.getByteArray());
+ }
+}