/*
* Copyright 2011 Specto Technologies Inc. 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, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package com.spectotechnologies.util;
import java.util.List;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Functions to process simple tasks on HTML data.
*
* @author Specto Technologies Inc., Alexandre Lavoie
*/
public class HTMLUtils
{
public static final String SEPARATOR_ONE = ""; // Problem : IE8, Safari/Windows
public static final String SEPARATOR_TWO = ""; // Problem : IE 5.5, IE 6
public static final String SEPARATOR_THREE = ""; // Problem : FireFox 2
public static String makeBreakableLine(String p_sLine, int p_nInterval, String p_sSeparator)
{
String sTemporaryLine = p_sLine;
String sResult = "";
int nInterval = p_nInterval;
do
{
if(nInterval > sTemporaryLine.length())
{
nInterval = sTemporaryLine.length();
sResult = sResult + sTemporaryLine.substring(0,nInterval);
}
else
{
sResult = sResult + sTemporaryLine.substring(0,nInterval) + p_sSeparator;
}
sTemporaryLine = sTemporaryLine.substring(nInterval,sTemporaryLine.length());
}
while(sTemporaryLine.length() > 0);
return sResult;
}
/**
* 2009-05-13 : Alexandre Lavoie
*
* Replaces all tags in list by specified replacement.
*
*
*
* @param p_sText Text to be verified
* @param p_lTags Tags to search
* @param p_sReplacement Replacement value
* @return
*/
public static String replaceTags(String p_sText, List p_lTags, String p_sReplacement)
{
String sResult;
Pattern oPattern;
Matcher oMatcher;
String sTag;
int nTag;
String sPattern;
int nCharacter;
sResult = p_sText;
for(nTag = 0;nTag < p_lTags.size();nTag++)
{
sTag = p_lTags.get(nTag);
/*
Example of tag pattern
(]*
(/>|
>([^<]|
<[^/]|
[^i]|
)
)
*/
sPattern = "(<" + sTag + "[^/>]*";
sPattern += "(/>|";
sPattern += ">([^<]|";
sPattern += "<[^/]|";
sPattern += "[^" + sTag.charAt(0) + "]|";
for(nCharacter = 0;nCharacter < (sTag.length() - 1);nCharacter++)
{
sPattern += "" + sTag.charAt(nCharacter) + "[^" + sTag.charAt(nCharacter + 1) + "]|";
}
sPattern += ")*" + sTag + ">";
sPattern += ")";
sPattern += ")";
//System.out.println("Pattern : " + sPattern);
oPattern = Pattern.compile(sPattern,Pattern.CASE_INSENSITIVE);
oMatcher = oPattern.matcher(sResult);
sResult = oMatcher.replaceAll(p_sReplacement);
}
return sResult;
}
/**
* Function that trims HTML text content keeping necessary HTML tags.
*
* @param p_sText HTML content to be trimmed
* @param p_nLength Maximum text length
* @return
*/
public static String trim(String p_sText, int p_nLength)
{
if(p_sText == null || p_sText.isEmpty())
return "";
if(p_sText.length() < p_nLength)
return p_sText;
String sTempText;
String sValue;
StringBuilder sbResult = new StringBuilder();
int nTextLength = p_sText.length();
int nResultLength = 0;
Stack oStackHTMLTags = new Stack();
// Start string valid patterns
Pattern oPatternText = Pattern.compile("^[^<&]+");
Pattern oPatternHTMLTag = Pattern.compile("^<.*?>");
Pattern oPatternSpecialCharacter = Pattern.compile("^&[^;]*?;");
Pattern oPatternHTMLTagName = Pattern.compile("^<[a-z]*");
Matcher oMatcher;
boolean bFoundMatch;
int nPosition = 0;
while(nPosition < nTextLength)
{
sTempText = p_sText.substring(nPosition);
bFoundMatch = false;
if(!bFoundMatch)
{
oMatcher = oPatternText.matcher(sTempText);
if(oMatcher.find())
{
sValue = oMatcher.group();
nPosition += sValue.length();
if(sValue.length() >= (p_nLength - nResultLength))
{
sbResult.append(sValue.substring(0,p_nLength - nResultLength));
sbResult.append(" [...]");
break;
}
else
{
sbResult.append(sValue);
nResultLength += sValue.length();
}
bFoundMatch = true;
}
}
if(!bFoundMatch)
{
oMatcher = oPatternHTMLTag.matcher(sTempText);
if(oMatcher.find())
{
sValue = oMatcher.group();
sbResult.append(sValue);
nPosition += sValue.length();
oMatcher = oPatternHTMLTagName.matcher(sValue);
// Add HTML open tag to stack
if(sValue.indexOf('/') == -1 && oMatcher.find())
{
sValue = oMatcher.group();
oStackHTMLTags.push("" + sValue.substring(1) + ">");
}
// Remove HTML close tag
else if(sValue.indexOf('/') == 1)
{
oStackHTMLTags.pop();
}
bFoundMatch = true;
}
}
if(!bFoundMatch)
{
oMatcher = oPatternSpecialCharacter.matcher(sTempText);
if(oMatcher.find())
{
sValue = oMatcher.group();
if(1 >= (p_nLength - nResultLength))
{
sbResult.append(sValue.substring(0,p_nLength - nResultLength));
sbResult.append(" [...]");
break;
}
else
{
sbResult.append(sValue);
nResultLength += 1;
}
nPosition += sValue.length();
bFoundMatch = true;
}
}
}
// Reconstruct HTML close tags
while(oStackHTMLTags.size() > 0)
{
sValue = oStackHTMLTags.pop().toString();
sbResult.append(sValue);
}
return sbResult.toString();
}
}