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;
+ }
+
+}