You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2015/03/30 21:01:29 UTC
[3/4] wicket git commit: Revert "Revert merging for WICKET-5819"
Revert "Revert merging for WICKET-5819"
This reverts commit 37116aff50ba0d4382c4b3371eb537bad29fa48d.
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/499f11fd
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/499f11fd
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/499f11fd
Branch: refs/heads/master
Commit: 499f11fdaf8783b3c795a93e9af7870aa2f84f3c
Parents: 792a0a4
Author: Andrea Del Bene <ad...@apache.org>
Authored: Fri Mar 13 21:40:20 2015 +0100
Committer: Martin Tzvetanov Grigorov <mg...@apache.org>
Committed: Mon Mar 30 21:59:14 2015 +0300
----------------------------------------------------------------------
.../util/resource/PackageResourceStream.java | 27 +-
.../markup/html/media/MediaComponent.java | 500 +++++++++++++++++++
.../media/MediaStreamingResourceReference.java | 182 +++++++
.../markup/html/media/PartWriterCallback.java | 185 +++++++
.../apache/wicket/markup/html/media/Source.java | 240 +++++++++
.../apache/wicket/markup/html/media/Track.java | 274 ++++++++++
.../wicket/markup/html/media/audio/Audio.java | 95 ++++
.../wicket/markup/html/media/video/Video.java | 210 ++++++++
.../html/media/MediaComponentsApplication.java | 52 ++
.../html/media/MediaTagsExtendedTestPage.html | 12 +
.../html/media/MediaTagsExtendedTestPage.java | 53 ++
.../wicket/markup/html/media/MediaTagsTest.java | 92 ++++
.../markup/html/media/MediaTagsTestPage.html | 10 +
.../markup/html/media/MediaTagsTestPage.java | 56 +++
.../wicket/markup/html/media/dummyAudio.mp3 | 0
.../wicket/markup/html/media/dummyPoster.jpg | 0
.../wicket/markup/html/media/dummySubtitles.vtt | 0
.../wicket/markup/html/media/dummyVideo.m4a | 0
wicket-examples/pom.xml | 2 +
.../org/apache/wicket/examples/media/Home.css | 32 ++
.../org/apache/wicket/examples/media/Home.html | 29 ++
.../org/apache/wicket/examples/media/Home.java | 116 +++++
.../examples/media/VideosApplication.java | 63 +++
.../apache/wicket/examples/media/novideo.gif | Bin 0 -> 25903 bytes
.../org/apache/wicket/examples/media/video.mp4 | Bin 0 -> 2757913 bytes
.../wicket/examples/homepage/HomePage.html | 1 +
wicket-examples/src/main/webapp/WEB-INF/web.xml | 22 +-
27 files changed, 2248 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-core/src/main/java/org/apache/wicket/core/util/resource/PackageResourceStream.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/core/util/resource/PackageResourceStream.java b/wicket-core/src/main/java/org/apache/wicket/core/util/resource/PackageResourceStream.java
index e76926d..4a1a4e6 100644
--- a/wicket-core/src/main/java/org/apache/wicket/core/util/resource/PackageResourceStream.java
+++ b/wicket-core/src/main/java/org/apache/wicket/core/util/resource/PackageResourceStream.java
@@ -18,6 +18,7 @@ package org.apache.wicket.core.util.resource;
import java.io.IOException;
import java.io.InputStream;
+import java.util.Locale;
import org.apache.wicket.Application;
import org.apache.wicket.WicketRuntimeException;
@@ -36,10 +37,10 @@ import org.apache.wicket.util.time.Time;
* {@link IResourceStreamLocator}.
*
* @author <a href="mailto:jbq@apache.org">Jean-Baptiste Quenot</a>
+ * @author Tobias Soloschenko
*/
public class PackageResourceStream extends AbstractResourceStream
{
- /** */
private static final long serialVersionUID = 1L;
private final IResourceStream resourceStream;
@@ -56,11 +57,33 @@ public class PackageResourceStream extends AbstractResourceStream
*/
public PackageResourceStream(Class<?> scope, String path)
{
+ this(scope, path, null, null, null);
+ }
+
+ /**
+ * Obtains an {@link IResourceStream} from the application's
+ * {@link IResourceStreamLocator#locate(Class, String)}
+ *
+ * @param scope
+ * This argument will be used to get the class loader for loading the package
+ * resource, and to determine what package it is in.
+ * @param path
+ * The path to the resource
+ * @param locale
+ * the locale of the resource to get
+ * @param style
+ * the style of the resource to get
+ * @param variation
+ * the variation of the resource to get
+ */
+ public PackageResourceStream(Class<?> scope, String path, Locale locale, String style,
+ String variation)
+ {
String absolutePath = Packages.absolutePath(scope, path);
resourceStream = Application.get()
.getResourceSettings()
.getResourceStreamLocator()
- .locate(scope, absolutePath, null, null, null, null, false);
+ .locate(scope, absolutePath, style, variation, locale, null, false);
if (resourceStream == null)
{
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-core/src/main/java/org/apache/wicket/markup/html/media/MediaComponent.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/media/MediaComponent.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/media/MediaComponent.java
new file mode 100755
index 0000000..093cd8e
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/media/MediaComponent.java
@@ -0,0 +1,500 @@
+/*
+ * 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 org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.request.Url;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.mapper.parameter.PageParametersEncoder;
+
+/**
+ * The media component is used to provide basic functionality to the video and audio component. The
+ * given media streaming resource reference supports Content-Ranges and other stuff to make the
+ * audio and video playback smooth.
+ *
+ * @author Tobias Soloschenko
+ * @author Andrew Lombardi
+ */
+public abstract class MediaComponent extends WebMarkupContainer
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * To be used for the <em>crossorigin</em> attribute
+ *
+ * @see {@link #setCrossOrigin(Cors)}
+ */
+ public enum Cors
+ {
+ ANONYMOUS("anonymous"), USER_CREDENTIALS("user-credentials"), NO_CORS("");
+
+ private final String realName;
+
+ private Cors(String realName)
+ {
+ this.realName = realName;
+ }
+
+ public String getRealName()
+ {
+ return realName;
+ }
+ }
+
+ /**
+ * To be used for the <em>preload</em> attribute
+ *
+ * @see {@link #setPreload(Preload)}
+ */
+ public enum Preload
+ {
+ NONE("none"), METADATA("metadata"), AUTO("auto");
+
+ public final String realName;
+
+ private Preload(String realname)
+ {
+ realName = realname;
+ }
+
+ public String getRealName()
+ {
+ return realName;
+ }
+ }
+
+ private boolean autoplay;
+
+ private boolean loop;
+
+ private boolean muted;
+
+ private boolean controls = true;
+
+ private Preload preload;
+
+ private String startTime;
+
+ private String endTime;
+
+ private String mediaGroup;
+
+ private Cors crossOrigin;
+
+ private final PageParameters pageParameters;
+
+ private final MediaStreamingResourceReference mediaStreamingResourceReference;
+
+ private final String url;
+
+ /**
+ * Constructor.
+ *
+ * @param id
+ * The component id
+ */
+ public MediaComponent(String id)
+ {
+ this(id, null, null, null, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param id
+ * The component id
+ * @param model
+ * The component model
+ */
+ public MediaComponent(String id, IModel<?> model)
+ {
+ this(id, model, null, null, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param id
+ * The component id
+ * @param mediaStreamingResourceReference
+ */
+ public MediaComponent(String id, MediaStreamingResourceReference mediaStreamingResourceReference)
+ {
+ this(id, null, null, null, mediaStreamingResourceReference);
+ }
+
+ public MediaComponent(String id, IModel<?> model,
+ MediaStreamingResourceReference mediaStreamingResourceReference)
+ {
+ this(id, model, null, null, mediaStreamingResourceReference);
+ }
+
+ public MediaComponent(String id,
+ MediaStreamingResourceReference mediaStreamingResourceReference,
+ PageParameters pageParameters)
+ {
+ this(id, null, null, pageParameters, mediaStreamingResourceReference);
+ }
+
+ public MediaComponent(String id, IModel<?> model,
+ MediaStreamingResourceReference mediaStreamingResourceReference,
+ PageParameters pageParameters)
+ {
+ this(id, model, null, pageParameters, mediaStreamingResourceReference);
+ }
+
+ public MediaComponent(String id, String url)
+ {
+ this(id, null, url, null, null);
+ }
+
+ public MediaComponent(String id, IModel<?> model, String url)
+ {
+ this(id, model, url, null, null);
+ }
+
+ public MediaComponent(String id, IModel<?> model, String url, PageParameters pageParameters)
+ {
+ this(id, model, url, pageParameters, null);
+ }
+
+ private MediaComponent(String id, IModel<?> model, String url, PageParameters pageParameters,
+ MediaStreamingResourceReference mediaStreamingResourceReference)
+ {
+ super(id, model);
+ this.url = url;
+ this.pageParameters = pageParameters;
+ this.mediaStreamingResourceReference = mediaStreamingResourceReference;
+ }
+
+ @Override
+ protected void onComponentTag(ComponentTag tag)
+ {
+ super.onComponentTag(tag);
+
+ // The time management is used to set the start / stop
+ // time in seconds of the movie to be played back
+ String timeManagement = "";
+ if (startTime != null)
+ {
+ timeManagement += "#t=" + startTime + (endTime != null ? "," + endTime : "");
+ }
+
+ if (mediaStreamingResourceReference != null)
+ {
+ CharSequence urlToMediaReference = RequestCycle.get().urlFor(
+ mediaStreamingResourceReference, pageParameters);
+ tag.put("src", urlToMediaReference + timeManagement);
+ }
+ else if (url != null)
+ {
+ Url encoded = new PageParametersEncoder().encodePageParameters(pageParameters);
+ String queryString = encoded.getQueryString();
+ tag.put("src", url + (queryString != null ? "?" + queryString : "") + timeManagement);
+ }
+
+ String mg = getMediaGroup();
+ if (mg != null)
+ {
+ tag.put("mediagroup", mg);
+ }
+
+ if (isAutoplay())
+ {
+ tag.put("autoplay", "autoplay");
+ }
+
+ if (isLooping())
+ {
+ tag.put("loop", "loop");
+ }
+
+ if (isMuted())
+ {
+ tag.put("muted", "muted");
+ }
+
+ if (hasControls())
+ {
+ tag.put("controls", "controls");
+ }
+
+ Preload _preload = getPreload();
+ if (_preload != null)
+ {
+ tag.put("preload", _preload.getRealName());
+ }
+
+ Cors cors = getCrossOrigin();
+ if (cors != null)
+ {
+ tag.put("crossorigin", cors.getRealName());
+ }
+ }
+
+ /**
+ * If the playback is autoplayed on load
+ *
+ * @return If the playback is autoplayed on load
+ */
+ public boolean isAutoplay()
+ {
+ return autoplay;
+ }
+
+ /**
+ * Sets the playback to be autoplayed on load
+ *
+ * @param autoplay
+ * If the playback is autoplayed on load
+ */
+ public void setAutoplay(boolean autoplay)
+ {
+ this.autoplay = autoplay;
+ }
+
+ /**
+ * If the playback is looped
+ *
+ * @return If the playback is looped
+ */
+ public boolean isLooping()
+ {
+ return loop;
+ }
+
+ /**
+ * Sets the playback to be looped
+ *
+ * @param loop
+ * If the playback is looped
+ */
+ public void setLooping(boolean loop)
+ {
+ this.loop = loop;
+ }
+
+ /**
+ * If the playback is muted initially
+ *
+ * @return If the playback is muted initially
+ */
+ public boolean isMuted()
+ {
+ return muted;
+ }
+
+ /**
+ * Sets the playback muted initially
+ *
+ * @param muted
+ * If the playback is muted initially
+ */
+ public void setMuted(boolean muted)
+ {
+ this.muted = muted;
+ }
+
+ /**
+ * If the controls are going to be displayed
+ *
+ * @return if the controls are going to displayed
+ */
+ public boolean hasControls()
+ {
+ return controls;
+ }
+
+ /**
+ * Sets if the controls are going to be displayed
+ *
+ * @param controls
+ * if the controls are going to displayed
+ */
+ public void setControls(Boolean controls)
+ {
+ this.controls = controls;
+ }
+
+ /**
+ * The type of preload
+ *
+ * @see {@link #setPreload(Preload)}
+ *
+ * @return the preload
+ */
+ public Preload getPreload()
+ {
+ return preload;
+ }
+
+ /**
+ * Sets the type of preload.
+ * <ul>
+ * <li><b>none</b>: Hints to the user agent that either the author does not expect the user to
+ * need the media resource, or that the server wants to minimise unnecessary traffic.</li>
+ *
+ * <li><b>metadata</b>: Hints to the user agent that the author does not expect the user to need
+ * the media resource, but that fetching the resource metadata (dimensions, first frame, track
+ * list, duration, etc) is reasonable.</li>
+ *
+ * <li><b>auto</b>: Hints to the user agent that the user agent can put the user's needs first
+ * without risk to the server, up to and including optimistically downloading the entire
+ * resource.</li>
+ * </ul>
+ * </p>
+ *
+ * @param preload
+ * the type of the preload
+ */
+ public void setPreload(Preload preload)
+ {
+ this.preload = preload;
+ }
+
+ /**
+ * Gets the position at which the media component starts the playback
+ *
+ * @see {@link #setStartTime(String)}
+ *
+ * @return the time at which position the media component starts the playback
+ */
+ public String getStartTime()
+ {
+ return startTime;
+ }
+
+ /**
+ * Sets the position at which the media component starts the playback<br>
+ * <br>
+ * t=<b>10</b>,20<br>
+ * t=<b>npt:10</b>,20<br>
+ * <br>
+ *
+ * t=<b>120s</b>,121.5s<br>
+ * t=<b>npt:120</b>,0:02:01.5<br>
+ * <br>
+ *
+ * t=<b>smpte-30:0:02:00</b>,0:02:01:15<br>
+ * t=<b>smpte-25:0:02:00:00</b>,0:02:01:12.1<br>
+ * <br>
+ *
+ * t=<b>clock:20090726T111901Z</b>,20090726T121901Z
+ *
+ * @param startTime
+ * the time at which position the media component starts the playback
+ */
+ public void setStartTime(String startTime)
+ {
+ this.startTime = startTime;
+ }
+
+ /**
+ * Gets the position at which the media component stops the playback
+ *
+ * @see {@link #setEndTime(String)}
+ *
+ * @return the time at which position the media component stops the playback
+ */
+ public String getEndTime()
+ {
+ return endTime;
+ }
+
+ /**
+ * Sets the position at which the media component stops the playback<br>
+ * <br>
+ * t=10,<b>20</b><br>
+ * t=npt:10,<b>20</b><br>
+ * <br>
+ *
+ * t=120s,<b>121.5s</b><br>
+ * t=npt:120,<b>0:02:01.5</b><br>
+ * <br>
+ *
+ * t=smpte-30:0:02:00,<b>0:02:01:15</b><br>
+ * t=smpte-25:0:02:00:00,<b>0:02:01:12.1</b><br>
+ * <br>
+ *
+ * t=clock:20090726T111901Z,<b>20090726T121901Z</b>
+ *
+ * @param endTime
+ * the time at which position the media component stops the playback
+ */
+ public void setEndTime(String endTime)
+ {
+ this.endTime = endTime;
+ }
+
+ /**
+ * Gets the media group.
+ *
+ * @return the media group
+ */
+ public String getMediaGroup()
+ {
+ return mediaGroup;
+ }
+
+ /**
+ * Sets the media group
+ *
+ * @param mediaGroup
+ * to be set
+ */
+ public void setMediaGroup(String mediaGroup)
+ {
+ this.mediaGroup = mediaGroup;
+ }
+
+ /**
+ * Gets the cross origin settings
+ *
+ * @see {@link #setCrossOrigin(Cors)}
+ *
+ * @return the cross origins settings
+ */
+ public Cors getCrossOrigin()
+ {
+ return crossOrigin;
+ }
+
+ /**
+ * Sets the cross origin settings<br>
+ * <br>
+ *
+ * <b>ANONYMOUS</b>: Cross-origin CORS requests for the element will not have the credentials
+ * flag set.<br>
+ * <br>
+ * <b>USER_CREDENTIALS</b>: Cross-origin CORS requests for the element will have the credentials
+ * flag set.<br>
+ * <br>
+ * <b>NO_CORS</b>: The empty string is also a valid keyword, and maps to the Anonymous state.
+ * The attribute's invalid value default is the Anonymous state. The missing value default, used
+ * when the attribute is omitted, is the No CORS state
+ *
+ * @param crossOrigin
+ * the cross origins settings to set
+ */
+ public void setCrossOrigin(Cors crossOrigin)
+ {
+ this.crossOrigin = crossOrigin;
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/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
new file mode 100755
index 0000000..76a208f
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/media/MediaStreamingResourceReference.java
@@ -0,0 +1,182 @@
+/*
+ * 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.util.Locale;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.request.Request;
+import org.apache.wicket.request.Response;
+import org.apache.wicket.request.http.WebRequest;
+import org.apache.wicket.request.http.WebResponse;
+import org.apache.wicket.request.resource.ContentDisposition;
+import org.apache.wicket.request.resource.PackageResource;
+import org.apache.wicket.request.resource.PackageResourceReference;
+import org.apache.wicket.util.resource.IResourceStream;
+import org.apache.wicket.util.string.Strings;
+
+/**
+ * The media streaming resource reference is used to provided streamed data based on bytes requested
+ * by the client for video and audio files
+ *
+ * @author Tobias Soloschenko
+ */
+public class MediaStreamingResourceReference extends PackageResourceReference
+{
+ private static final long serialVersionUID = 1L;
+
+ public MediaStreamingResourceReference(Class<?> scope, String name, Locale locale,
+ String style, String variation)
+ {
+ super(scope, name, locale, style, variation);
+ }
+
+ public MediaStreamingResourceReference(Class<?> scope, String name)
+ {
+ this(scope, name, null, null, null);
+ }
+
+ public MediaStreamingResourceReference(Key key)
+ {
+ super(key);
+ }
+
+ public MediaStreamingResourceReference(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ public PackageResource getResource()
+ {
+ return new PackageResource(getScope(), getName(), getLocale(), getStyle(), getVariation())
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected ResourceResponse newResourceResponse(Attributes attributes)
+ {
+ IResourceStream resourceStream = getResourceStream();
+ if (resourceStream == null)
+ {
+ throw new WicketRuntimeException("Cannot find resource: " + toString());
+ }
+ try
+ {
+ Request request = attributes.getRequest();
+ Response response = attributes.getResponse();
+
+ if (!(request instanceof WebRequest) || !(response instanceof WebResponse))
+ {
+ throw new IllegalStateException(
+ "Web request/response are required! Request: " + request +
+ ", response: " + response);
+ }
+
+ WebRequest webRequest = (WebRequest)request;
+ WebResponse webResponse = (WebResponse)response;
+
+ long length = resourceStream.length().bytes();
+
+ ResourceResponse resourceResponse = new ResourceResponse();
+ resourceResponse.setContentType(resourceStream.getContentType());
+ resourceResponse.setFileName(MediaStreamingResourceReference.this.getName());
+ resourceResponse.setContentDisposition(ContentDisposition.ATTACHMENT);
+ resourceResponse.setLastModified(resourceStream.lastModifiedTime());
+
+ // accept ranges, so that the player can
+ // load and play content from a specific byte position
+ webResponse.setHeader("Accept-Range", "bytes");
+
+ Long startbyte = null;
+ Long endbyte = null;
+
+ // Calculating the response code and the byte range to be played
+ String rangeHeader = webRequest.getHeader("range");
+ if (Strings.isEmpty(rangeHeader))
+ {
+ resourceResponse.setStatusCode(200);
+ resourceResponse.setContentLength(length);
+ }
+ else
+ {
+ rangeHeader = rangeHeader.replaceAll(" ", "");
+ // 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 = Strings.split(range, '-');
+
+ String startByteString = rangeParts[0];
+ String endByteString = rangeParts[1];
+
+ startbyte = startByteString != null && !startByteString.trim().equals("")
+ ? Long.parseLong(startByteString) : 0;
+ endbyte = endByteString != null && !endByteString.trim().equals("")
+ ? Long.parseLong(endByteString) : length - 1;
+
+ webResponse.setHeader("Content-Range", "bytes " + startbyte + '-' +
+ endbyte + '/' + length);
+ resourceResponse.setContentLength((endbyte - startbyte) + 1);
+ }
+
+ // Apply the writer callback to send the requested part to the client
+ resourceResponse.setWriteCallback(new PartWriterCallback(resourceStream,
+ startbyte, endbyte));
+
+ return resourceResponse;
+ }
+ catch (Exception e)
+ {
+ throw new WicketRuntimeException(
+ "A problem occurred while creating the video response.", e);
+ }
+ finally
+ {
+ try
+ {
+ resourceStream.close();
+ }
+ catch (IOException e)
+ {
+ throw new WicketRuntimeException(
+ "A problem occurred while closing the video response stream.", e);
+ }
+ }
+ }
+ };
+
+ }
+
+ /**
+ * Returns the mime type of the media this resource reference belongs to
+ *
+ * @return the mime type of this media
+ */
+ public String getType()
+ {
+ final String resourceName = MediaStreamingResourceReference.this.getName();
+ return Application.get().getMimeType(resourceName);
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/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..da8abda
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/media/PartWriterCallback.java
@@ -0,0 +1,185 @@
+/*
+ * 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.protocol.http.servlet.ResponseIOException;
+import org.apache.wicket.request.resource.AbstractResource.WriteCallback;
+import org.apache.wicket.request.resource.IResource.Attributes;
+import org.apache.wicket.util.io.Streams;
+import org.apache.wicket.util.resource.IResourceStream;
+
+/**
+ * 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 final IResourceStream resourceStream;
+
+ private final Long startbyte;
+
+ private Long endbyte;
+
+ private int bufferSize;
+
+ /**
+ * Creates a part writer callback.<br>
+ * <br>
+ * Reads a part of the given 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 resourceStream
+ * the resource stream to 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(IResourceStream resourceStream, Long startbyte,
+ Long endbyte)
+ {
+ this.resourceStream = resourceStream;
+ 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 = resourceStream.getInputStream();
+ OutputStream outputStream = attributes.getResponse().getOutputStream();
+ byte[] buffer = new byte[getBufferSize()];
+
+ 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 = resourceStream.length().bytes();
+ }
+
+ long totalBytes = 0;
+ int actualReadBytes;
+
+ while ((actualReadBytes = inputStream.read(buffer)) != -1)
+ {
+ totalBytes = totalBytes + buffer.length;
+ long lowerBuffer = endbyte - totalBytes;
+ if (lowerBuffer <= 0)
+ {
+ buffer = resizeArray(buffer, actualReadBytes);
+ outputStream.write(buffer);
+ break;
+ }
+ else
+ {
+ outputStream.write(buffer);
+ }
+ }
+ }
+ else
+ {
+ Streams.copy(inputStream, outputStream, getBufferSize());
+ }
+ }
+ 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 byte[] resizeArray(byte[] oldArray, int newSize)
+ {
+ int oldSize = oldArray.length;
+ byte[] newArray = new byte[newSize];
+ int minLength = Math.min(oldSize, newSize);
+ if (minLength > 0)
+ {
+ System.arraycopy(oldArray, 0, newArray, 0, minLength);
+ }
+ 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 4096)
+ */
+ public int getBufferSize()
+ {
+ return bufferSize > 0 ? bufferSize : 4096;
+ }
+
+ /**
+ * Sets the buffer size used to send the data to the client
+ *
+ * @param bufferSize
+ * the buffer size used to send the data to the client
+ */
+ public void setBufferSize(int bufferSize)
+ {
+ this.bufferSize = bufferSize;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-core/src/main/java/org/apache/wicket/markup/html/media/Source.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/media/Source.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/media/Source.java
new file mode 100755
index 0000000..76b4002
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/media/Source.java
@@ -0,0 +1,240 @@
+/*
+ * 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 org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+/**
+ * The source of an audio or a video media component
+ *
+ * @author Tobias Soloschenko
+ * @author Andrew Lombardi
+ */
+public class Source extends WebMarkupContainer
+{
+ private static final long serialVersionUID = 1L;
+
+ private boolean displayType;
+
+ private String type;
+
+ private String media;
+
+ private final MediaStreamingResourceReference mediaStreamingResourceReference;
+
+ private final PageParameters pageParameters;
+
+ private final String url;
+
+ public Source(String id)
+ {
+ this(id, null, null, null, null);
+ }
+
+ public Source(String id, IModel<?> model)
+ {
+ this(id, model, null, null, null);
+ }
+
+ public Source(String id, MediaStreamingResourceReference mediaStreamingResourceReference)
+ {
+ this(id, null, null, null, mediaStreamingResourceReference);
+ }
+
+ public Source(String id, IModel<?> model,
+ MediaStreamingResourceReference mediaStreamingResourceReference)
+ {
+ this(id, model, null, null, mediaStreamingResourceReference);
+ }
+
+ public Source(String id, MediaStreamingResourceReference mediaStreamingResourceReference,
+ PageParameters pageParameters)
+ {
+ this(id, null, null, pageParameters, mediaStreamingResourceReference);
+ }
+
+ public Source(String id, IModel<?> model,
+ MediaStreamingResourceReference mediaStreamingResourceReference,
+ PageParameters pageParameters)
+ {
+ this(id, model, null, pageParameters, mediaStreamingResourceReference);
+ }
+
+ public Source(String id, String url)
+ {
+ this(id, null, url, null, null);
+ }
+
+ public Source(String id, IModel<?> model, String url)
+ {
+ this(id, model, url, null, null);
+ }
+
+ private Source(String id, IModel<?> model, String url, PageParameters pageParameters,
+ MediaStreamingResourceReference mediaStreamingResourceReference)
+ {
+ super(id, model);
+ this.url = url;
+ this.pageParameters = pageParameters;
+ this.mediaStreamingResourceReference = mediaStreamingResourceReference;
+ }
+
+ @Override
+ protected void onComponentTag(ComponentTag tag)
+ {
+ checkComponentTag(tag, "source");
+ super.onComponentTag(tag);
+
+ if (mediaStreamingResourceReference != null)
+ {
+ CharSequence url = RequestCycle.get().urlFor(mediaStreamingResourceReference, pageParameters);
+ tag.put("src", url);
+ } else if (url != null)
+ {
+ tag.put("src", url);
+ }
+
+ if (getDisplayType())
+ {
+ if (type != null)
+ {
+ tag.put("type", type);
+ }
+ else if (mediaStreamingResourceReference != null)
+ {
+ tag.put("type", mediaStreamingResourceReference.getType());
+ }
+ }
+
+ String _media = getMedia();
+ if (_media != null)
+ {
+ tag.put("media", _media);
+ }
+
+ }
+
+ /**
+ * If the type is going to be displayed
+ *
+ * @return If the type is going to be displayed
+ */
+ public boolean getDisplayType()
+ {
+ return displayType;
+ }
+
+ /**
+ * Sets if the type is going to be displayed
+ *
+ * @param displayType
+ * if the type is going to be displayed
+ */
+ public void setDisplayType(boolean displayType)
+ {
+ this.displayType = displayType;
+ }
+
+ /**
+ * Gets the type
+ *
+ * @see {@link #setType(String)}
+ *
+ * @return the type of this media element
+ */
+ public String getType()
+ {
+ return type;
+ }
+
+ /**
+ * Sets the type<br>
+ * <br>
+ *
+ * * The following list shows some examples of how to use the codecs= MIME parameter in the type
+ * attribute.<br>
+ * <br>
+ *
+ * H.264 Constrained baseline profile video (main and extended video compatible) level 3 and
+ * Low-Complexity AAC audio in MP4 container<br>
+ * <source src='video.mp4' <b>type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'</b>><br>
+ * H.264 Extended profile video (baseline-compatible) level 3 and Low-Complexity AAC audio in
+ * MP4 container<br>
+ * <source src='video.mp4' <b>type='video/mp4; codecs="avc1.58A01E, mp4a.40.2"'</b>><br>
+ * H.264 Main profile video level 3 and Low-Complexity AAC audio in MP4 container<br>
+ * <source src='video.mp4' <b>type='video/mp4; codecs="avc1.4D401E, mp4a.40.2"'</b>><br>
+ * H.264 'High' profile video (incompatible with main, baseline, or extended profiles) level 3
+ * and Low-Complexity AAC audio in MP4 container<br>
+ * <source src='video.mp4' <b>type='video/mp4; codecs="avc1.64001E, mp4a.40.2"'</b>><br>
+ * MPEG-4 Visual Simple Profile Level 0 video and Low-Complexity AAC audio in MP4 container<br>
+ * <source src='video.mp4' <b>type='video/mp4; codecs="mp4v.20.8, mp4a.40.2"'</b>><br>
+ * MPEG-4 Advanced Simple Profile Level 0 video and Low-Complexity AAC audio in MP4 container<br>
+ * <source src='video.mp4' <b>type='video/mp4; codecs="mp4v.20.240, mp4a.40.2"'</b>><br>
+ * MPEG-4 Visual Simple Profile Level 0 video and AMR audio in 3GPP container<br>
+ * <source src='video.3gp' <b>type='video/3gpp; codecs="mp4v.20.8, samr"'</b>><br>
+ * Theora video and Vorbis audio in Ogg container<br>
+ * <source src='video.ogv' <b>type='video/ogg; codecs="theora, vorbis"'</b>><br>
+ * Theora video and Speex audio in Ogg container<br>
+ * <source src='video.ogv' <b>type='video/ogg; codecs="theora, speex"'</b>><br>
+ * Vorbis audio alone in Ogg container<br>
+ * <source src='audio.ogg' <b>type='audio/ogg; codecs=vorbis'</b>><br>
+ * Speex audio alone in Ogg container<br>
+ * <source src='audio.spx' <b>type='audio/ogg; codecs=speex'</b>><br>
+ * FLAC audio alone in Ogg container<br>
+ * <source src='audio.oga' <b>type='audio/ogg; codecs=flac'</b>><br>
+ * Dirac video and Vorbis audio in Ogg container<br>
+ * <source src='video.ogv' <b>type='video/ogg; codecs="dirac, vorbis"'</b>><br>
+ * Theora video and Vorbis audio in Matroska container<br>
+ * <source src='video.mkv' <b>type='video/x-matroska; codecs="theora, vorbis"'</b>><br>
+ *
+ * @param type
+ * the type of this media element
+ */
+ public void setType(String type)
+ {
+ this.type = type;
+ }
+
+ /**
+ * The media for which the content of this source should be shown
+ *
+ * @See {@link #setMedia(String)}
+ * @return The media for which the content of this source should be shown
+ */
+ public String getMedia()
+ {
+ return media;
+ }
+
+ /**
+ * Sets the media for which the content of this source should be shown<br>
+ * <br>
+ *
+ * <source src="movie.ogg" type="video/ogg" <b>media="screen and (min-width:320px)"><br>
+ *
+ * @param media
+ * the media for which to content of this source should be shown
+ */
+ public void setMedia(String media)
+ {
+ this.media = media;
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-core/src/main/java/org/apache/wicket/markup/html/media/Track.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/media/Track.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/media/Track.java
new file mode 100755
index 0000000..c2554b3
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/media/Track.java
@@ -0,0 +1,274 @@
+/*
+ * 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.util.Locale;
+
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.resource.ResourceReference;
+
+/**
+ * The track tag is used to provide subtitles, captions, descriptions, chapters, metadata to a video
+ * media component
+ *
+ * @author Tobias Soloschenko
+ */
+public class Track extends WebMarkupContainer
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * To be used for the kind attribute
+ */
+ public enum Kind
+ {
+ SUBTITLES("subtitles"), CAPTIONS("captions"), DESCRIPTIONS("descriptions"), CHAPTERS(
+ "chapters"), METADATA("metadata");
+
+ private String realName;
+
+ Kind(String realName)
+ {
+ this.realName = realName;
+ }
+
+ public String getRealName()
+ {
+ return realName;
+ }
+ }
+
+ private Kind kind;
+
+ private String label;
+
+ private boolean defaultTrack;
+
+ private Locale srclang;
+
+ private final ResourceReference resourceReference;
+
+ private final String url;
+
+ private final PageParameters pageParameters;
+
+ public Track(String id)
+ {
+ this(id, null, null, null, null);
+ }
+
+ public Track(String id, IModel<?> model)
+ {
+ this(id, model, null, null, null);
+ }
+
+ public Track(String id, ResourceReference resourceReference)
+ {
+ this(id, null, null, null, resourceReference);
+ }
+
+ public Track(String id, IModel<?> model, ResourceReference resourceReference)
+ {
+ this(id, model, null, null, resourceReference);
+ }
+
+ public Track(String id, ResourceReference resourceReference, PageParameters pageParameters)
+ {
+ this(id, null, null, pageParameters, resourceReference);
+ }
+
+ public Track(String id, IModel<?> model, ResourceReference resourceReference,
+ PageParameters pageParameters)
+ {
+ this(id, model, null, pageParameters, resourceReference);
+ }
+
+ public Track(String id, String url)
+ {
+ this(id, null, url, null, null);
+ }
+
+ public Track(String id, IModel<?> model, String url)
+ {
+ this(id, model, url, null, null);
+ }
+
+ private Track(String id, IModel<?> model, String url, PageParameters pageParameters,
+ ResourceReference resourceReference)
+ {
+ super(id, model);
+ this.url = url;
+ this.pageParameters = pageParameters;
+ this.resourceReference = resourceReference;
+ }
+
+ @Override
+ protected void onComponentTag(ComponentTag tag)
+ {
+ checkComponentTag(tag, "track");
+ super.onComponentTag(tag);
+
+ if (resourceReference != null)
+ {
+ tag.put("src", RequestCycle.get().urlFor(resourceReference, pageParameters));
+ }
+ else if (url != null)
+ {
+ tag.put("src", url);
+ }
+
+ Kind _kind = getKind();
+ if (_kind != null)
+ {
+ tag.put("kind", _kind.getRealName());
+ }
+
+ String _label = getLabel();
+ if (_label != null)
+ {
+ tag.put("label", _label);
+ }
+
+ if (defaultTrack)
+ {
+ tag.put("default", "default");
+ }
+
+ // if the srclang field is set use this, else if the
+ // resource reference provides a locale use the language
+ // of the resource reference
+ Locale _srclang = getSrclang();
+ if (_srclang != null)
+ {
+ tag.put("srclang", _srclang.getLanguage());
+ }
+ else if (resourceReference != null && resourceReference.getLocale() != null)
+ {
+ tag.put("srclang", resourceReference.getLocale().getLanguage());
+ }
+ }
+
+ /**
+ * Gets the kind of the track belongs to the media component
+ *
+ * @see {@link #setKind(Kind)}
+ *
+ * @return the kind
+ */
+ public Kind getKind()
+ {
+ return kind;
+ }
+
+ /**
+ * Sets the kind of the track belongs to the media component<br>
+ * <br>
+ * <b>SUBTITLES</b>: Transcription or translation of the dialogue, suitable for when the sound
+ * is available but not understood (e.g. because the user does not understand the language of
+ * the media resource's soundtrack). Displayed over the video.<br>
+ * <br>
+ * <b>CAPTIONS</b>: Transcription or translation of the dialogue, sound effects, relevant
+ * musical cues, and other relevant audio information, suitable for when the soundtrack is
+ * unavailable (e.g. because it is muted or because the user is deaf). Displayed over the video;
+ * labeled as appropriate for the hard-of-hearing.<br>
+ * <br>
+ * <b>DESCRIPTIONS</b>: Textual descriptions of the video component of the media resource,
+ * intended for audio synthesis when the visual component is unavailable (e.g. because the user
+ * is interacting with the application without a screen while driving, or because the user is
+ * blind). Synthesized as separate audio track.<br>
+ * <br>
+ * <b>CHAPTERS</b>: Chapter titles, intended to be used for navigating the media resource.
+ * Displayed as an interactive list in the user agent's interface.<br>
+ * <br>
+ * <b>METADATA</b>: Tracks intended for use from script. Not displayed by the user agent.<br>
+ * <br>
+ *
+ * @param kind
+ * the kind
+ */
+ public void setKind(Kind kind)
+ {
+ this.kind = kind;
+ }
+
+ /**
+ * The label for this track
+ *
+ * @return the label
+ */
+ public String getLabel()
+ {
+ return label;
+ }
+
+ /**
+ * Sets the label for this track
+ *
+ * @param label
+ * the label to be set
+ */
+ public void setLabel(String label)
+ {
+ this.label = label;
+ }
+
+ /**
+ * If the track is the default track
+ *
+ * @return if the track is the default track
+ */
+ public boolean isDefaultTrack()
+ {
+ return defaultTrack;
+ }
+
+ /**
+ * Sets if this track is the default track
+ *
+ * @param defaultTrack
+ * if the track is the default track
+ */
+ public void setDefaultTrack(Boolean defaultTrack)
+ {
+ this.defaultTrack = defaultTrack;
+ }
+
+ /**
+ * Gets the src lang
+ *
+ * @return the src lang
+ */
+ public Locale getSrclang()
+ {
+ return srclang;
+ }
+
+ /**
+ * Sets the src lang
+ *
+ * @param srclang
+ * the src lang to set
+ */
+ public void setSrclang(Locale srclang)
+ {
+ this.srclang = srclang;
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-core/src/main/java/org/apache/wicket/markup/html/media/audio/Audio.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/media/audio/Audio.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/media/audio/Audio.java
new file mode 100755
index 0000000..e16cb8b
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/media/audio/Audio.java
@@ -0,0 +1,95 @@
+/*
+ * 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.audio;
+
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.media.MediaComponent;
+import org.apache.wicket.markup.html.media.MediaStreamingResourceReference;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+/**
+ * An audio media component to playback audio files.
+ *
+ * @author Tobias Soloschenko
+ * @author Andrew Lombardi
+ */
+public class Audio extends MediaComponent
+{
+ private static final long serialVersionUID = 1L;
+
+ public Audio(String id)
+ {
+ super(id);
+ }
+
+ public Audio(String id, IModel<?> model)
+ {
+ super(id, model);
+ }
+
+ public Audio(String id, MediaStreamingResourceReference mediaStreamingResourceReference)
+ {
+ super(id, mediaStreamingResourceReference);
+ }
+
+ public Audio(String id, IModel<?> model,
+ MediaStreamingResourceReference mediaStreamingResourceReference)
+ {
+ super(id, model, mediaStreamingResourceReference);
+ }
+
+ public Audio(String id, MediaStreamingResourceReference mediaStreamingResourceReference,
+ PageParameters pageParameters)
+ {
+ super(id, mediaStreamingResourceReference, pageParameters);
+ }
+
+ public Audio(String id, IModel<?> model,
+ MediaStreamingResourceReference mediaStreamingResourceReference,
+ PageParameters pageParameters)
+ {
+ super(id, model, mediaStreamingResourceReference, pageParameters);
+ }
+
+ public Audio(String id, String url)
+ {
+ super(id, url);
+ }
+
+ public Audio(String id, IModel<?> model, String url)
+ {
+ super(id, model, url);
+ }
+
+ public Audio(String id, String url, PageParameters pageParameters)
+ {
+ super(id, null, url, pageParameters);
+ }
+
+ public Audio(String id, IModel<?> model, String url, PageParameters pageParameters)
+ {
+ super(id, model, url, pageParameters);
+ }
+
+ @Override
+ protected void onComponentTag(ComponentTag tag)
+ {
+ checkComponentTag(tag, "audio");
+ super.onComponentTag(tag);
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-core/src/main/java/org/apache/wicket/markup/html/media/video/Video.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/media/video/Video.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/media/video/Video.java
new file mode 100755
index 0000000..b73ba3d
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/media/video/Video.java
@@ -0,0 +1,210 @@
+/*
+ * 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.video;
+
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.media.MediaComponent;
+import org.apache.wicket.markup.html.media.MediaStreamingResourceReference;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.resource.ResourceReference;
+
+/**
+ * A video media component to display videos.
+ *
+ * @author Tobias Soloschenko
+ * @author Andrew Lombardi
+ */
+public class Video extends MediaComponent
+{
+ private static final long serialVersionUID = 1L;
+
+ private Integer width;
+
+ private Integer height;
+
+ private ResourceReference poster;
+
+ private PageParameters posterPageParameters;
+
+ public Video(String id)
+ {
+ super(id);
+ }
+
+ public Video(String id, IModel<?> model)
+ {
+ super(id, model);
+ }
+
+ public Video(String id, MediaStreamingResourceReference mediaStreamingResourceReference)
+ {
+ super(id, mediaStreamingResourceReference);
+ }
+
+ public Video(String id, IModel<?> model,
+ MediaStreamingResourceReference mediaStreamingResourceReference)
+ {
+ super(id, model, mediaStreamingResourceReference);
+ }
+
+ public Video(String id, MediaStreamingResourceReference mediaStreamingResourceReference,
+ PageParameters pageParameters)
+ {
+ super(id, mediaStreamingResourceReference, pageParameters);
+ }
+
+ public Video(String id, IModel<?> model,
+ MediaStreamingResourceReference mediaStreamingResourceReference,
+ PageParameters pageParameters)
+ {
+ super(id, model, mediaStreamingResourceReference, pageParameters);
+ }
+
+ public Video(String id, String url)
+ {
+ super(id, url);
+ }
+
+ public Video(String id, IModel<?> model, String url)
+ {
+ super(id, model, url);
+ }
+
+ public Video(String id, String url, PageParameters pageParameters)
+ {
+ super(id, null, url, pageParameters);
+ }
+
+ public Video(String id, IModel<?> model, String url, PageParameters pageParameters)
+ {
+ super(id, model, url, pageParameters);
+ }
+
+ @Override
+ protected void onComponentTag(ComponentTag tag)
+ {
+ checkComponentTag(tag, "video");
+ super.onComponentTag(tag);
+
+ Integer _width = getWidth();
+ if (_width != null)
+ {
+ tag.put("width", _width);
+ }
+
+ Integer _height = getHeight();
+ if (_height != null)
+ {
+ tag.put("height", _height);
+ }
+
+ ResourceReference _poster = getPoster();
+ if (_poster != null)
+ {
+ tag.put("poster", RequestCycle.get().urlFor(_poster, getPosterPageParameters()));
+ }
+ }
+
+ /**
+ * The image to be displayed if the video isn't available
+ *
+ * @return the resource reference of the image
+ */
+ public ResourceReference getPoster()
+ {
+ return poster;
+ }
+
+ /**
+ * Gets the posters page parameters
+ *
+ * @return the page parameters for the poster
+ */
+ public PageParameters getPosterPageParameters()
+ {
+ return posterPageParameters;
+ }
+
+ /**
+ * Sets the image to be displayed if the video isn't available
+ *
+ * @param poster
+ * the resource reference of the image used if the video isn't available
+ */
+ public void setPoster(ResourceReference poster)
+ {
+ this.poster = poster;
+ }
+
+ /**
+ * Sets the image to be displayed if the video isn't available
+ *
+ * @param poster
+ * the resource reference of the image used if the video isn't available
+ * @param posterPageParameters
+ * the page parameters for the poster
+ */
+ public void setPoster(ResourceReference poster, PageParameters posterPageParameters)
+ {
+ this.poster = poster;
+ this.posterPageParameters = posterPageParameters;
+ }
+
+ /**
+ * Gets the width of the video area
+ *
+ * @return the width of the video area
+ */
+ public Integer getWidth()
+ {
+ return width;
+ }
+
+ /**
+ * Sets the width of the video area
+ *
+ * @param width
+ * the width of the video area
+ */
+ public void setWidth(Integer width)
+ {
+ this.width = width;
+ }
+
+ /**
+ * Gets the height of the video area
+ *
+ * @return the height of the video area
+ */
+ public Integer getHeight()
+ {
+ return height;
+ }
+
+ /**
+ * Sets the height of the video area
+ *
+ * @param height
+ * the height of the video area
+ */
+ public void setHeight(Integer height)
+ {
+ this.height = height;
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaComponentsApplication.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaComponentsApplication.java b/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaComponentsApplication.java
new file mode 100755
index 0000000..899f553
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaComponentsApplication.java
@@ -0,0 +1,52 @@
+/*
+ * 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 org.apache.wicket.Page;
+import org.apache.wicket.markup.html.IPackageResourceGuard;
+import org.apache.wicket.markup.html.SecurePackageResourceGuard;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.request.resource.caching.NoOpResourceCachingStrategy;
+
+public class MediaComponentsApplication extends WebApplication
+{
+ @Override
+ public Class<? extends Page> getHomePage()
+ {
+ return MediaTagsTestPage.class;
+ }
+
+ @Override
+ protected void init()
+ {
+ super.init();
+
+ getResourceSettings().setCachingStrategy(NoOpResourceCachingStrategy.INSTANCE);
+
+ IPackageResourceGuard packageResourceGuard = org.apache.wicket.Application.get()
+ .getResourceSettings()
+ .getPackageResourceGuard();
+ if (packageResourceGuard instanceof SecurePackageResourceGuard)
+ {
+ SecurePackageResourceGuard securePackageResourceGuard = (SecurePackageResourceGuard)packageResourceGuard;
+ securePackageResourceGuard.addPattern("+*.vtt");
+ securePackageResourceGuard.addPattern("+*.srt");
+ securePackageResourceGuard.addPattern("+*.mp3");
+ securePackageResourceGuard.addPattern("+*.m4a");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsExtendedTestPage.html
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsExtendedTestPage.html b/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsExtendedTestPage.html
new file mode 100755
index 0000000..1f7d793
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsExtendedTestPage.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>de.test.mediatags</title>
+ </head>
+ <body>
+ <video wicket:id="video">
+ <source wicket:id="source" />
+ <track wicket:id="track" />
+ </video>
+ </body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsExtendedTestPage.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsExtendedTestPage.java b/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsExtendedTestPage.java
new file mode 100644
index 0000000..b191c35
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsExtendedTestPage.java
@@ -0,0 +1,53 @@
+/*
+ * 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.util.Locale;
+
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.media.Track.Kind;
+import org.apache.wicket.markup.html.media.video.Video;
+import org.apache.wicket.request.resource.PackageResourceReference;
+
+public class MediaTagsExtendedTestPage extends WebPage
+{
+ private static final long serialVersionUID = 1L;
+
+ public MediaTagsExtendedTestPage()
+ {
+ Video video = new Video("video", new MediaStreamingResourceReference(
+ MediaTagsTestPage.class, "dummyVideo.m4a"));
+
+ // source tag
+ Source source = new Source("source","http://www.mytestpage.xc/video.m4a");
+ source.setMedia("screen and (device-width:500px)");
+ source.setType("video/mp4");
+ source.setDisplayType(true);
+ video.add(source);
+
+ // tack tag
+ Track track = new Track("track", new PackageResourceReference(MediaTagsTestPage.class,"dummySubtitles.vtt"));
+ track.setKind(Kind.SUBTITLES);
+ track.setLabel("Subtitles of video");
+ track.setSrclang(Locale.GERMANY);
+ track.setDefaultTrack(true);
+ video.add(track);
+
+ add(video);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsTest.java b/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsTest.java
new file mode 100644
index 0000000..6698d79
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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 org.apache.wicket.WicketTestCase;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.util.tester.TagTester;
+import org.junit.Test;
+
+public class MediaTagsTest extends WicketTestCase
+{
+ @Override
+ protected WebApplication newApplication()
+ {
+ return new MediaComponentsApplication();
+ }
+
+ @Test
+ public void audioTagIsRenderedRight()
+ {
+ tester.startPage(MediaTagsTestPage.class);
+ String lastResponseAsString = tester.getLastResponse().getDocument();
+ TagTester createTagByAttribute = TagTester.createTagByAttribute(lastResponseAsString,
+ "audio");
+ assertTrue(createTagByAttribute.hasAttribute("autoplay"));
+ assertTrue(createTagByAttribute.hasAttribute("controls"));
+ assertTrue(createTagByAttribute.hasAttribute("loop"));
+ assertTrue(createTagByAttribute.hasAttribute("muted"));
+ assertEquals("user-credentials", createTagByAttribute.getAttribute("crossorigin"));
+ String attribute = createTagByAttribute.getAttribute("src");
+ assertTrue("The time period is set right in the src attribute",
+ attribute.contains("#t=5,10"));
+ assertTrue("page parameter is in the url of the src attribute",
+ attribute.contains("test=test"));
+ }
+
+ @Test
+ public void videoTagIsRenderedRight()
+ {
+ tester.startPage(MediaTagsTestPage.class);
+ String lastResponseAsString = tester.getLastResponse().getDocument();
+ TagTester createTagByAttribute = TagTester.createTagByAttribute(lastResponseAsString,
+ "video");
+ String attribute = createTagByAttribute.getAttribute("poster");
+ assertTrue("page parameter is in the url of the poster",
+ attribute.contains("test2=test2"));
+ String attributesrc = createTagByAttribute.getAttribute("src");
+ assertTrue("video url is in the src attribute",
+ attributesrc.contains("dummyVideo.m4a"));
+ assertEquals("500", createTagByAttribute.getAttribute("width"));
+ assertEquals("400", createTagByAttribute.getAttribute("height"));
+ }
+
+ @Test
+ public void extendedVideoTagIsRenderedRight()
+ {
+ tester.startPage(MediaTagsExtendedTestPage.class);
+ String lastResponseAsString = tester.getLastResponse().getDocument();
+ TagTester createTagByAttribute = TagTester.createTagByAttribute(lastResponseAsString,
+ "video");
+ assertTrue(createTagByAttribute.hasChildTag("source"));
+ assertTrue(createTagByAttribute.hasChildTag("track"));
+
+
+ TagTester sourceTag = TagTester.createTagByAttribute(lastResponseAsString, "source");
+ assertEquals("video/mp4", sourceTag.getAttribute("type"));
+ assertEquals("screen and (device-width:500px)", sourceTag.getAttribute("media"));
+ assertEquals("http://www.mytestpage.xc/video.m4a", sourceTag.getAttribute("src"));
+
+ TagTester trackTag = TagTester.createTagByAttribute(lastResponseAsString, "track");
+
+ assertTrue(trackTag.getAttribute("src").contains("dummySubtitles"));
+ assertEquals("subtitles", trackTag.getAttribute("kind"));
+ assertEquals("Subtitles of video", trackTag.getAttribute("label"));
+ assertEquals("default", trackTag.getAttribute("default"));
+ assertEquals("de", trackTag.getAttribute("srclang"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsTestPage.html
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsTestPage.html b/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsTestPage.html
new file mode 100755
index 0000000..e68360d
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsTestPage.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>de.test.mediatags</title>
+ </head>
+ <body>
+ <audio wicket:id="audio" />
+ <video wicket:id="video"/>
+ </body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsTestPage.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsTestPage.java b/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsTestPage.java
new file mode 100644
index 0000000..e8dbdd8
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/media/MediaTagsTestPage.java
@@ -0,0 +1,56 @@
+/*
+ * 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 org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.media.MediaComponent.Cors;
+import org.apache.wicket.markup.html.media.audio.Audio;
+import org.apache.wicket.markup.html.media.video.Video;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.resource.PackageResourceReference;
+
+public class MediaTagsTestPage extends WebPage
+{
+ private static final long serialVersionUID = 1L;
+
+ public MediaTagsTestPage()
+ {
+ PageParameters pageParameters = new PageParameters();
+ pageParameters.set("test", "test");
+ Audio audio = new Audio("audio", new MediaStreamingResourceReference(
+ MediaTagsTestPage.class, "dummyAudio.mp3"), pageParameters);
+ audio.setAutoplay(true);
+ audio.setControls(true);
+ audio.setCrossOrigin(Cors.USER_CREDENTIALS);
+ audio.setLooping(true);
+ audio.setMuted(true);
+ audio.setStartTime("5");
+ audio.setEndTime("10");
+ add(audio);
+
+ Video video = new Video("video", new MediaStreamingResourceReference(
+ MediaTagsTestPage.class, "dummyVideo.m4a"));
+ PageParameters pageParameters2 = new PageParameters();
+ pageParameters2.add("test2", "test2");
+ video.setPoster(new PackageResourceReference(MediaTagsTestPage.class, "dummyPoster.jpg"),
+ pageParameters2);
+ video.setWidth(500);
+ video.setHeight(400);
+ add(video);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-core/src/test/java/org/apache/wicket/markup/html/media/dummyAudio.mp3
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/media/dummyAudio.mp3 b/wicket-core/src/test/java/org/apache/wicket/markup/html/media/dummyAudio.mp3
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-core/src/test/java/org/apache/wicket/markup/html/media/dummyPoster.jpg
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/media/dummyPoster.jpg b/wicket-core/src/test/java/org/apache/wicket/markup/html/media/dummyPoster.jpg
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-core/src/test/java/org/apache/wicket/markup/html/media/dummySubtitles.vtt
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/media/dummySubtitles.vtt b/wicket-core/src/test/java/org/apache/wicket/markup/html/media/dummySubtitles.vtt
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-core/src/test/java/org/apache/wicket/markup/html/media/dummyVideo.m4a
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/media/dummyVideo.m4a b/wicket-core/src/test/java/org/apache/wicket/markup/html/media/dummyVideo.m4a
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-examples/pom.xml
----------------------------------------------------------------------
diff --git a/wicket-examples/pom.xml b/wicket-examples/pom.xml
index d03ffad..c184b27 100644
--- a/wicket-examples/pom.xml
+++ b/wicket-examples/pom.xml
@@ -204,6 +204,7 @@
<include>**/*.txt</include>
<include>**/*.xml</include>
<include>**/*.properties</include>
+ <include>**/*.mp4</include>
</includes>
</resource>
<resource>
@@ -221,6 +222,7 @@
<include>**/*.properties</include>
<include>**/*.vm</include>
<include>**/*.tmpl</include>
+ <include>**/*.mp4</include>
</includes>
</resource>
</resources>
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-examples/src/main/java/org/apache/wicket/examples/media/Home.css
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/media/Home.css b/wicket-examples/src/main/java/org/apache/wicket/examples/media/Home.css
new file mode 100644
index 0000000..45dee80
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/media/Home.css
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+video{
+ float:left;
+ height:240px;
+ width:320px;
+ margin-bottom:10px;
+ margin-right:10px;
+}
+.videoDescription{
+ float:left;
+ height:240px;
+ width:300px;
+ margin-bottom:10px;
+}
+.clearer{
+ clear:both;
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-examples/src/main/java/org/apache/wicket/examples/media/Home.html
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/media/Home.html b/wicket-examples/src/main/java/org/apache/wicket/examples/media/Home.html
new file mode 100644
index 0000000..be0b1ce
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/media/Home.html
@@ -0,0 +1,29 @@
+<html xmlns:wicket="http://wicket.apache.org">
+<head>
+ <title>Wicket Examples - videos</title>
+ <link rel="stylesheet" type="text/css" href="style.css"/>
+</head>
+<body>
+ <div wicket:id="mainNavigation"></div>
+ <h2>Below there are three types of videos to show the basic functionality of Wicket's media implementation</h2>
+ <h3>The implementation features full support of video / audio / source / track tags.</h3>
+ <div>
+ <!-- Video 1 -->
+ <video wicket:id="video1" ></video>
+ <div class="videoDescription"><b>Video1</b><br/>Demonstrate the basic set of methods to configure a video (setAutoplay(false); setControls(true); setLooping(false); setWidth(320); setHeight(240);) The width and height are null by default which means that the video is going to be rendered in size of the media file.</div>
+ <div class="clearer"></div>
+
+ <!-- Video 2 -->
+ <video wicket:id="video2" >
+ <source wicket:id="source2" />
+ </video>
+ <div class="videoDescription"><b>Video2</b><br/>This video is rendered with a source tag. You can add many source tags and apply a media query (setMedia(query);) so that based on the resolution different videos are going to be displayed.</div>
+ <div class="clearer"></div>
+
+ <!-- Video 3 -->
+ <video wicket:id="video3" ></video>
+ <div class="videoDescription"><b>Video3</b><br/>The last sample shows a remote video located here: http://media.w3.org/2010/05/video/movie_300.mp4. It can be added by set the url as String instead of adding a ResourceReference.</div>
+ <div class="clearer"></div>
+ </div>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-examples/src/main/java/org/apache/wicket/examples/media/Home.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/media/Home.java b/wicket-examples/src/main/java/org/apache/wicket/examples/media/Home.java
new file mode 100644
index 0000000..87d70f5
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/media/Home.java
@@ -0,0 +1,116 @@
+/*
+ * 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.examples.media;
+
+import java.util.UUID;
+
+import org.apache.wicket.examples.WicketExamplePage;
+import org.apache.wicket.markup.head.CssHeaderItem;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.html.media.MediaStreamingResourceReference;
+import org.apache.wicket.markup.html.media.Source;
+import org.apache.wicket.markup.html.media.video.Video;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.resource.PackageResourceReference;
+
+
+/**
+ * Demonstrates different flavors of org.apache.wicket.examples.videos.<br>
+ * <br>
+ *
+ * Videos are from: http://media.w3.org/2010/05/video/<br>
+ * <br>
+ * Images are from: http://search.creativecommons.org/ with check on commercial use and modify...
+ *
+ * @author Tobias Soloschenko
+ */
+public final class Home extends WicketExamplePage
+{
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor
+ */
+ public Home()
+ {
+ // Internal video with several options
+
+ Video video1 = new Video("video1", new MediaStreamingResourceReference(Home.class,
+ "video.mp4"));
+ video1.setAutoplay(false);
+ video1.setControls(true);
+ video1.setLooping(false);
+ video1.setWidth(320);
+ video1.setHeight(240);
+ video1.setPoster(new PackageResourceReference(Home.class, "novideo.gif"));
+ add(video1);
+
+ // video with source
+
+ Video video2 = new Video("video2");
+ video2.setPoster(new PackageResourceReference(Home.class, "novideo.gif"));
+
+ Source source2 = new Source("source2", new MediaStreamingResourceReference(Home.class,
+ "video.mp4"));
+ // Need to be set to true to show the type
+ source2.setDisplayType(true);
+ // the default type is the mime type of the image with no codec information
+ source2.setType("video/mp4; codecs=\"avc1.42E01E, mp4a.40.2\"");
+ video2.add(source2);
+
+ add(video2);
+
+ // External video
+ PageParameters pageParameters = new PageParameters();
+ pageParameters.add("random", UUID.randomUUID().toString());
+ pageParameters.add("test", "test");
+ Video video3 = new Video("video3", "http://media.w3.org/2010/05/video/movie_300.mp4",
+ pageParameters);
+ video3.setPoster(new PackageResourceReference(Home.class, "novideo.gif"));
+ add(video3);
+
+ /*
+ * // video with track
+ * Video video4 = new Video("video4", new MediaStreamingResourceReference(Home.class, "dummyVideo.m4a"));
+ *
+ * // source tag
+ * Source source4 = new Source("source4", "http://www.mytestpage.xc/video.m4a");
+ * source4.setMedia("screen and (device-width:500px)");
+ * source4.setType("video/mp4");
+ * source4.setDisplayType(true); video4.add(source4);
+ *
+ * // tack tag
+ * Track track4 = new Track("track4", new PackageResourceReference(Home.class, "dummySubtitles.vtt"));
+ * track4.setKind(Kind.subtitles);
+ * track4.setLabel("Subtitles of video");
+ * track4.setSrclang(Locale.GERMANY);
+ * track4.setDefaultTrack(true);
+ * video4.add(track4);
+ *
+ * add(video4);
+ */
+ }
+
+ @Override
+ public void renderHead(IHeaderResponse response)
+ {
+ super.renderHead(response);
+ response.render(CssHeaderItem.forReference(new PackageResourceReference(Home.class,
+ "Home.css")));
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-examples/src/main/java/org/apache/wicket/examples/media/VideosApplication.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/media/VideosApplication.java b/wicket-examples/src/main/java/org/apache/wicket/examples/media/VideosApplication.java
new file mode 100644
index 0000000..2e59703
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/media/VideosApplication.java
@@ -0,0 +1,63 @@
+/*
+ * 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.examples.media;
+
+import org.apache.wicket.Page;
+import org.apache.wicket.examples.WicketExampleApplication;
+import org.apache.wicket.markup.html.IPackageResourceGuard;
+import org.apache.wicket.markup.html.SecurePackageResourceGuard;
+
+
+/**
+ * Application class for the videos examples.
+ *
+ * @author Tobias Soloschenko
+ */
+public class VideosApplication extends WicketExampleApplication
+{
+ /**
+ * Constructor
+ */
+ public VideosApplication()
+ {
+
+ }
+
+ /**
+ * @see org.apache.wicket.Application#getHomePage()
+ */
+ @Override
+ public Class<? extends Page> getHomePage()
+ {
+ return Home.class;
+ }
+
+ /**
+ * @see org.apache.wicket.examples.WicketExampleApplication#init()
+ */
+ @Override
+ protected void init()
+ {
+ IPackageResourceGuard packageResourceGuard = getResourceSettings().getPackageResourceGuard();
+ if (packageResourceGuard instanceof SecurePackageResourceGuard)
+ {
+ SecurePackageResourceGuard guard = (SecurePackageResourceGuard)packageResourceGuard;
+ guard.addPattern("+*.mp4");
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-examples/src/main/java/org/apache/wicket/examples/media/novideo.gif
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/media/novideo.gif b/wicket-examples/src/main/java/org/apache/wicket/examples/media/novideo.gif
new file mode 100644
index 0000000..98cc51a
Binary files /dev/null and b/wicket-examples/src/main/java/org/apache/wicket/examples/media/novideo.gif differ
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-examples/src/main/java/org/apache/wicket/examples/media/video.mp4
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/media/video.mp4 b/wicket-examples/src/main/java/org/apache/wicket/examples/media/video.mp4
new file mode 100644
index 0000000..cf59777
Binary files /dev/null and b/wicket-examples/src/main/java/org/apache/wicket/examples/media/video.mp4 differ
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html b/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html
index 4789751..d83ae2c 100644
--- a/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html
+++ b/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html
@@ -66,6 +66,7 @@
<tr><td align="right"><a href="atmosphere">Atmosphere</a></td><td> - Atmosphere Framework integration</td></tr>
<tr><td align="right"><a href="cdi">CDI</a></td><td> - Context Dependency and Injection integration</td></tr>
<tr><td align="right"><a href="bean-validation">Bean Validation</a></td><td> - Bean Validation integration (JSR 303)</td></tr>
+ <tr><td align="right"><a href="videos">HTML5 Media Tags</a></td><td> - Integration for HTML5 Media Tags</td></tr>
</tbody>
</table>
</div>
http://git-wip-us.apache.org/repos/asf/wicket/blob/499f11fd/wicket-examples/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/webapp/WEB-INF/web.xml b/wicket-examples/src/main/webapp/WEB-INF/web.xml
index 92f956a..ec23694 100644
--- a/wicket-examples/src/main/webapp/WEB-INF/web.xml
+++ b/wicket-examples/src/main/webapp/WEB-INF/web.xml
@@ -16,9 +16,9 @@
limitations under the License.
-->
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- version="2.5">
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
<display-name>Wicket Examples</display-name>
@@ -162,6 +162,15 @@
</filter>
<filter>
+ <filter-name>VideosApplication</filter-name>
+ <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
+ <init-param>
+ <param-name>applicationClassName</param-name>
+ <param-value>org.apache.wicket.examples.media.VideosApplication</param-value>
+ </init-param>
+ </filter>
+
+ <filter>
<filter-name>LibraryApplication</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
@@ -544,6 +553,13 @@
</filter-mapping>
<filter-mapping>
+ <filter-name>VideosApplication</filter-name>
+ <url-pattern>/videos/*</url-pattern>
+ <dispatcher>REQUEST</dispatcher>
+ <dispatcher>INCLUDE</dispatcher>
+ </filter-mapping>
+
+ <filter-mapping>
<filter-name>HelloWorldApplication</filter-name>
<url-pattern>/helloworld/*</url-pattern>
<dispatcher>REQUEST</dispatcher>