001package Torello.JavaDoc; 002 003import Torello.HTML.*; 004import Torello.HTML.NodeSearch.*; 005 006import Torello.Java.StrCmpr; 007 008import java.util.*; 009 010/** 011 * Exception that may be thrown when erroneous-input is provided to internal-class 012 * <B>{@code Details}</B> or <B>{@link ReflHTML}</B>. These classes throw exceptions, rather than 013 * printing errors to the messager, since they may be called, externally, by the end-users. Those 014 * classes are not strictly limited to internal-use. 015 * 016 * @see ReflHTML 017 */ 018public class DetailsException extends IllegalArgumentException 019{ 020 /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUIDEX> */ 021 public static final long serialVersionUID = 1; 022 023 /** 024 * This is a helpful message explaining how to ensure that a sub-section of a vectorized-HTML 025 * Documentation Web-Page is properly formatted according to the 'details' section of a 026 * Java-Doc page. 027 */ 028 protected static final String PLEASE_USE = 029 "Please use the Details iterator(); Methods to retrieve a details section for a " + 030 "Method, Field, Constructor or Enumerated-Constant."; 031 032 /** 033 * This is the message used for explaining how to retrieve an iterator of the 'details' 034 * section for an Annotation Java-Doc page. 035 */ 036 protected static final String PLEASE_USE_ANNOT = 037 "Please use the Details iterator(); Methods to retrieve a details section for " + 038 "the Annotation Elements."; 039 040 /** Constructs a {@code DetailsException} with no detail message. */ 041 public DetailsException() 042 { super(); } 043 044 /** 045 * Constructs a {@code DetailsException} with the specified detail message. 046 * @param message the detail message. 047 */ 048 public DetailsException(String message) 049 { super(message); } 050 051 /** 052 * Constructs a new exception with the specified detail message and cause. 053 * 054 * <BR /><BR /><B CLASS=JDDescLabel>NOTE:</B> 055 * 056 * <BR /><BR />The detail message associated with cause is not automatically incorporated into 057 * this exception's detail message. 058 * 059 * @param message The detail message (which is saved for later retrieval by the 060 * {@code Throwable.getMessage()} method). 061 * 062 * @param cause the cause (which is saved for later retrieval by the 063 * {@code Throwable.getCause()} method). (A null value is permitted, and indicates that the 064 * cause is nonexistent or unknown.) 065 */ 066 public DetailsException(String message, Throwable cause) 067 { super(message, cause); } 068 069 /** 070 * Constructs a new exception with the specified cause and a detail message of 071 * {@code (cause==null ? null : cause.toString())} (which typically contains the class and 072 * detail message of cause). 073 * 074 * <BR /><BR />This constructor is useful for exceptions that are little more than wrappers for 075 * other throwables. 076 * 077 * @param cause The cause (which is saved for later retrieval by the 078 * {@code Throwable.getCause()} method). (A null value is permitted, and indicates that the 079 * cause is nonexistent or unknown.) 080 */ 081 public DetailsException(Throwable cause) 082 { super(cause); } 083 084 /** 085 * This check method is used to ensure that a passed-parameter vectorized-HTML sub-page to one 086 * of the {@code DetailsPartMethods, DetailsPartConstructors} or {@code DetailsPartFields} is a 087 * properly formatted HTML Sub-Section. The purpose of the iterators within {@code class 088 * Details} is to retrieve the <I>individual, detailed</I> descriptions for the fields, methods 089 * and constructors from an HTML Page generated by the Java-Doc tool. This exception class will 090 * do some <I>simple, basic</I> parameter checking to ensure that the proper parameters are 091 * passed. The priority is to provide more useable and meaningful error information. 092 * 093 * @param details This is supposed to be the return value from a call to the 094 * {@code HNLIInclusive iter.next()} method. The iterator should be one returned from the 095 * {@code class Details} iterator' methods. If it was, then it should a guarantee that the 096 * section is properly formatted, because it would have been retrieved from a JavaDoc HTML 097 * page. 098 * 099 * @throws DetailsException This exception shall throw if any of the requirements of the 100 * section have not been met. 101 * 102 * @see StrCmpr 103 * @see TagNode 104 */ 105 public static void check(Vector<HTMLNode> details) 106 { 107 TagNode first = null; 108 TagNode last = null; 109 110 // Ensure that the section is not null. 111 if (details == null) throw new NullPointerException 112 ("The vectorized-HTML section vector-reference was null."); 113 114 // There should quite a number of elements in this vector, besides the beginning and 115 // ending <UL>...</UL> elements. 116 if (details.size() < 3) throw new DetailsException( 117 "The vectorized-HTML section parameter has v.size()=" + details.size() + 118 ". This is not sufficient. " + PLEASE_USE 119 ); 120 121 // All Details Elements begin with <ul class='blockList'> or <ul class='blockListLast'> 122 try 123 { first = (TagNode) details.elementAt(0); } 124 catch (ClassCastException e) 125 { 126 throw new DetailsException( 127 "This vectorized-HTML section does not begin with a TagNode element. " + 128 "It begins with [" + first.str + "]" + PLEASE_USE 129 ); 130 } 131 132 // All Details Elements end with </ul> 133 try 134 { last = (TagNode) details.elementAt(details.size() - 1); } 135 catch (ClassCastException e) 136 { 137 throw new DetailsException( 138 "This vectorized-HTML section does not end with a TagNode element. " + 139 "It ends with [" + last.str + "]" + PLEASE_USE 140 ); 141 } 142 143 // All Details Elements begin with <ul class='blockList'> or <ul class='blockListLast'> 144 if ((! first.tok.equals("ul")) || first.isClosing) 145 throw new DetailsException( 146 "The first node of the vectorized-HTML section is not an Opening <UL> Element. " + 147 "It is a [" + first.str + "]. " + PLEASE_USE 148 ); 149 150 // All Details Elements end with </ul> 151 if ((! last.tok.equals("ul")) || (! last.isClosing)) 152 throw new DetailsException( 153 "The last node of the vectorized-HTML section is not a Closing </UL> Element. " + 154 "It is a [" + last.str + "]. " + PLEASE_USE 155 ); 156 157 // All Details Elements begin with <ul class='blockList'> or <ul class='blockListLast'> 158 if (! StrCmpr.containsOR_CI(first.AV("class"), "blockList", "blockListLast")) 159 throw new DetailsException( 160 "The first node of the vectorized-HTML section is not an Opening <UL> Element " + 161 "with 'class' attribute containing string: 'blockList' or 'blockListLast.' " + 162 "Instead it is: [" + first.str + "]." 163 ); 164 } 165 166 /** 167 * This check method is used to ensure that a passed-parameter vectorized-HTML sub-page is 168 * correct. 169 * 170 * <BR /><BR /><B STYLE='color:red;'>NOTE:</B> The Annotation-Element Details are just ever 171 * so slightly different than they are for the other four types of details (Methods, 172 * Constructors, Fields, and Enumerated-Constants). The Annotation-Element Iterator returns 173 * HTML {@code <SECTION>} elements instead! 174 * 175 * @param details This is supposed to be the return value from a call to the 176 * {@code HNLIInclusive iter.next()} method. The iterator should be one returned from the 177 * {@code class Details} methods retreiving an Annotation-Element Iterator. 178 * 179 * @throws DetailsException This exception shall throw if any of the requirements of the 180 * section have not been met. 181 * 182 * @see StrCmpr 183 * @see TagNode 184 */ 185 public static void checkAnnotation(Vector<HTMLNode> details) 186 { 187 TagNode first = null; 188 TagNode last = null; 189 190 // Ensure that the section is not null. 191 if (details == null) throw new NullPointerException 192 ("The vectorized-HTML section vector-reference was null."); 193 194 // There should quite a number of elements in this vector, besides the beginning and 195 // ending <UL>...</UL> elements. 196 if (details.size() < 3) throw new DetailsException( 197 "The vectorized-HTML section parameter has v.size()=" + details.size() + 198 ". This is not sufficient. " + PLEASE_USE 199 ); 200 201 // All Details Elements begin with <ul class='blockList'> or <ul class='blockListLast'> 202 try 203 { first = (TagNode) details.elementAt(0); } 204 catch (ClassCastException e) 205 { 206 throw new DetailsException( 207 "This vectorized-HTML section does not begin with a TagNode element. " + 208 "It begins with [" + first.str + "]" + PLEASE_USE_ANNOT 209 ); 210 } 211 212 // All Details Elements end with </ul> 213 try 214 { last = (TagNode) details.elementAt(details.size() - 1); } 215 catch (ClassCastException e) 216 { 217 throw new DetailsException( 218 "This vectorized-HTML section does not end with a TagNode element. " + 219 "It ends with [" + last.str + "]" + PLEASE_USE_ANNOT 220 ); 221 } 222 223 // All Details Elements begin with <ul class='blockList'> or <ul class='blockListLast'> 224 if ((! first.tok.equals("section")) || first.isClosing) 225 throw new DetailsException( 226 "The first node of the vectorized-HTML section is not an Opening <SECTION> " + 227 "Element. It is a [" + first.str + "]. " + PLEASE_USE_ANNOT 228 ); 229 230 // All Details Elements end with </ul> 231 if ((! last.tok.equals("section")) || (! last.isClosing)) 232 throw new DetailsException( 233 "The last node of the vectorized-HTML section is not a Closing </SECTION> " + 234 "Element. It is a [" + last.str + "]. " + PLEASE_USE_ANNOT 235 ); 236 237 // All Details Elements begin with <ul class='blockList'> or <ul class='blockListLast'> 238 if (! StrCmpr.containsOR_CI(first.AV("role"), "region")) 239 throw new DetailsException( 240 "The first node of the vectorized-HTML section is not an Opening <SECTION> " + 241 "element with 'role' attribute containing string: 'region.' " + 242 "Instead it is: [" + first.str + "]." 243 ); 244 } 245}