001package Torello.HTML; 002 003import java.util.regex.*; 004 005import Torello.HTML.HelperPackages.TagNode.AttrRegEx; 006 007/** 008 * This occurs whenever a parameter specifies an Inner-Tag 009 * <B STYLE="color: red;">"Key-Value Pair"</B> (which, in this package, are <I>also known 010 * as</I> Attribute-<B STYLE="color: red;">Value</B> Pairs) that contain inappropriate characters 011 * inside the {@code key-String}. 012 * 013 * <BR /><BR /><B CLASS=JDDescLabel>Reg-Ex Rules:</B> 014 * 015 * <BR />All matching HTML Element Attributes must have attribute-<B STYLE="color: red;">names</B> 016 * (inner-tags) whose nomenclature conforms to this regular-expression: {@code [A-Za-z][\w-]+}. 017 * 018 * <BR /><BR />All this says is that attribute-<B STYLE="color: red;">names</B> <I>must begin with 019 * an alphabetic character</I>, and then the characters that follow must be "regular-expression" 020 * {@code word-characters '\w'}. 021 * 022 * <BR /><BR />In a regular-expression, the characters that match a {@code \w} include the letters 023 * {@code A-Z}, the (lower-case) letters {@code a-z}, the digits {@code 0-9}, and the underscore 024 * {@code '_'}. The minus-sign {@code '-'} may also be used in an 025 * attribute-<B STYLE="color: red;">name</B><I> (it just may not be the first character used in an 026 * attribute-<B STYLE="color: red;">name</B>)</I>. 027 * 028 * <DIV CLASS="EXAMPLE">{@code 029 * <IMG SRC="http://example.com/pic.jpg"> 030 * <DIV data-id="this is example data"> 031 * }</DIV> 032 * 033 * <BR />For the above two examples, both the {@code 'SRC'} attribute-name (key-name) and the 034 * {@code 'data-id'} key-<B STYLE="color: red;">name</B> are legitimately named. No exceptions 035 * would be thrown if a programmer initiated a search using a string to look for an inner-tag that 036 * was named {@code 'src'} nor would there be problems using a string named {@code 'data-id'} to 037 * look for the <B STYLE="color: red;">value</B> of {@code data-id} above. 038 * 039 * <DIV CLASS=EXAMPLE>{@code 040 * Properties p = new java.util.Properties(); 041 * p.put("My Attribute Value", "data 1"); 042 * p.put("123Attribute", "data 2"); 043 * p.put("SpecialChars!@#$%", "data 3"); 044 * TagNode tn = new TagNode("DIV", p, SD.DoubleQuotes, false); 045 * }</DIV> 046 * <BR />An {@code InnerTagKeyException} would be generated <I>for all three cases!</I> Each of 047 * the above inner-tag <B STYLE="color: red;">key-value pairs</B> have 048 * key-<B STYLE="color: red;">names</B> with illegal characters. 049 * 050 * <BR /><BR /><B CLASS=JDDescLabel>Specifically:</B> 051 * 052 * <BR /><BR /><UL CLASS=JDUL> 053 * <LI>Attribute-Value Pair 1: The key-<B STYLE="color: red;">name</B> contains a space.</LI> 054 * <LI>Attribute-Value Pair 2: The key-<B STYLE="color: red;">name</B> begins with a number.</LI> 055 * 056 * <LI> Attribute-Value Pair 3: The key-<B STYLE="color: red;">name</B> has invalid, 057 * non-alpha-numeric 058 * characters! 059 * </LI> 060 * 061 * </UL> 062 * 063 * <BR />If a search were made using an inner-tag (attribute-<B STYLE="color: red;">name</B>)using 064 * a {@code String} that did not meet these criteria, an {@code InnerTagKeyException} would be 065 * thrown. 066 * 067 */ 068public class InnerTagKeyException extends IllegalArgumentException 069{ 070 /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUIDEX> */ 071 public static final long serialVersionUID = 1; 072 073 /** Constructs an {@code InnerTagKeyException} with no detail message. */ 074 public InnerTagKeyException() 075 { super(); } 076 077 /** 078 * Constructs an {@code InnerTagKeyException} with the specified detail message. 079 * @param message the detail message. 080 */ 081 public InnerTagKeyException(String message) 082 { super(message); } 083 084 /** 085 * Constructs a new exception with the specified detail message and cause. 086 * 087 * <BR /><BR /><B CLASS=JDDescLabel>NOTE:</B> 088 * 089 * <BR /><BR />The detail message associated with cause is not automatically incorporated into 090 * this exception's detail message. 091 * 092 * @param message The detail message (which is saved for later retrieval by the 093 * {@code Throwable.getMessage()} method). 094 * 095 * @param cause the cause (which is saved for later retrieval by the 096 * {@code Throwable.getCause()} method). (A null value is permitted, and indicates that the 097 * cause is nonexistent or unknown). 098 */ 099 public InnerTagKeyException(String message, Throwable cause) 100 { super(message, cause); } 101 102 /** 103 * Constructs a new exception with the specified cause and a detail message of 104 * {@code (cause==null ? null : cause.toString())} (which typically contains the class and 105 * detail message of cause). 106 * 107 * This constructor is useful for exceptions that are little more than wrappers for other 108 * throwables. 109 * 110 * @param cause The cause (which is saved for later retrieval by the 111 * {@code Throwable.getCause()} method). (A null value is permitted, and indicates that the 112 * cause is nonexistent or unknown.) 113 */ 114 public InnerTagKeyException(Throwable cause) 115 { super(cause); } 116 117 /** 118 * This verifies that any Java-{@code String} that is intended to be use as an inner-tag 119 * conforms to the right rules. If a problem is found, then an {@code InnerTagKeyException} or 120 * {@code NullPointerException} is thrown. 121 * 122 * @param keys One or many HTML-Inner-Tag to be checked for use as an HTML-Attribute 123 * <B STYLE="color: red;">name</B> 124 * 125 * @throws InnerTagKeyException If any {@code String} does not match the {@code CHECK_KEY} 126 * Regular-Expression {@code Pattern}. 127 * 128 * @throws NullPointerException If any of the attributes / inner-tag 129 * <B STYLE="color: red;">keys</B> passed are null. 130 */ 131 public static void check(String... keys) 132 { 133 for (String key : keys) 134 135 if (key == null) throw new NullPointerException( 136 "You have passed a null as an Attribute-Name (also known as an " + 137 "'InnerTag-Key Name'), but this is not allowed." 138 ); 139 140 else if (! AttrRegEx.ATTRIBUTE_KEY_REGEX.matcher(key).find()) 141 throw new InnerTagKeyException 142 ("Inner-tag key has invalid characters: [" + key + ']'); 143 } 144 145 /** 146 * This method is <B>identical</B> to the <B>{@code public static void check(key);}</B>, except 147 * it allows the programmer to add the <B STYLE="color: red;">key-value pair</B> to the 148 * Exception's error message. No change to the code is present, except the exception's error 149 * message. 150 * 151 * @param key Any HTML-Inner-Tag <B STYLE="color: red;">name</B>to be checked for use as an 152 * HTML-Attribute 153 * 154 * @param value This is the <B STYLE="color: red;">value</B> taken by this 155 * <B STYLE="color: red;">key</B>, it is included for error-logging only, but it is not 156 * checked. 157 * 158 * @throws InnerTagKeyException If this class does not match the {@code CHECK_KEY} 159 * Regular-Expression {@code Pattern}, than it throws. 160 */ 161 public static void check(String key, String value) 162 { 163 if (key == null) throw new NullPointerException( 164 "You have passed a null as an Attribute-Name (also known as an 'InnerTag-Key Name'), " + 165 "but this is not allowed." 166 ); 167 168 if (! AttrRegEx.ATTRIBUTE_KEY_REGEX.matcher(key).find()) 169 throw new InnerTagKeyException( 170 "The specified inner-tag key has invalid characters: [" + key + "]\n" + 171 "For Key-Value Pair: [" + key + ", " + value + "]" 172 ); 173 } 174}