Java tutorial
/** * * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * **/ package lucee.runtime.tag; import java.awt.Color; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import lucee.commons.color.ColorCaster; import lucee.commons.io.res.Resource; import lucee.commons.io.res.type.file.FileResource; import lucee.commons.lang.StringUtil; import lucee.runtime.PageContext; import lucee.runtime.PageSource; import lucee.runtime.exp.ApplicationException; import lucee.runtime.exp.ExpressionException; import lucee.runtime.exp.PageException; import lucee.runtime.ext.tag.BodyTagSupport; import lucee.runtime.functions.string.JSStringFormat; import lucee.runtime.op.Caster; import lucee.runtime.op.Decision; import lucee.runtime.type.Collection.Key; import lucee.runtime.type.Struct; import lucee.runtime.video.VideoInput; import lucee.runtime.video.VideoInputImpl; import lucee.runtime.video.VideoUtilImpl; import org.apache.commons.collections.map.ReferenceMap; /** * implementation of the tag Compiler */ public class VideoPlayerJW extends BodyTagSupport { private static final int TYPE_NONE = 0; private static final int TYPE_PLAYLIST = 1; private static final int TYPE_CHAPTERS = 2; private static final int PLAYLIST_NONE = 0; private static final int PLAYLIST_RIGHT = 1; private static final int PLAYLIST_BOTTOM = 2; private static Color BG_COLOR = new Color(51, 51, 51); private static Color FG_COLOR = new Color(198, 198, 198); private String video = null; private boolean autostart = false; private lucee.runtime.video.Range showPlay = lucee.runtime.video.Range.TRUE; private lucee.runtime.video.Range showPause = lucee.runtime.video.Range.TRUE; private lucee.runtime.video.Range showTimeline = lucee.runtime.video.Range.TRUE; private List params = new ArrayList(); private java.awt.Color bgcolor = BG_COLOR; private java.awt.Color fgcolor = FG_COLOR; private java.awt.Color screencolor = null; private java.awt.Color lightcolor = null; private int width = -1; private int height = -1; private boolean debug; private boolean allowfullscreen; private String strWidth; private String strHeight; private static Map sizes = new ReferenceMap(ReferenceMap.SOFT, ReferenceMap.SOFT); // JW private Struct passthrough = null; private String preview; private boolean group = false; private boolean playlistThumbnails = true; private int playlistSize = -1; private int playlist = PLAYLIST_NONE; private String target = "_self"; private boolean linkfromdisplay; private String overstretch; private boolean download; private String id; private String align; private static int _id = 0; public VideoPlayerJW() { } @Override public void release() { super.release(); video = null; autostart = false; showPlay = lucee.runtime.video.Range.TRUE; showPause = lucee.runtime.video.Range.TRUE; showTimeline = lucee.runtime.video.Range.TRUE; params.clear(); debug = false; id = null; group = false; playlist = PLAYLIST_NONE; playlistSize = -1; playlistThumbnails = true; target = "_self"; linkfromdisplay = false; overstretch = null; /*group="yes" playlist="right,bottom,none" playlistSize="300" playlistThumbnails="300" */ align = null; bgcolor = BG_COLOR; fgcolor = FG_COLOR; screencolor = null; lightcolor = null; width = -1; height = -1; strWidth = null; strHeight = null; // JW passthrough = null; preview = null; allowfullscreen = false; download = false; } protected void setParam(VideoPlayerParamBean param) { params.add(param); } /** * @param video the video to set */ public void setVideo(String video) { this.video = video; } /** * @param autostart the autostart to set */ public void setAutostart(boolean autostart) { this.autostart = autostart; } /** * @param showPlay the showPlay to set * @throws PageException */ public void setShowplay(String showPlay) throws PageException { this.showPlay = lucee.runtime.video.Range.toRange(showPlay); } public void setId(String id) throws PageException { this.id = Caster.toVariableName(id); } /** * @param showPause the showPause to set * @throws PageException */ public void setShowpause(String showPause) throws PageException { this.showPause = lucee.runtime.video.Range.toRange(showPause); } /** * @param showTimeline the showTimeline to set * @throws PageException */ public void setShowtimeline(String showTimeline) throws PageException { this.showTimeline = lucee.runtime.video.Range.toRange(showTimeline); } /** * @param color the background color to set * @throws PageException */ public void setBgcolor(String color) throws PageException { this.bgcolor = ColorCaster.toColor(color); } public void setBackgroundcolor(String color) throws PageException { setBgcolor(color); } public void setBackground(String color) throws PageException { setBgcolor(color); } public void setScreencolor(String color) throws PageException { this.screencolor = ColorCaster.toColor(color); } public void setLightcolor(String color) throws PageException { this.lightcolor = ColorCaster.toColor(color); } /** * @param color the background color to set * @throws PageException */ public void setFgcolor(String color) throws PageException { this.fgcolor = ColorCaster.toColor(color); } public void setForeground(String color) throws PageException { setFgcolor(color); } public void setForegroundcolor(String color) throws PageException { setFgcolor(color); } /** * @param width the width to set */ public void setWidth(String strWidth) { this.strWidth = strWidth; this.width = Caster.toIntValue(strWidth, -1); } /** * @param height the height to set */ public void setHeight(String strHeight) { this.strHeight = strHeight; this.height = Caster.toIntValue(strHeight, -1); } @Override public int doStartTag() throws PageException { return EVAL_BODY_INCLUDE; } public int doEndTag() throws PageException { // fill top video to params if (video != null) { VideoPlayerParamBean vppb = new VideoPlayerParamBean(); vppb.setVideo(pageContext, video); if (!StringUtil.isEmpty(preview)) vppb.setImage(pageContext, preview); params.add(vppb); } else { if (!StringUtil.isEmpty(preview)) throw new ApplicationException( "attribute [preview] is only allowed when attribute [video] is used"); } if (params.size() == 0) throw new ApplicationException("you have to define at least one video source"); // calculate dimension int[] dim = calculateDimension(pageContext, params, width, strWidth, height, strHeight); //print.out(width+":"+height); //print.out(strWidth+":"+strHeight); width = dim[0]; height = dim[1]; //print.out(width+":"+height); // playlist int dspHeight = -1, dspWidth = -1; if (playlist != PLAYLIST_NONE) { if (playlistSize < 20) playlistSize = playlist == PLAYLIST_BOTTOM ? 100 : 200; if (playlist == PLAYLIST_BOTTOM) { dspHeight = height; height += playlistSize; } else { dspWidth = width; width += playlistSize; } } else playlistThumbnails = false; VideoPlayerParamBean param; String id = getId();// String placeholderId = "ph_" + id; String flashId = "swf_" + id; StringBuffer sb = new StringBuffer(); write(sb, "<script type=\"text/javascript\" src=\"/lucee/swfobject.js.cfm\"></script>"); write(sb, "<div "); if (passthrough != null) { Iterator<Entry<Key, Object>> it = passthrough.entryIterator(); Entry<Key, Object> e; String key; while (it.hasNext()) { e = it.next(); key = e.getKey().getString(); if (StringUtil.startsWithIgnoreCase(key, "div.")) write(sb, key.substring(4) + "=\"" + Caster.toString(e.getValue()) + "\" "); } } write(sb, (align != null ? "align=\"" + align + "\"" : "") + " id=\"" + placeholderId + "\"><a href=\"http://www.macromedia.com/go/getflashplayer\">Get the Flash Player</a> to see this player.</a></div>"); write(sb, "<script type=\"text/javascript\">\n"); write(sb, "var so = new SWFObject(\"/lucee/mediaplayer.swf.cfm\", \"" + flashId + "\", \"" + width + "\", \"" + (height) + "\", \"8\", \"" + format("#", bgcolor) + "\");\n"); // script addParam(sb, "allowscriptaccess", "always"); addVariable(sb, "enablejs", "true"); addVariable(sb, "javascriptid", flashId); addVariable(sb, "shuffle", "false"); addVariable(sb, "linktarget", target); addVariable(sb, "linkfromdisplay", Caster.toString(linkfromdisplay)); addVariable(sb, "abouttxt", "Lucee Video Player"); addVariable(sb, "aboutlnk", "http://www.lucee.org"); // control addParam(sb, "allowfullscreen", Caster.toString(allowfullscreen)); addParam(sb, "usefullscreen", Caster.toString(allowfullscreen)); addVariable(sb, "autostart", Caster.toString(autostart)); if (!StringUtil.isEmpty(overstretch)) addVariable(sb, "overstretch", overstretch); addVariable(sb, "showdownload", Caster.toString(download)); // color if (lightcolor == null) lightcolor = fgcolor.brighter(); if (screencolor == null) screencolor = Color.BLACK;//fgcolor.brighter(); addVariable(sb, "backcolor", format("0x", bgcolor)); addVariable(sb, "frontcolor", format("0x", fgcolor)); addVariable(sb, "lightcolor", format("0x", lightcolor)); addVariable(sb, "screencolor", format("0x", screencolor)); if (passthrough != null) { Iterator<Entry<Key, Object>> it = passthrough.entryIterator(); Entry<Key, Object> e; String key; while (it.hasNext()) { e = it.next(); key = e.getKey().getString(); if (StringUtil.startsWithIgnoreCase(key, "param.")) addParam(sb, key.substring(6), Caster.toString(e.getValue())); else if (StringUtil.startsWithIgnoreCase(key, "variable.")) addVariable(sb, key.substring(9), Caster.toString(e.getValue())); else if (StringUtil.startsWithIgnoreCase(key, "div.")) ; else addVariable(sb, key, Caster.toString(e.getValue())); } } if (params.size() > 1 && group) addVariable(sb, "repeat", "true"); /*if(playlist!=PLAYLIST_NONE) { if(playlistSize<20)playlistSize=playlist==PLAYLIST_BOTTOM?300:200; if(playlist==PLAYLIST_BOTTOM) { addVariable(sb,"displayheight",Caster.toString(height)); height+=playlistSize; } else { addVariable(sb,"displaywidth",Caster.toString(width)); width+=playlistSize; } if(playlistThumbnails && hasImages())addVariable(sb,"thumbsinplaylist","true"); }*/ // dimension if (dspWidth > 0) addVariable(sb, "displaywidth", Caster.toString(dspWidth)); if (dspHeight > 0) addVariable(sb, "displayheight", Caster.toString(dspHeight)); addVariable(sb, "width", Caster.toString(width)); addVariable(sb, "height", Caster.toString(height)); if (playlistThumbnails && hasImages()) addVariable(sb, "thumbsinplaylist", "true"); //if(preview!=null) addVariable(sb,"image",toPath(preview)); //Iterator it = params.iterator(); //addVariable("file","/rvp/videos/David.flv"); //addVariable("captions","http://localhost:8080/caption.cfm"); //while(it.hasNext()) { //param=(VideoPlayerParamBean) it.next(); //addVariable(sb,"file",toPath(param.getResource())); //break; //} //addVariable("image","video.jpg"); write(sb, "so.write(\"" + placeholderId + "\");\n"); //if(params.size()>1) { Iterator it = params.iterator(); while (it.hasNext()) { param = (VideoPlayerParamBean) it.next(); addItem(sb, flashId, param); } //} write(sb, "</script>"); try { if (debug) { pageContext.forceWrite("<pre>" + StringUtil.replace(sb.toString(), "<", "<", false) + "</pre>"); } pageContext.forceWrite(sb.toString()); } catch (IOException e) { } return EVAL_PAGE; } private synchronized String getId() { if (!StringUtil.isEmpty(id)) return id; _id++; if (_id < 0) _id = 1; return "" + _id; } private boolean hasImages() { Iterator it = params.iterator(); while (it.hasNext()) { if (((VideoPlayerParamBean) it.next()).getImage() != null) return true; } return false; } private void addItem(StringBuffer sb, String id, VideoPlayerParamBean param) { //sb.append("setTimeout('thisMovie(\""+id+"\").addItem({file:\""+JSStringFormat.invoke(path)+"\"},null);',1000);\n"); // file String file = "file:'" + JSStringFormat.invoke(toPath(param.getResource())) + "'"; // image String image = ""; if (param.getImage() != null) { image = ",image:'" + JSStringFormat.invoke(toPath(param.getImage())) + "'"; } // title String title = ""; if (!StringUtil.isEmpty(param.getTitle())) { title = ",title:'" + JSStringFormat.invoke(param.getTitle()) + "'"; } // link String link = ""; if (!StringUtil.isEmpty(param.getLink())) { link = ",link:'" + JSStringFormat.invoke(param.getLink()) + "'"; } // author String author = ""; if (!StringUtil.isEmpty(param.getAuthor())) { author = ",author:'" + JSStringFormat.invoke(param.getAuthor()) + "'"; } sb.append("addItem('" + id + "',{" + file + title + image + link + author + "});\n"); } private void addVariable(StringBuffer sb, String name, String value) { value = JSStringFormat.invoke(value); if (!(value.equals("false") || value.equals("true"))) value = "'" + value + "'"; sb.append("so.addVariable('" + JSStringFormat.invoke(name) + "'," + value + ");\n"); } private void addParam(StringBuffer sb, String name, String value) { sb.append("so.addParam('" + name + "','" + value + "');\n"); } private static int[] calculateDimension(PageContext pc, List params, int width, String strWidth, int height, String strHeight) throws PageException { Iterator it = params.iterator(); ArrayList sources = new ArrayList(); //Resource[] sources=new Resource[params.size()]; VideoPlayerParamBean param; while (it.hasNext()) { param = (VideoPlayerParamBean) it.next(); if (param.getVideo() != null) sources.add(new VideoInputImpl(param.getVideo())); } return VideoUtilImpl.getInstance().calculateDimension(pc, (VideoInput[]) sources.toArray(new VideoInput[sources.size()]), width, strWidth, height, strHeight); } private String toPath(Resource res) { if (!(res instanceof FileResource)) return res.getAbsolutePath(); //Config config=pageContext.getConfig(); PageSource ps = pageContext.toPageSource(res, null); if (ps == null) return res.getAbsolutePath(); String relPath = ps.getRealpath(); relPath = relPath.replace('\\', '/'); if (relPath.endsWith("/")) relPath = relPath.substring(0, relPath.length() - 1); //print.out("real:"+relPath); String mapping = ps.getMapping().getVirtual(); mapping = mapping.replace('\\', '/'); if (mapping.endsWith("/")) mapping = mapping.substring(0, mapping.length() - 1); return mapping + relPath; } private void write(StringBuffer sb, String string) { sb.append(string); } private static String format(String prefix, Color color) { return prefix + toHex(color.getRed()) + toHex(color.getGreen()) + toHex(color.getBlue()); } private static String toHex(int value) { String str = Integer.toHexString(value); if (str.length() == 1) return "0".concat(str); return str; } /** * @param debug the debug to set */ public void setDebug(boolean debug) { this.debug = debug; } /** * @param passthrough the passthrough to set */ public void setPassthrough(Struct passthrough) { this.passthrough = passthrough; } /** * @param preview the preview to set * @throws ExpressionException */ public void setPreview(String preview) { this.preview = preview;//ResourceUtil.toResourceExisting(pageContext, preview); } /** * @param allowfullscreen the allowfullscreen to set */ public void setAllowfullscreen(boolean allowfullscreen) { this.allowfullscreen = allowfullscreen; } public void setAlign(String strAlign) throws ApplicationException { if (StringUtil.isEmpty(strAlign)) return; strAlign = strAlign.trim().toLowerCase(); if ("right".equals(strAlign)) this.align = "right"; else if ("center".equals(strAlign)) this.align = "center"; else if ("left".equals(strAlign)) this.align = "left"; else throw new ApplicationException( "invalid value for attribute align [" + strAlign + "], valid values are [left,center,right]"); } /** * @param group the group to set */ public void setGroup(boolean group) { this.group = group; } public void setLinktarget(String target) { this.target = target; } public void setTarget(String target) { this.target = target; } public void setLinkfromdisplay(boolean linkfromdisplay) { this.linkfromdisplay = linkfromdisplay; } /** * @param playlistThumbnails the playlistThumbnails to set */ public void setPlaylistthumbnails(boolean playlistThumbnails) { this.playlistThumbnails = playlistThumbnails; } public void setThumbnails(boolean playlistThumbnails) { setPlaylistthumbnails(playlistThumbnails); } public void setThumbs(boolean playlistThumbnails) { setPlaylistthumbnails(playlistThumbnails); } /** * @param playlistSize the playlistSize to set */ public void setPlaylistsize(double playlistSize) throws ApplicationException { if (playlistSize <= 40) throw new ApplicationException("playlist size has to be a positive number, at least 41px"); this.playlistSize = (int) playlistSize; } /** * @param playlist the playlist to set */ public void setPlaylist(String strPlaylist) throws PageException { strPlaylist = strPlaylist.trim().toLowerCase(); if ("right".equals(strPlaylist)) playlist = PLAYLIST_RIGHT; else if ("bottom".equals(strPlaylist)) playlist = PLAYLIST_BOTTOM; else if ("none".equals(strPlaylist)) playlist = PLAYLIST_NONE; else if (Decision.isBoolean(strPlaylist)) { playlist = Caster.toBooleanValue(strPlaylist) ? PLAYLIST_BOTTOM : PLAYLIST_NONE; } else throw new ApplicationException( "invalid playlist definition [" + strPlaylist + "], valid values are [right,bottom,none]"); } /** * @param overstretch the overstretch to set */ public void setOverstretch(String overstretch) throws PageException { overstretch = overstretch.trim().toLowerCase(); if ("fit".equals(overstretch)) overstretch = "fit"; else if ("none".equals(overstretch)) overstretch = "none"; else if ("proportion".equals(overstretch)) overstretch = "true"; else if (Decision.isBoolean(overstretch)) { overstretch = Caster.toString(Caster.toBooleanValue(overstretch)); } else throw new ApplicationException( "invalid overstretch definition [" + overstretch + "], valid values are [fit,none,true,false]"); this.overstretch = overstretch; } /** * @param download the download to set */ public void setDownload(boolean download) { this.download = download; } }