Initial check-in.

git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@1879 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
Matt Tucker 2003-04-11 15:50:20 +00:00 committed by mtucker
parent 89ef40ba10
commit 4ae4e66cbf
18 changed files with 604 additions and 0 deletions

View File

@ -0,0 +1,292 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2003 Jive Software. All rights reserved.
*
* This software is the proprietary information of Jive Software. Use is subject to license terms.
*/
package org.jivesoftware.webchat;
/**
* A Filter that converts ASCII emoticons into image equivalents.
* This filter should only be run after any HTML stripping filters.<p>
*
* The filter must be configured with information about where the image files
* are located. A table containing all the supported emoticons with their
* ASCII representations and image file names is as follows:<p>
*
* <table border=1>
* <tr><td><b>Emotion</b></td><td><b>ASCII</b></td><td><b>Image</b></td></tr>
*
* <tr><td>Happy</td><td>:) or :-)</td><td>happy.gif</td></tr>
* <tr><td>Sad</td><td>:( or :-(</td><td>sad.gif</td></tr>
* <tr><td>Grin</td><td>:D</td><td>grin.gif</td></tr>
* <tr><td>Love</td><td>:x</td><td>love.gif</td></tr>
* <tr><td>Mischief</td><td>;\</td><td>mischief.gif</td></tr>
* <tr><td>Cool</td><td>B-)</td><td>cool.gif</td></tr>
* <tr><td>Devil</td><td>]:)</td><td>devil.gif</td></tr>
* <tr><td>Silly</td><td>:p</td><td>silly.gif</td></tr>
* <tr><td>Angry</td><td>X-(</td><td>angry.gif</td></tr>
* <tr><td>Laugh</td><td>:^O</td><td>laugh.gif</td></tr>
* <tr><td>Wink</td><td>;) or ;-)</td><td>wink.gif</td></tr>
* <tr><td>Blush</td><td>:8}</td><td>blush.gif</td></tr>
* <tr><td>Cry</td><td>:_|</td><td>cry.gif</td></tr>
* <tr><td>Confused</td><td>?:|</td><td>confused.gif</td></tr>
* <tr><td>Shocked</td><td>:O</td><td>shocked.gif</td></tr>
* <tr><td>Plain</td><td>:|</td><td>plain.gif</td></tr>
* </table>
*
* Note: special thanks to August Harrison for implementing an earlier version of this filter.
*/
public class EmoticonFilter {
private static String imageHappy = "happy.gif";
private static String imageSad = "sad.gif";
private static String imageGrin = "grin.gif";
private static String imageLove = "love.gif";
private static String imageMischief = "mischief.gif";
private static String imageCool = "cool.gif";
private static String imageDevil = "devil.gif";
private static String imageSilly = "silly.gif";
private static String imageAngry = "angry.gif";
private static String imageLaugh = "laugh.gif";
private static String imageWink = "wink.gif";
private static String imageBlush = "blush.gif";
private static String imageCry = "cry.gif";
private static String imageConfused = "confused.gif";
private static String imageShocked = "shocked.gif";
private static String imagePlain = "plain.gif";
private static String imageURL = "images/emoticons";
// Placeholders for the built image tags
private static String imgHappy;
private static String imgSad;
private static String imgGrin;
private static String imgLove;
private static String imgMischief;
private static String imgCool;
private static String imgDevil;
private static String imgSilly;
private static String imgAngry;
private static String imgLaugh;
private static String imgWink;
private static String imgBlush;
private static String imgCry;
private static String imgConfused;
private static String imgShocked;
private static String imgPlain;
public EmoticonFilter() {
buildImageTags();
}
public String applyFilter(String string) {
if (string == null || string.length() < 1) {
return string;
}
int length = string.length();
StringBuffer filtered = new StringBuffer(string.length() + 100);
char[] chars = string.toCharArray();
int length1 = length - 1;
int length2 = length - 2;
int index = -1, i = 0, oldend = 0;
String imgTag;
// Replace each of the emoticons, expanded search for performance
while (++index < length1) {
// no tag found yet...
imgTag = null;
switch (chars[i = index]) {
case ']':
// "]:)"
if (i < length2 && chars[++i] == ':' && chars[++i] == ')') {
imgTag = imgDevil;
}
break;
case ':':
switch (chars[++i]) {
case ')':
// ":)"
imgTag = imgHappy;
break;
case '-':
// ":-)"
if (i < length1 && chars[++i] == ')') {
imgTag = imgHappy;
}
// ":-("
else if (chars[i] == '(') {
imgTag = imgSad;
}
break;
case '(':
// ":("
imgTag = imgSad;
break;
case 'D':
// ":D"
imgTag = imgGrin;
break;
case 'x':
// ":x"
imgTag = imgLove;
break;
case 'p':
// ":p"
imgTag = imgSilly;
break;
case '^':
// ":^O"
if (i < length1 && chars[++i] == 'O') {
imgTag = imgLaugh;
}
break;
case '8':
// ":8}"
if (i < length1 && chars[++i] == '}') {
imgTag = imgBlush;
}
break;
case '_':
// ":_|"
if (i < length1 && chars[++i] == '|') {
imgTag = imgCry;
}
break;
case 'O':
// ":O"
imgTag = imgShocked;
break;
case '|':
// ":|"
imgTag = imgPlain;
break;
default:
break;
}
break;
case ';':
switch (chars[++i]) {
case ')':
// ";)"
imgTag = imgWink;
break;
case '-':
// ";-)"
if (i < length1 && chars[++i] == ')') {
imgTag = imgWink;
}
break;
case '\\':
// ";\\"
imgTag = imgMischief;
break;
default:
break;
}
break;
case 'B':
// "B-)"
if (i < length2 && chars[++i] == '-' && chars[++i] == ')') {
imgTag = imgCool;
}
break;
case 'X':
// "X-("
if (i < length2 && chars[++i] == '-' && chars[++i] == '(') {
imgTag = imgAngry;
}
break;
case '?':
// "?:|"
if (i < length2 && chars[++i] == ':' && chars[++i] == '|') {
imgTag = imgConfused;
}
break;
default:
break;
}
// if we found one, replace
if (imgTag != null) {
filtered.append(chars, oldend, index-oldend);
filtered.append(imgTag);
oldend = i + 1;
index = i;
}
}
if (oldend < length) {
filtered.append(chars, oldend, length-oldend);
}
return filtered.toString();
}
/**
* Returns the base URL for emoticon images. This can be specified as
* an absolute or relative path.
*
* @return the base URL for smiley images.
*/
public String getImageURL() {
return imageURL;
}
/**
* Sets the base URL for emoticon images. This can be specified as
* an absolute or relative path.
*
* @param imageURL the base URL for emoticon images.
*/
public void setImageURL(String imageURL) {
if (imageURL != null && imageURL.length() > 0) {
if (imageURL.charAt(imageURL.length()-1) == '/') {
imageURL = imageURL.substring(0, imageURL.length()-1);
}
}
this.imageURL = imageURL;
// rebuild the image tags
buildImageTags();
}
/**
* Build image tags
*/
private void buildImageTags() {
imgHappy = buildURL(imageHappy);
imgSad = buildURL(imageSad);
imgGrin = buildURL(imageGrin);
imgLove = buildURL(imageLove);
imgMischief = buildURL(imageMischief);
imgCool = buildURL(imageCool);
imgDevil = buildURL(imageDevil);
imgSilly = buildURL(imageSilly);
imgAngry = buildURL(imageAngry);
imgLaugh = buildURL(imageLaugh);
imgWink = buildURL(imageWink);
imgBlush = buildURL(imageBlush);
imgCry = buildURL(imageCry);
imgConfused = buildURL(imageConfused);
imgShocked = buildURL(imageShocked);
imgPlain = buildURL(imagePlain);
}
/**
* Returns an HTML image tag using the base image URL and image name.
*/
private String buildURL(String imageName) {
String tag = "<img border='0' src='" + imageURL + "/" + imageName + "'>";
return tag;
}
}

