You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by ad...@apache.org on 2015/03/12 22:18:11 UTC

[04/34] wicket git commit: WICKET-5819 - Own file for PartWriterCallback

WICKET-5819 - Own file for PartWriterCallback

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/4434d94f
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/4434d94f
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/4434d94f

Branch: refs/heads/master
Commit: 4434d94f95c5c8b8b6e70e65ab630ccac42f9b6d
Parents: ff1bf27
Author: klopfdreh <kl...@tobiass-mbp>
Authored: Sat Feb 7 20:06:27 2015 +0100
Committer: klopfdreh <kl...@tobiass-mbp>
Committed: Sat Feb 7 20:06:27 2015 +0100

----------------------------------------------------------------------
 .../media/MediaStreamingResourceReference.java  | 234 +++++--------------
 .../markup/html/media/PartWriterCallback.java   | 188 +++++++++++++++
 2 files changed, 252 insertions(+), 170 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/4434d94f/wicket-core/src/main/java/org/apache/wicket/markup/html/media/MediaStreamingResourceReference.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/media/MediaStreamingResourceReference.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/media/MediaStreamingResourceReference.java
index 0f7568f..54d9442 100755
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/media/MediaStreamingResourceReference.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/media/MediaStreamingResourceReference.java
@@ -17,14 +17,11 @@
 package org.apache.wicket.markup.html.media;
 
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.util.Locale;
 
 import org.apache.wicket.Application;
 import org.apache.wicket.WicketRuntimeException;
 import org.apache.wicket.core.util.resource.PackageResourceStream;
-import org.apache.wicket.protocol.http.servlet.ResponseIOException;
 import org.apache.wicket.request.Request;
 import org.apache.wicket.request.Response;
 import org.apache.wicket.request.cycle.RequestCycle;
@@ -46,8 +43,6 @@ public class MediaStreamingResourceReference extends ResourceReference
 
 	private static final long serialVersionUID = 1L;
 
