001 package edu.nrao.sss.html; 002 003 import java.io.IOException; 004 import java.io.Writer; 005 006 import javax.swing.text.html.HTML; 007 008 /** 009 * An HTML anchor ({@link javax.swing.text.html.HTML.Tag#A}). 010 * <p> 011 * <b>Version Info:</b> 012 * <table style="margin-left:2em"> 013 * <tr><td>$Revision: 1360 $</td></tr> 014 * <tr><td>$Date: 2008-06-19 14:08:48 -0600 (Thu, 19 Jun 2008) $</td></tr> 015 * <tr><td>$Author: dharland $</td></tr> 016 * </table></p> 017 * 018 * @author David M. Harland 019 * @since 2007-03-20 020 */ 021 public class HtmlAnchor 022 extends HtmlElement 023 { 024 private String displayText; 025 026 /** Creates a new, unnamed, empty anchor. */ 027 public HtmlAnchor() 028 { 029 this(null, null, null); 030 } 031 032 /** 033 * Creates a new HTML anchor with the given properties. 034 * The text form of this anchor is:<pre> 035 * <a name="<i>name</i>" href="<i>href</i>"><i>display</i></a> 036 * </pre> 037 * 038 * @param name the name of this anchor. 039 * If this parameter is <i>null</i>, this anchor will have 040 * no name. 041 * 042 * @param href the HTML link associated with this anchor. 043 * If this parameter is <i>null</i>, this anchor will have 044 * no link. 045 * 046 * @param display the text displayed on an HTML page for this anchor. 047 * If this parameter is <i>null</i>, it will be converted 048 * to the empty string (<tt>""</tt>). 049 */ 050 public HtmlAnchor(String name, String href, String display) 051 { 052 super(HTML.Tag.A); 053 054 if (name != null) 055 attributes.put(HTML.Attribute.NAME, 056 new HtmlAttribute(HTML.Attribute.NAME, name)); 057 058 if (href != null) 059 attributes.put(HTML.Attribute.HREF, 060 new HtmlAttribute(HTML.Attribute.HREF, href)); 061 062 displayText = (display == null) ? "" : display; 063 } 064 065 /** 066 * Creates and returns a new HTML anchor by parsing {@code anchorTag}. 067 * 068 * @param anchorTag the HTML form of this anchor. 069 * The expected form of the text is: 070 * <pre> <a name="name" href='absolute or relative URL'>display text</a></pre> 071 * The anchor name can be "a" or "A"; you may even mix the capitalization in 072 * a single tag (<A ...>...</a>). Values may be quoted with 073 * either single (') or double (") quotes. Leading and trailing whitespace 074 * is permitted and will be trimmed during parsing.</p> 075 * 076 * @return a new HTML anchor by parsing {@code anchorTag}. 077 * 078 * @throws IllegalArgumentException if anything goes wrong during parsing. 079 */ 080 public static HtmlAnchor parse(String anchorTag) 081 { 082 try 083 { 084 HtmlAnchor anchor = new HtmlAnchor(); 085 anchor.parseAnchor(anchorTag); 086 return anchor; 087 } 088 catch (Exception ex) 089 { 090 throw new IllegalArgumentException("Could not parse anchorTag [" + 091 anchorTag + "]: " + 092 ex.getMessage()); 093 } 094 } 095 096 @Override 097 public boolean isSimple() 098 { 099 return false; 100 } 101 102 /** 103 * Sets the text to display for this anchor. 104 * 105 * @param text the text to display for this anchor. If this 106 * parameter is <i>null</i>, it will be replaced by the 107 * empty string (<tt>""</tt>). 108 */ 109 public void setDisplayText(String text) 110 { 111 displayText = (text == null) ? "" : text; 112 } 113 114 /** 115 * Returns the text to display for this anchor. 116 * 117 * @return the text to display for this anchor. This value is guaranteed 118 * to be non-null, but it could be the empty string (<tt>""</tt>). 119 */ 120 public String getDisplayText() 121 { 122 return displayText; 123 } 124 125 /** 126 * Sets the value of this anchor tag based on the given text. 127 * <p> 128 * The expected form of the text is: 129 * <pre> <a name1="value1" name2='value two'>display text</a></pre> 130 * The anchor name can be "a" or "A"; you may even mix the capitalization in 131 * a single tag (<A ...>...</a>). Values may be quoted with 132 * either single (') or double (") quotes. Leading and trailing whitespace 133 * is permitted and will be trimmed during parsing.</p> 134 * <p> 135 * If anything goes wrong during parsing, an {@code IllegalArgumentException} 136 * is thrown. All successfully parsed information up to the point of the 137 * exception will be maintained by this instance.</p> 138 * 139 * @param anchorTag text representation of an HTML anchor. 140 */ 141 private void parseAnchor(String anchorTag) 142 { 143 if (anchorTag == null) 144 throw new IllegalArgumentException("must not be null."); 145 146 String text = anchorTag.trim(); 147 148 if (anchorTag.length() == 0) 149 throw new IllegalArgumentException("must not be empty."); 150 151 if (!(text.startsWith("<a") || text.startsWith("<A")) || 152 !(text.endsWith("</a>") || text.endsWith("</A>"))) 153 throw new IllegalArgumentException( 154 "must start with '<a' and end with '</a>'."); 155 156 int endOpenTagPos = text.indexOf('>'); 157 158 displayText = text.substring(endOpenTagPos+1,text.indexOf("</")); 159 160 parseAttributes(text.substring(2, endOpenTagPos)); 161 } 162 163 //============================================================================ 164 // WRITING 165 //============================================================================ 166 167 void writeContentsAsHtml(Writer device, int padding, int depth) throws IOException 168 { 169 device.write(displayText); 170 } 171 172 //============================================================================ 173 // CONVENIENCE METHODS 174 //============================================================================ 175 176 /** 177 * Returns <i>true</i> if this anchor has a non-<i>null</i> value for the 178 * <tt>HTML.Attribute.NAME</tt> type. 179 * 180 * @return 181 * <i>true</i> if this anchor has a non-<i>null</i> name. 182 */ 183 public boolean hasName() 184 { 185 return getAttributeValue(HTML.Attribute.NAME) != null; 186 } 187 188 /** 189 * Returns the name of this anchor, if any. If this anchor has no name, 190 * <i>null</i> is returned. This is a convenience method equivalent to 191 * the call <tt>getAttributeValue(HTML.Attribute.NAME)</tt>. 192 * 193 * @return 194 * the name of this anchor, or <i>null</i> if this anchor has no name. 195 */ 196 public String getName() 197 { 198 return getAttributeValue(HTML.Attribute.NAME); 199 } 200 201 /** 202 * Return <i>true</i> if this anchor has a non-<i>null</i> value for the 203 * <tt>HTML.Attribute.HREF</tt> type. 204 * 205 * @return 206 * <i>true</i> if this anchor has a non-<i>null</i> name. 207 */ 208 public boolean hasUrlText() 209 { 210 return getAttributeValue(HTML.Attribute.HREF) != null; 211 } 212 213 /** 214 * Returns the <tt>HREF</tt> value for this anchor, if any. 215 * If this anchor has no such value, <i>null</i> is returned. 216 * This is a convenience method equivalent to the call 217 * <tt>getAttributeValue(HTML.Attribute.NAME)</tt>. 218 * Beware that the text returned may be only a <i>relative</i> 219 * URL, not the entire URL. 220 * 221 * @return 222 * the href value of this anchor, 223 * or <i>null</i> if this anchor has no such value. 224 */ 225 public String getUrlText() 226 { 227 return getAttributeValue(HTML.Attribute.HREF); 228 } 229 230 //============================================================================ 231 // 232 //============================================================================ 233 234 /* 235 public static void main(String[] args) 236 { 237 HtmlAnchor anchor = HtmlAnchor.parse(args[0]); 238 239 for (String key : anchor.attributes.keySet()) 240 { 241 System.out.println("["+key + "=" + anchor.attributes.get(key) + "]"); 242 } 243 System.out.println("Display text [" + anchor.displayText + "]"); 244 System.out.println(anchor.appendTo(null).toString()); 245 System.out.println(HTML.getAttributeKey("class").toString()); 246 System.out.println(HTML.NULL_ATTRIBUTE_VALUE + ", " + HTML.NULL_ATTRIBUTE_VALUE.length()); 247 } 248 */ 249 }