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/95e9eaa2 Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/95e9eaa2 Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/95e9eaa2 Branch: refs/heads/pr-86-media_tags Commit: 95e9eaa23b97b4b29d3cd80217126cfe3b4da67e Parents: 478f1be Author: Andrea Del Bene <[email protected]> Authored: Fri Mar 13 21:40:20 2015 +0100 Committer: Andrea Del Bene <[email protected]> Committed: Fri Mar 13 21:40:20 2015 +0100 ---------------------------------------------------------------------- .../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/95e9eaa2/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:[email protected]">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/95e9eaa2/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..d8f6d49 --- /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/95e9eaa2/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..03903df --- /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/95e9eaa2/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..cb6dd64 --- /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/95e9eaa2/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..c3fc50f --- /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/95e9eaa2/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..cef3914 --- /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/95e9eaa2/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..c29d98c --- /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/95e9eaa2/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..a608a4b --- /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/95e9eaa2/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..0fb54c6 --- /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/95e9eaa2/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/95e9eaa2/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..d530894 --- /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/95e9eaa2/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..7c50031 --- /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/95e9eaa2/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/95e9eaa2/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/95e9eaa2/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/95e9eaa2/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/95e9eaa2/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/95e9eaa2/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/95e9eaa2/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/95e9eaa2/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/95e9eaa2/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..7388a03 --- /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/95e9eaa2/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..03b1e8f --- /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/95e9eaa2/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..c17a393 --- /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/95e9eaa2/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/95e9eaa2/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/95e9eaa2/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/95e9eaa2/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..6b91161 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> @@ -160,6 +160,15 @@ <param-value>org.apache.wicket.examples.images.ImagesApplication</param-value> </init-param> </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> @@ -542,6 +551,13 @@ <dispatcher>REQUEST</dispatcher> <dispatcher>INCLUDE</dispatcher> </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>