-	private Integer buffer;
-
 	public MediaStreamingResourceReference(Class<?> scope, String name, Locale locale,
 		String style, String variation)
 	{
@@ -75,152 +70,96 @@ public class MediaStreamingResourceReference extends ResourceReference
 		AbstractResource mediaStreamingResource = new AbstractResource()
 		{
 			private static final long serialVersionUID = 1L;
-			private Long startbyte;
-			private Long endbyte;
-			private PackageResourceStream packageResourceStream;
 
 			@Override
 			protected ResourceResponse newResourceResponse(Attributes attributes)
 			{
+				PackageResourceStream packageResourceStream = null;
+				Long startbyte = null;
+				Long endbyte = null;
 				try
 				{
 					Request request = attributes.getRequest();
 					Response response = attributes.getResponse();
-					if (request instanceof WebRequest && response instanceof WebResponse)
+
+					if (!(request instanceof WebRequest) || !(response instanceof WebResponse))
 					{
-						WebRequest webRequest = (WebRequest)request;
-						WebResponse webResponse = (WebResponse)response;
+						throw new IllegalStateException(
+							"Either the request is no web request or the response is no web response");
+					}
+
+					WebRequest webRequest = (WebRequest)request;
+					WebResponse webResponse = (WebResponse)response;
 
-						packageResourceStream = new PackageResourceStream(
-							MediaStreamingResourceReference.this.getScope(),
-							MediaStreamingResourceReference.this.getName(),
-							MediaStreamingResourceReference.this.getLocale(),
-							MediaStreamingResourceReference.this.getStyle(),
-							MediaStreamingResourceReference.this.getVariation());
-						long length = packageResourceStream.length().bytes();
+					packageResourceStream = new PackageResourceStream(
+						MediaStreamingResourceReference.this.getScope(),
+						MediaStreamingResourceReference.this.getName(),
+						MediaStreamingResourceReference.this.getLocale(),
+						MediaStreamingResourceReference.this.getStyle(),
+						MediaStreamingResourceReference.this.getVariation());
 
-						ResourceResponse resourceResponse = new ResourceResponse();
-						resourceResponse.setContentType(packageResourceStream.getContentType());
-						resourceResponse.setFileName(MediaStreamingResourceReference.this.getName());
-						resourceResponse.setContentDisposition(ContentDisposition.ATTACHMENT);
-						resourceResponse.setLastModified(packageResourceStream.lastModifiedTime());
 
-						// We accept ranges, so that the player can
-						// load and play content from a specific byte position
-						webResponse.setHeader("Accept-Range", "bytes");
+					long length = packageResourceStream.length().bytes();
 
-						// Calculating the response code and the byte range to be played
-						String rangeHeader = webRequest.getHeader("range");
-						if (rangeHeader == null || "".equals(rangeHeader))
+					ResourceResponse resourceResponse = new ResourceResponse();
+					resourceResponse.setContentType(packageResourceStream.getContentType());
+					resourceResponse.setFileName(MediaStreamingResourceReference.this.getName());
+					resourceResponse.setContentDisposition(ContentDisposition.ATTACHMENT);
+					resourceResponse.setLastModified(packageResourceStream.lastModifiedTime());
+
+					// We accept ranges, so that the player can
+					// load and play content from a specific byte position
+					webResponse.setHeader("Accept-Range", "bytes");
+
+					// Calculating the response code and the byte range to be played
+					String rangeHeader = webRequest.getHeader("range");
+					if (rangeHeader == null || "".equals(rangeHeader))
+					{
+						resourceResponse.setStatusCode(200);
+						resourceResponse.setContentLength(length);
+					}
+					else
+					{
+						rangeHeader = rangeHeader.replaceAll(" ", "");
+						// If the range header is filled 206 for
+						// partial content has to be returned
+						resourceResponse.setStatusCode(206);
+
+						// And now the calculation of the range to be read
+						// and to be given as response within the Content-Range header
+						// for more information take a look here:
+						// http://stackoverflow.com/questions/8293687/sample-http-range-request-session
+						String range = rangeHeader.substring(rangeHeader.indexOf('=') + 1,
+							rangeHeader.length());
+						String[] rangeParts = range.split("-");
+						if (rangeParts[0].equals("0"))
 						{
-							resourceResponse.setStatusCode(200);
+							webResponse.setHeader("Content-Range", "bytes 0-" + (length - 1) + "/" +
+								length);
 							resourceResponse.setContentLength(length);
 						}
 						else
 						{
-							rangeHeader = rangeHeader.replaceAll(" ", "");
-							// If the range header is filled 206 for
-							// partial content has to be returned
-							resourceResponse.setStatusCode(206);
-
-							// And now the calculation of the range to be read
-							// and to be given as response within the Content-Range header
-							String range = rangeHeader.substring(rangeHeader.indexOf('=') + 1,
-								rangeHeader.length());
-							String[] rangeParts = range.split("-");
-							if (rangeParts[0].equals("0"))
+							startbyte = Long.parseLong(rangeParts[0]);
+							if (rangeParts.length == 2)
 							{
-								webResponse.setHeader("Content-Range", "bytes 0-" + (length - 1) +
-									"/" + length);
-								resourceResponse.setContentLength(length);
+								endbyte = Long.parseLong(rangeParts[1]);
 							}
 							else
 							{
-								startbyte = Long.parseLong(rangeParts[0]);
-								if (rangeParts.length == 2)
-								{
-									endbyte = Long.parseLong(rangeParts[1]);
-								}
-								else
-								{
-									endbyte = length - 1;
-								}
-								webResponse.setHeader("Content-Range", "bytes " + startbyte + "-" +
-									endbyte + "/" + length);
-								resourceResponse.setContentLength((endbyte - startbyte) + 1);
+								endbyte = length - 1;
 							}
+							webResponse.setHeader("Content-Range", "bytes " + startbyte + "-" +
+								endbyte + "/" + length);
+							resourceResponse.setContentLength((endbyte - startbyte) + 1);
 						}
+					}
 
-						resourceResponse.setWriteCallback(new WriteCallback()
-						{
-							@Override
-							public void writeData(Attributes attributes) throws IOException
-							{
-								try
-								{
-									InputStream inputStream = packageResourceStream.getInputStream();
-									OutputStream outputStream = attributes.getResponse()
-										.getOutputStream();
-									byte[] buffer = new byte[MediaStreamingResourceReference.this.getBuffer()];
-
-									if (startbyte != null || endbyte != null)
-									{
-										// skipping the first bytes which are
-										// not requested by the client
-										inputStream.skip(startbyte);
-
-										long totalBytes = 0;
-										int actualReadBytes = 0;
-
-										while ((actualReadBytes = inputStream.read(buffer)) != -1)
-										{
-											totalBytes = totalBytes + buffer.length;
-											long lowerBuffer = endbyte - totalBytes;
-											if (lowerBuffer <= 0)
-											{
-												buffer = (byte[])resizeArray(buffer,
-													actualReadBytes);
-												outputStream.write(buffer);
-												break;
-											}
-											else
-											{
-												outputStream.write(buffer);
-											}
-										}
-									}
-									else
-									{
-										while (inputStream.read(buffer) != -1)
-										{
-											outputStream.write(buffer);
-										}
-									}
-								}
-								catch (ResponseIOException e)
-								{
-									// the client has closed the connection and
-									// doesn't read the stream further on
-									// (in tomcats
-									// org.apache.catalina.connector.ClientAbortException)
-									// we ignore this case
-								}
-								catch (Exception e)
-								{
-									throw new WicketRuntimeException(
-										"A problem occurred while writing the buffer to the output stream.",
-										e);
-								}
-							}
-						});
+					// Apply the writer callback to send the requested part to the client
+					resourceResponse.setWriteCallback(new PartWriterCallback(
+						packageResourceStream, startbyte, endbyte));
 
-						return resourceResponse;
-					}
-					else
-					{
-						throw new IllegalStateException(
-							"Either the request is no web request or the response is no web response");
-					}
+					return resourceResponse;
 				}
 				catch (Exception e)
 				{
@@ -249,51 +188,6 @@ public class MediaStreamingResourceReference extends ResourceReference
 	}
 
 	/**
-	 * Sets the buffer size used to send the data to the client
-	 * 
-	 * @return the buffer size used to send the data to the client
-	 */
-	public Integer getBuffer()
-	{
-		return buffer != null ? buffer : 4048;
-	}
-
-	/**
-	 * Sets the buffer size used to send the data to the client
-	 * 
-	 * @param buffer
-	 *            the buffer size used to send the data to the client
-	 */
-	public void setBuffer(Integer buffer)
-	{
-		this.buffer = buffer;
-	}
-
-	/**
-	 * Reallocates an array with a new size, and copies the contents of the old array to the new
-	 * array.
-	 * 
-	 * @param oldArray
-	 *            the old array, to be reallocated.
-	 * @param newSize
-	 *            the new array size.
-	 * @return A new array with the same contents.
-	 */
-	@SuppressWarnings("rawtypes")
-	private static Object resizeArray(Object oldArray, int newSize)
-	{
-		int oldSize = java.lang.reflect.Array.getLength(oldArray);
-		Class elementType = oldArray.getClass().getComponentType();
-		Object newArray = java.lang.reflect.Array.newInstance(elementType, newSize);
-		int preserveLength = Math.min(oldSize, newSize);
-		if (preserveLength > 0)
-		{
-			System.arraycopy(oldArray, 0, newArray, 0, preserveLength);
-		}
-		return newArray;
-	}
-
-	/**
 	 * Gets the type of the media this resource reference belongs to
 	 * 
 	 * @return the type of this media

http://git-wip-us.apache.org/repos/asf/wicket/blob/4434d94f/wicket-core/src/main/java/org/apache/wicket/markup/html/media/PartWriterCallback.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/media/PartWriterCallback.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/media/PartWriterCallback.java
new file mode 100644
index 0000000..694544d
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/media/PartWriterCallback.java
@@ -0,0 +1,188 @@
+/*
+ * 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.wicket.markup.html.media;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.core.util.resource.PackageResourceStream;
+import org.apache.wicket.protocol.http.servlet.ResponseIOException;
+import org.apache.wicket.request.resource.AbstractResource.WriteCallback;
+import org.apache.wicket.request.resource.IResource.Attributes;
+
+/**
+ * Used to read a part of the package resource stream and write it to the output stream of the
+ * response.
+ * 
+ * @author Tobias Soloschenko
+ *
+ */
+public class PartWriterCallback extends WriteCallback
+{
+	private PackageResourceStream packageResourceStream;
+
+	private Long startbyte;
+
+	private Long endbyte;
+
+	private Integer buffer;
+
+	/**
+	 * Creates a part writer callback.<br>
+	 * <br>
+	 * Reads a part of the given package resource stream. If the startbyte parameter is not null the
+	 * number of bytes are skipped till the stream is read. If the endbyte is not null the stream is
+	 * read till endbyte, else to the end of the whole stream. If startbyte and endbyte is null the
+	 * whole stream is read.
+	 * 
+	 * @param packageResourceStream
+	 *            the package resource stream to be read
+	 * @param startbyte
+	 *            the start position to read from (if not null the number of bytes are skipped till
+	 *            the stream is read)
+	 * @param endbyte
+	 *            the end position to read to (if not null the stream is going to be read till
+	 *            endbyte, else to the end of the whole stream)
+	 */
+	public PartWriterCallback(PackageResourceStream packageResourceStream, Long startbyte,
+		Long endbyte)
+	{
+		this.packageResourceStream = packageResourceStream;
+		this.startbyte = startbyte;
+		this.endbyte = endbyte;
+	}
+
+	/**
+	 * Writes the data
+	 * 
+	 * @param Attributes
+	 *            the attributes to get the output stream of the response
+	 */
+	@Override
+	public void writeData(Attributes attributes) throws IOException
+	{
+		try
+		{
+			InputStream inputStream = packageResourceStream.getInputStream();
+			OutputStream outputStream = attributes.getResponse().getOutputStream();
+			byte[] buffer = new byte[getBuffer()];
+
+			if (startbyte != null || endbyte != null)
+			{
+				// skipping the first bytes which are
+				// requested to be skipped by the client
+				if (startbyte != null)
+				{
+					inputStream.skip(startbyte);
+				}
+
+				// If there are no end bytes given read the whole stream till the end
+				if (endbyte == null)
+				{
+					endbyte = packageResourceStream.length().bytes();
+				}
+
+				long totalBytes = 0;
+				int actualReadBytes = 0;
+
+				while ((actualReadBytes = inputStream.read(buffer)) != -1)
+				{
+					totalBytes = totalBytes + buffer.length;
+					long lowerBuffer = endbyte - totalBytes;
+					if (lowerBuffer <= 0)
+					{
+						buffer = (byte[])resizeArray(buffer, actualReadBytes);
+						outputStream.write(buffer);
+						break;
+					}
+					else
+					{
+						outputStream.write(buffer);
+					}
+				}
+			}
+			else
+			{
+				while (inputStream.read(buffer) != -1)
+				{
+					outputStream.write(buffer);
+				}
+			}
+		}
+		catch (ResponseIOException e)
+		{
+			// the client has closed the connection and
+			// doesn't read the stream further on
+			// (in tomcats
+			// org.apache.catalina.connector.ClientAbortException)
+			// we ignore this case
+		}
+		catch (Exception e)
+		{
+			throw new WicketRuntimeException(
+				"A problem occurred while writing the buffer to the output stream.", e);
+		}
+	}
+
+	/**
+	 * Reallocates an array with a new size, and copies the contents of the old array to the new
+	 * array.
+	 * 
+	 * @param oldArray
+	 *            the old array, to be reallocated.
+	 * @param newSize
+	 *            the new array size.
+	 * @return A new array with the same contents.
+	 */
+	@SuppressWarnings("rawtypes")
+	private static Object resizeArray(Object oldArray, int newSize)
+	{
+		int oldSize = java.lang.reflect.Array.getLength(oldArray);
+		Class elementType = oldArray.getClass().getComponentType();
+		Object newArray = java.lang.reflect.Array.newInstance(elementType, newSize);
+		int preserveLength = Math.min(oldSize, newSize);
+		if (preserveLength > 0)
+		{
+			System.arraycopy(oldArray, 0, newArray, 0, preserveLength);
+		}
+		return newArray;
+	}
+
+	/**
+	 * Sets the buffer size used to send the data to the client
+	 * 
+	 * @return the buffer size used to send the data to the client (default is 4048)
+	 */
+	public Integer getBuffer()
+	{
+		return buffer != null ? buffer : 4048;
+	}
+
+	/**
+	 * Sets the buffer size used to send the data to the client
+	 * 
+	 * @param buffer
+	 *            the buffer size used to send the data to the client
+	 */
+	public void setBuffer(Integer buffer)
+	{
+		this.buffer = buffer;
+	}
+
+}