diff options
Diffstat (limited to 'subsonic-main/src/main/java/net/sourceforge/subsonic/taglib')
5 files changed, 499 insertions, 0 deletions
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/EscapeJavaScriptTag.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/EscapeJavaScriptTag.java new file mode 100644 index 00000000..c7c09677 --- /dev/null +++ b/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/EscapeJavaScriptTag.java @@ -0,0 +1,77 @@ +/* + This file is part of Subsonic. + + Subsonic is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Subsonic 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see <http://www.gnu.org/licenses/>. + + Copyright 2009 (C) Sindre Mehus + */ +package net.sourceforge.subsonic.taglib; + +import org.apache.commons.lang.StringEscapeUtils; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.JspTagException; +import javax.servlet.jsp.tagext.BodyTagSupport; +import java.io.IOException; + +/** + * Escapes the characters in a <code>String</code> using JavaScript String rules. + * <p/> + * Escapes any values it finds into their JavaScript String form. + * Deals correctly with quotes and control-chars (tab, backslash, cr, ff, etc.) + * <p/> + * So a tab becomes the characters <code>'\\'</code> and + * <code>'t'</code>. + * <p/> + * The only difference between Java strings and JavaScript strings + * is that in JavaScript, a single quote must be escaped. + * <p/> + * Example: + * <pre> + * input string: He didn't say, "Stop!" + * output string: He didn\'t say, \"Stop!\" + * </pre> + * + * @author Sindre Mehus + */ +public class EscapeJavaScriptTag extends BodyTagSupport { + + private String string; + + public int doStartTag() throws JspException { + return EVAL_BODY_BUFFERED; + } + + public int doEndTag() throws JspException { + try { + pageContext.getOut().print(StringEscapeUtils.escapeJavaScript(string)); + } catch (IOException x) { + throw new JspTagException(x); + } + return EVAL_PAGE; + } + + public void release() { + string = null; + super.release(); + } + + public String getString() { + return string; + } + + public void setString(String string) { + this.string = string; + } +}
\ No newline at end of file diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/FormatBytesTag.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/FormatBytesTag.java new file mode 100644 index 00000000..0279316b --- /dev/null +++ b/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/FormatBytesTag.java @@ -0,0 +1,76 @@ +/* + This file is part of Subsonic. + + Subsonic is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Subsonic 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see <http://www.gnu.org/licenses/>. + + Copyright 2009 (C) Sindre Mehus + */ +package net.sourceforge.subsonic.taglib; + +import net.sourceforge.subsonic.util.*; +import org.springframework.web.servlet.support.*; + +import javax.servlet.http.*; +import javax.servlet.jsp.*; +import javax.servlet.jsp.tagext.*; +import java.io.*; +import java.util.*; + +/** + * Converts a byte-count to a formatted string suitable for display to the user, with respect + * to the current locale. + * <p/> + * For instance: + * <ul> + * <li><code>format(918)</code> returns <em>"918 B"</em>.</li> + * <li><code>format(98765)</code> returns <em>"96 KB"</em>.</li> + * <li><code>format(1238476)</code> returns <em>"1.2 MB"</em>.</li> + * </ul> + * This class assumes that 1 KB is 1024 bytes. + * + * @author Sindre Mehus + */ +public class FormatBytesTag extends BodyTagSupport { + + private long bytes; + + public int doStartTag() throws JspException { + return EVAL_BODY_BUFFERED; + } + + public int doEndTag() throws JspException { + Locale locale = RequestContextUtils.getLocale((HttpServletRequest) pageContext.getRequest()); + String result = StringUtil.formatBytes(bytes, locale); + + try { + pageContext.getOut().print(result); + } catch (IOException x) { + throw new JspTagException(x); + } + return EVAL_PAGE; + } + + public void release() { + bytes = 0L; + super.release(); + } + + public long getBytes() { + return bytes; + } + + public void setBytes(long bytes) { + this.bytes = bytes; + } +} diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/ParamTag.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/ParamTag.java new file mode 100644 index 00000000..1043902e --- /dev/null +++ b/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/ParamTag.java @@ -0,0 +1,67 @@ +/* + This file is part of Subsonic. + + Subsonic is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Subsonic 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see <http://www.gnu.org/licenses/>. + + Copyright 2009 (C) Sindre Mehus + */ +package net.sourceforge.subsonic.taglib; + +import javax.servlet.jsp.tagext.*; +import javax.servlet.jsp.*; + +/** + * A tag representing an URL query parameter. + * + * @see ParamTag + * @author Sindre Mehus + */ +public class ParamTag extends TagSupport { + + private String name; + private String value; + + public int doEndTag() throws JspTagException { + + // Add parameter name and value to surrounding 'url' tag. + UrlTag tag = (UrlTag) findAncestorWithClass(this, UrlTag.class); + if (tag == null) { + throw new JspTagException("'sub:param' tag used outside 'sub:url'"); + } + tag.addParameter(name, value); + return EVAL_PAGE; + } + + public void release() { + name = null; + value = null; + super.release(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/UrlTag.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/UrlTag.java new file mode 100644 index 00000000..141ba847 --- /dev/null +++ b/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/UrlTag.java @@ -0,0 +1,207 @@ +/* + This file is part of Subsonic. + + Subsonic is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Subsonic 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see <http://www.gnu.org/licenses/>. + + Copyright 2009 (C) Sindre Mehus + */ +package net.sourceforge.subsonic.taglib; + +import net.sourceforge.subsonic.Logger; +import net.sourceforge.subsonic.filter.ParameterDecodingFilter; +import net.sourceforge.subsonic.util.StringUtil; +import org.apache.taglibs.standard.tag.common.core.UrlSupport; +import org.apache.commons.lang.CharUtils; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.JspTagException; +import javax.servlet.jsp.PageContext; +import javax.servlet.jsp.tagext.BodyTagSupport; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; + +/** + * Creates a URL with optional query parameters. Similar to 'c:url', but + * you may specify which character encoding to use for the URL query + * parameters. If no encoding is specified, the following steps are performed: + * <ul> + * <li>Parameter values are encoded as the hexadecimal representation of the UTF-8 bytes of the original string.</li> + * <li>Parameter names are prepended with the suffix "Utf8Hex"</li> + * <li>Note: Nothing is done with the parameter name or value if the value only contains ASCII alphanumeric characters.</li> + * </ul> + * <p/> + * (The problem with c:url is that is uses the same encoding as the http response, + * but most(?) servlet container assumes that ISO-8859-1 is used.) + * + * @author Sindre Mehus + */ +public class UrlTag extends BodyTagSupport { + + private String DEFAULT_ENCODING = "Utf8Hex"; + private static final Logger LOG = Logger.getLogger(UrlTag.class); + + private String var; + private String value; + private String encoding = DEFAULT_ENCODING; + private List<Parameter> parameters = new ArrayList<Parameter>(); + + public int doStartTag() throws JspException { + parameters.clear(); + return EVAL_BODY_BUFFERED; + } + + public int doEndTag() throws JspException { + + // Rewrite and encode the url. + String result = formatUrl(); + + // Store or print the output + if (var != null) + pageContext.setAttribute(var, result, PageContext.PAGE_SCOPE); + else { + try { + pageContext.getOut().print(result); + } catch (IOException x) { + throw new JspTagException(x); + } + } + return EVAL_PAGE; + } + + private String formatUrl() throws JspException { + String baseUrl = UrlSupport.resolveUrl(value, null, pageContext); + + StringBuffer result = new StringBuffer(); + result.append(baseUrl); + if (!parameters.isEmpty()) { + result.append('?'); + + for (int i = 0; i < parameters.size(); i++) { + Parameter parameter = parameters.get(i); + try { + result.append(parameter.getName()); + if (isUtf8Hex() && !isAsciiAlphaNumeric(parameter.getValue())) { + result.append(ParameterDecodingFilter.PARAM_SUFFIX); + } + + result.append('='); + if (parameter.getValue() != null) { + result.append(encode(parameter.getValue())); + } + if (i < parameters.size() - 1) { + result.append("&"); + } + + } catch (UnsupportedEncodingException x) { + throw new JspTagException(x); + } + } + } + return result.toString(); + } + + private String encode(String s) throws UnsupportedEncodingException { + if (isUtf8Hex()) { + if (isAsciiAlphaNumeric(s)) { + return s; + } + + try { + return StringUtil.utf8HexEncode(s); + } catch (Exception x) { + LOG.error("Failed to utf8hex-encode the string '" + s + "'.", x); + return s; + } + } + + return URLEncoder.encode(s, encoding); + } + + private boolean isUtf8Hex() { + return DEFAULT_ENCODING.equals(encoding); + } + + private boolean isAsciiAlphaNumeric(String s) { + if (s == null) { + return true; + } + + for (int i = 0; i < s.length(); i++) { + if (!CharUtils.isAsciiAlphanumeric(s.charAt(i))) { + return false; + } + } + return true; + } + + public void release() { + var = null; + value = null; + encoding = DEFAULT_ENCODING; + parameters.clear(); + super.release(); + } + + public void addParameter(String name, String value) { + parameters.add(new Parameter(name, value)); + } + + public String getVar() { + return var; + } + + public void setVar(String var) { + this.var = var; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getEncoding() { + return encoding; + } + + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + /** + * A URL query parameter. + */ + private static class Parameter { + private String name; + private String value; + + private Parameter(String name, String value) { + this.name = name; + this.value = value; + } + + private String getName() { + return name; + } + + private String getValue() { + return value; + } + } +} diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/WikiTag.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/WikiTag.java new file mode 100644 index 00000000..e099bd1e --- /dev/null +++ b/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/WikiTag.java @@ -0,0 +1,72 @@ +/* + This file is part of Subsonic. + + Subsonic is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Subsonic 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see <http://www.gnu.org/licenses/>. + + Copyright 2009 (C) Sindre Mehus + */ +package net.sourceforge.subsonic.taglib; + +import org.radeox.api.engine.*; +import org.radeox.api.engine.context.*; +import org.radeox.engine.*; +import org.radeox.engine.context.*; +import org.apache.commons.lang.*; + +import javax.servlet.jsp.*; +import javax.servlet.jsp.tagext.*; +import java.io.*; + +/** + * Renders a Wiki text with markup to HTML, using the Radeox render engine. + * + * @author Sindre Mehus + */ +public class WikiTag extends BodyTagSupport { + + private static final RenderContext RENDER_CONTEXT = new BaseRenderContext(); + private static final RenderEngine RENDER_ENGINE = new BaseRenderEngine(); + + private String text; + + public int doStartTag() throws JspException { + return EVAL_BODY_BUFFERED; + } + + public int doEndTag() throws JspException { + String result; + synchronized (RENDER_ENGINE) { + result = RENDER_ENGINE.render(StringEscapeUtils.unescapeXml(text), RENDER_CONTEXT); + } + try { + pageContext.getOut().print(result); + } catch (IOException x) { + throw new JspTagException(x); + } + return EVAL_PAGE; + } + + public void release() { + text = null; + super.release(); + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } +} |