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/pr-86-media_tags
Commit: 4434d94f95c5c8b8b6e70e65ab630ccac42f9b6d
Parents: ff1bf27
Author: klopfdreh <klopfdreh@tobiass-mbp>
Authored: Sat Feb 7 20:06:27 2015 +0100
Committer: klopfdreh <klopfdreh@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;
+       }
+
+}

Reply via email to