blob: 3e74cfd836e36ac631be178ad529d43c3271e627 [file] [log] [blame]
/*
* Copyright 1999,2004 The Apache Software Foundation.
*
* Licensed 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.roller.weblogger.ui.tags;
import javax.servlet.jsp.JspException;
import org.apache.commons.lang3.math.NumberUtils;
/**
* Code grabbed from retired Jakarta Tablibs project: http://jakarta.apache.org/taglibs/string/
*
* A more intelligent substring. It attempts to cut off a string after
* a space, following predefined or user-supplied lower and upper limits,
* useful for making short descriptions from long text. Can also strip
* HTML, or if not, intelligently close any tags that were left open.
* It adds on a user-defined ending.
*
* <dl>
* <dt>lower</dt><dd>
* Minimum length to truncate at.
* Required.
* </dd>
* <dt>upper</dt><dd>
* Maximum length to truncate at.
* Required.
* </dd>
* <dt>upper</dt><dd>
* String to append to end of truncated string.
* </dd>
* </dl>
*
* @author timster@mac.com
*/
public class TruncateNicelyTag extends StringTagSupport {
private String lower;
private String upper;
private String appendToEnd;
public TruncateNicelyTag() {
super();
}
/**
* Get the lower property
*
* @return String lower property
*/
public String getLower() {
return this.lower;
}
/**
* Set the upper property
*
* @param lower String property
*/
public void setLower(String lower) {
this.lower = lower;
}
/**
* Get the upper property
*
* @return String upper property
*/
public String getUpper() {
return this.upper;
}
/**
* Set the upper property
*
* @param upper String property
*/
public void setUpper(String upper) {
this.upper = upper;
}
public String getAppendToEnd() {
return this.appendToEnd;
}
public void setAppendToEnd(String s) {
this.appendToEnd = s;
}
public String changeString(String text) throws JspException {
int l = NumberUtils.toInt(lower);
int u = NumberUtils.toInt(upper);
return truncateNicely(text, l, u, this.appendToEnd);
}
@Override
public void initAttributes() {
this.lower = "10";
this.upper = "-1";
this.appendToEnd = "...";
}
/**
* Truncates a string nicely. It will search for the first space
* after the lower limit and truncate the string there. It will
* also append any string passed as a parameter to the end of the
* string. The hard limit can be specified to forcibily truncate a
* string (in the case of an extremely long word or such). All
* HTML/XML markup will be stripped from the string prior to
* processing for truncation.
*
* @param str String the string to be truncated.
* @param lower int value of the lower limit.
* @param upper int value of the upper limit, -1 if no limit is
* desired. If the uppper limit is lower than the
* lower limit, it will be adjusted to be same as
* the lower limit.
* @param appendToEnd String to be appended to the end of the
* truncated string.
* This is appended ONLY if the string was indeed
* truncated. The append is does not count towards
* any lower/upper limits.
*/
private static String truncateNicely(String str, int lower, int upper, String appendToEnd)
{
// strip markup from the string
str = removeXml(str);
// quickly adjust the upper if it is set lower than 'lower'
if(upper < lower) {
upper = lower;
}
// now determine if the string fits within the upper limit
// if it does, go straight to return, do not pass 'go' and collect $200
if(str.length() > upper) {
// the magic location int
int loc;
// first we determine where the next space appears after lower
loc = str.lastIndexOf(' ', upper);
// now we'll see if the location is greater than the lower limit
if(loc >= lower) {
// yes it was, so we'll cut it off here
str = str.substring(0, loc);
} else {
// no it wasn't, so we'll cut it off at the upper limit
str = str.substring(0, upper);
}
// the string was truncated, so we append the appendToEnd String
str = str + appendToEnd;
}
return str;
}
/**
* Remove any xml tags from a String.
*/
private static String removeXml(String str) {
int sz = str.length();
StringBuilder buffer = new StringBuilder(sz);
boolean inTag = false;
for (int i=0; i<sz; i++) {
char ch = str.charAt(i);
if (ch == '<') {
inTag = true;
} else
if (ch == '>') {
inTag = false;
continue;
}
if (!inTag) {
buffer.append(ch);
}
}
return buffer.toString();
}
}