View File

@ -0,0 +1,312 @@
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 1999-2002 CoolServlets, Inc. All rights reserved.
*
* This software is the proprietary information of CoolServlets, Inc.
* Use is subject to license terms.
*/
package org.jivesoftware.webchat;
import java.util.*;
/**
* A Filter that converts URL's to working HTML web links.<p>
*
* The default set of patterns recognized are <code>ftp://path-of-url</code>,
* <code>http://path-of-url</code>, <code>https://path-of-url</code> but can be expanded upon.<p>
*
* In addition, the following patterns are also recognized.
*
* <code>[url path-of-url]descriptive text[/url]</code> and
* <code>[url=path-of-url]descriptive text[/url]</code>.<p>
*
* The <code>[url]</code> allows any path to be defined as link.
*/
public class URLFilter{
private ArrayList schemes = new ArrayList();
// define a preset default set of schemes
public URLFilter() {
schemes.add("http://");
schemes.add("https://");
schemes.add("ftp://");
}
public String applyFilter(String string) {
if (string == null || string.length() == 0) {
return string;
}
int length = string.length();
StringBuffer filtered = new StringBuffer((int) (length * 1.5));
ArrayList urlBlocks = new ArrayList(5);
// search for url's such as [url=..]text[/url] or [url ..]text[/url]
int start = string.indexOf("[url");
while (start != -1 && (start + 5 < length)) {
// check to verify we're not in another block
if (withinAnotherBlock(urlBlocks, start)) {
start = string.indexOf("[url", start + 5);
continue;
}
int end = string.indexOf("[/url]", start + 5);
if (end == -1 || end >= length) {
// went past end of string, skip
break;
}
String u = string.substring(start, end + 6);
int startTagClose = u.indexOf(']');
String url;
String description;
if (startTagClose > 5) {
url = u.substring(5, startTagClose);
description = u.substring(startTagClose + 1, u.length() - 6);
// Check the user entered URL for a "javascript:" or "file:" link. Only
// append the user entered link if it doesn't contain 'javascript:' and 'file:'
String lcURL = url.toLowerCase();
if (lcURL.indexOf("javascript:") == -1 && lcURL.indexOf("file:") == -1) {
URLBlock block = new URLBlock(start, end + 5, url, description);
urlBlocks.add(block);
}
}
else {
url = description = u.substring(startTagClose + 1, u.length() - 6);
// Check the user entered URL for a "javascript:" or "file:" link. Only
// append the user entered link if it doesn't contain 'javascript:' and 'file:'
String lcURL = url.toLowerCase();
if (lcURL.indexOf("javascript:") == -1 && lcURL.indexOf("file:") == -1) {
URLBlock block = new URLBlock(start, end + 5, url);
urlBlocks.add(block);
}
}
start = string.indexOf("[url", end + 6);
}
// now handle all the other urls
Iterator iter = schemes.iterator();
while (iter.hasNext()) {
String scheme = (String) iter.next();
start = string.indexOf(scheme, 0);
while (start != -1) {
int end = start;
// check context, don't handle patterns preceded by any of '"<=
if (start > 0) {
char c = string.charAt(start - 1);
if (c == '\'' || c == '"' || c == '<' || c == '=') {
start = string.indexOf(scheme, start + scheme.length());
continue;
}
}
// check to verify we're not in another block
if (withinAnotherBlock(urlBlocks, start)) {
start = string.indexOf(scheme, start + scheme.length());
continue;
}
// find the end of the url
int cur = start + scheme.length();
while (end == start && cur < length) {
char c = string.charAt(cur);
switch (c) {
case ' ':
end = cur;
break;
case '\t':
end = cur;
break;
case '\'':
end = cur;
break;
case '\"':
end = cur;
break;
case '<':
end = cur;
break;
case '[':
end = cur;
break;
case '\n':
end = cur;
break;
case '\r':
end = cur;
break;
default:
// acceptable character
}
cur++;
}
// if this is true it means the url goes to the end of the string
if (end == start) {
end = length - 1;
}
URLBlock block = new URLBlock(start, end-1, string.substring(start, end));
urlBlocks.add(block);
start = string.indexOf(scheme, end);
}
}
// sort the blocks so that they are in start index order
sortBlocks(urlBlocks);
// now, markup the urls and pass along the filter chain the rest
Iterator blocks = urlBlocks.iterator();
int last = 0;
while (blocks.hasNext()) {
URLBlock block = (URLBlock) blocks.next();
if (block.getStart() > 0) {
filtered.append(string.substring(last, block.getStart()));
}
last = block.getEnd() + 1;
filtered.append("<a href='").append(block.getUrl()).append("' target='_blank'>");
if (block.getDescription().length() > 0) {
filtered.append(block.getDescription());
}
else {
filtered.append(block.getUrl());
}
filtered.append("</a>");
}
if (last < string.length() - 1) {
filtered.append(string.substring(last));
}
return filtered.toString();
}
/**
* Returns the current supported uri schemes as a comma seperated string.
*
* @return the current supported uri schemes as a comma seperated string.
*/
public String getSchemes() {
StringBuffer buf = new StringBuffer(50);
for (int i = 0; i < schemes.size(); i++) {
buf.append((String) schemes.get(i)).append(",");
}
buf.deleteCharAt(buf.length() - 1);
return buf.toString();
}
/**
* Sets the current supported uri schemes as a comma seperated string.
*
* @param schemes a comma seperated string of uri schemes.
*/
public void setSchemes(String schemes) {
if (schemes == null) {
return;
}
// enpty the current list
this.schemes.clear();
StringTokenizer st = new StringTokenizer(schemes, ",");
while (st.hasMoreElements()) {
this.schemes.add(st.nextElement());
}
}
private void sortBlocks(ArrayList blocks) {
Collections.sort(blocks, new Comparator() {
public int compare(Object object1, Object object2) {
URLBlock b1 = (URLBlock) object1;
URLBlock b2 = (URLBlock) object2;
return (b1.getStart() > b2.getStart()) ? 1 : -1;
}
});
}
private boolean withinAnotherBlock(List blocks, int start) {
for (int i = 0; i < blocks.size(); i++) {
URLBlock block = (URLBlock) blocks.get(i);
if (start >= block.getStart() && start < block.getEnd()) {
return true;
}
}
return false;
}
class URLBlock {
int start = 0;
int end = 0;
String description = "";
String url = "";
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
URLBlock(int start, int end, String url) {
this.start = start;
this.end = end;
this.url = url;
}
URLBlock(int start, int end, String url, String description) {
this.start = start;
this.end = end;
this.description = description;
this.url = url;
}
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getEnd() {
return end;
}
public void setEnd(int end) {
this.end = end;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 687 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 693 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 693 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 678 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 694 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B