import java.net.*;
import java.io.*;
import java.util.*;
//-- can only import packages in jdk 1.4
//import Html;
//import TextTool;
//import QuoteText;
//import EndText;
//import DocumentElement;
/**
*
* This class is a piece of text which contains as one
* of its dimensions data which may be interpreted as
* a locator of some other resource. One example format is
*
* http://dict.org/ 'search the dictionary'
*
*
* @author http://bumble.sf.net
* @See Answer, FAQ, etc
*/
public class TextLink extends Object implements DocumentElement
{
//--------------------------------------------
private static String NEWLINE = System.getProperty("line.separator");
//--------------------------------------------
/** */
private String text;
//--------------------------------------------
private String pointer;
//--------------------------------------------
public static String TERMINATOR = "";
//--------------------------------------------
/** the protocols which the link will recognize */
public static String[] protocols =
{
"www.", "http://", "https://", "ftp://", "link://",
"dict://", "news://", "file://", "telnet://", "sftp://",
"gopher://", "mailto:"
};
//--------------------------------------------
private boolean isGood;
//--------------------------------------------
private String returnToken;
//--------------------------------------------
public TextLink()
{
this.text = "";
this.pointer = "";
this.returnToken = "";
}
//--------------------------------------------
/** construct with some text */
public TextLink(String sText)
{
this();
this.loadData(sText);
}
//--------------------------------------------
/** load data from text */
public void loadData(String sText)
{
String sTextTrimmed;
String sTarget;
this.isGood = this.isTextLink(sText);
if (!this.isGood)
{
return;
}
sTextTrimmed = sText.trim();
String[] ssLink = TextTool.splitOnFirstSpace(sText);
sTarget = ssLink[0];
//--
if (sTarget.toLowerCase().startsWith("www."))
{
this.pointer = "http://" + sTarget;
}
else if (sTarget.toLowerCase().startsWith("link://"))
{
this.pointer = EndText.removePrefix(sTarget, "link://");
}
else
{
this.pointer = sTarget;
}
if (ssLink.length == 1)
{
this.text = this.pointer;
}
else if (ssLink.length == 2)
{
//-- if the second section only has one letter, then it
//-- is just the end token (end of link delimiter) and
//-- is not part of the data
//--
if (ssLink[1].length() == 1)
{
this.text = this.pointer;
}
else
{
this.text = QuoteText.popQuotes(ssLink[1]);
}
} //-- if
//-- if the display text is empty, make it the same
//-- as the pointer.
//--
if (this.text.trim().length() == 0)
{
this.text = this.pointer;
}
} //-- method: loadData
//--------------------------------------------
/** this method sees if the end of another string looks
* like the start of a TextLink. this might be called
* by a parsing routine */
public static boolean recognize(String sText)
{
//-- it is necessary to stop the token below from
//-- being recognised twice, first for the http:// and
//-- then for the www.
//--
if (sText.endsWith("http://www."))
{ return false; }
return TextTool.endsWithIgnoreCase(sText, TextLink.protocols);
}
//--------------------------------------------
public static String startToken(String sText)
{
return EndText.getSuffix(sText, TextLink.protocols);
}
//--------------------------------------------
/** we have to be able to hand back the end delimiter for
* a link with no display text, since that type of link
* is using a non-space character as its end delimiter */
public static String returnEndToken(String sText)
{
String[] ssSections = TextTool.splitOnFirstSpace(sText);
if (ssSections.length == 1)
{
return "";
}
if (ssSections[1].length() == 1)
{
return ssSections[1];
}
return "";
}
//--------------------------------------------
public String getText()
{
return this.text;
}
//--------------------------------------------
public void setText(String sText)
{
this.text = sText;
}
//--------------------------------------------
/** checks if this looks like a text link. If there is
* no display text then the link is ended by spaces and
* a non space, non-quote character. eg 'http://server.net q'
* */
public static boolean isTextLink(String sText)
{
if (sText.trim().length() == 0)
{ return false; }
if (!TextTool.startsWithIgnoreCase(sText.trim(), TextLink.protocols))
{
return false;
}
String[] ssSections = TextTool.splitOnFirstSpace(sText);
if (ssSections.length == 1)
{
return false;
}
else if (ssSections.length == 2)
{
if (!QuoteText.isQuoted(ssSections[1]))
{
if (ssSections[1].length() != 1)
{ return false; }
if (QuoteText.isQuote(ssSections[1].charAt(0)))
{ return false; }
}
}
return true;
} //-- method: isTextLink
//--------------------------------------------
/** a plain link has no display text after it in quotes.
* Its end is delimited by a space
**/
public static boolean isPlainLink(String sText)
{
if (sText.trim().length() == 0)
{ return false; }
if (!TextTool.startsWithIgnoreCase(sText.trim(), TextLink.protocols))
{
return false;
}
String[] ssSections = TextTool.splitOnFirstSpace(sText);
if (ssSections.length == 1)
{
if (!sText.endsWith(" "))
{
return false;
}
}
else if (ssSections.length == 2)
{
if (!QuoteText.isQuoted(ssSections[1]))
{
return false;
}
}
return true;
} //-- method: isTextLink
//--------------------------------------------
public String toString()
{
StringBuffer sbReturn = new StringBuffer("");
sbReturn.append(this.pointer);
sbReturn.append(" ");
if (!this.pointer.equals(this.text))
{
sbReturn.append("'" + this.text + "' ");
}
return sbReturn.toString();
}
//--------------------------------------------
public String printReport()
{
StringBuffer sbReturn = new StringBuffer("");
sbReturn.append("Text of the link>");
sbReturn.append(this.text);
sbReturn.append(NEWLINE);
sbReturn.append("Link points to >");
sbReturn.append(this.pointer);
sbReturn.append(NEWLINE);
sbReturn.append("Last data ok >");
sbReturn.append(this.isGood);
sbReturn.append(NEWLINE);
return sbReturn.toString();
}
//--------------------------------------------
public String printHtml()
{
StringBuffer sbReturn = new StringBuffer("");
sbReturn.append("");
sbReturn.append(Html.encode(this.text.trim()));
sbReturn.append(" ");
return sbReturn.toString();
}
//--------------------------------------------
public String printDocBook()
{
StringBuffer sbReturn = new StringBuffer("");
sbReturn.append("");
sbReturn.append(Html.encode(this.text.trim()));
sbReturn.append(" ");
return sbReturn.toString();
}
//--------------------------------------------
public String printWiki()
{
StringBuffer sbReturn = new StringBuffer("");
sbReturn.append("[");
sbReturn.append(this.pointer.trim());
sbReturn.append("][");
sbReturn.append(this.text.trim());
sbReturn.append("] ");
return sbReturn.toString();
}
//--------------------------------------------
public String print()
{
StringBuffer sbReturn = new StringBuffer("");
return this.toString();
}
//--------------------------------------------
/** a main method for testing */
public static void main(String[] args) throws Exception
{
StringBuffer sbUsageMessage = new StringBuffer("");
sbUsageMessage.append("test usage: java TextLink text");
sbUsageMessage.append(NEWLINE);
sbUsageMessage.append("eg: java TextLink \"http://bumble.sf.net 'here'\" ");
sbUsageMessage.append(NEWLINE);
StringBuffer sbMessage = new StringBuffer("");
if (args.length == 0)
{
System.out.println(sbUsageMessage);
System.exit(-1);
}
TextLink linkTest = new TextLink(args[0]);
System.out.println(".isTextLink(" + args[0] + ")");
System.out.println(linkTest.isTextLink(args[0]));
System.out.println(".isPlainLink(" + args[0] + ")");
System.out.println(linkTest.isPlainLink(args[0]));
System.out.println(".returnEndToken(" + args[0] + ")");
System.out.println(linkTest.returnEndToken(args[0]));
System.out.println(".startToken(" + args[0] + ")");
System.out.println(linkTest.startToken(args[0]));
System.out.println(".printHtml()");
System.out.println(linkTest.printHtml());
System.out.println(".toString()");
System.out.println(linkTest.toString());
System.out.println(".printReport()");
System.out.println(linkTest.printReport());
} //-- main()
} //-- Question class