001/*license*\ 002 Codelet: Copyright (C) 2014, Jeff Epstein (aliteralmind __DASH__ github __AT__ yahoo __DOT__ com) 003 004 This software is dual-licensed under the: 005 - Lesser General Public License (LGPL) version 3.0 or, at your option, any later version; 006 - Apache Software License (ASL) version 2.0. 007 008 Either license may be applied at your discretion. More information may be found at 009 - http://en.wikipedia.org/wiki/Multi-licensing. 010 011 The text of both licenses is available in the root directory of this project, under the names "LICENSE_lgpl-3.0.txt" and "LICENSE_asl-2.0.txt". The latest copies may be downloaded at: 012 - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 013 - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 014\*license*/ 015package com.github.aliteralmind.codelet; 016 import com.github.xbn.lang.CrashIfObject; 017 import com.github.xbn.util.EnumUtil; 018/** 019 <p>The type of a single JavaDoc codelet instance.</p> 020 021 * @author Copyright (C) 2014, Jeff Epstein, released under the LPGL 2.1. <a href="http://codelet.aliteralmind.com">{@code http://codelet.aliteralmind.com}</a>, <a href="https://github.com/aliteralmind/codelet">{@code https://github.com/aliteralmind/codelet}</a> 022 **/ 023public enum CodeletType { 024 /** 025 <p>{@code {@.codelet}}: A taglet that displays the example code's source code.</p> 026 027 <p>This sets<ol> 028 <li>{@link #getName() getName}{@code ()} to {@code ".codelet"}</li> 029 <li>{@link #getDefaultLineProcNamePrefix() getDefaultLineProcNamePrefix}{@code ()} to {@code "getSourceConfig_"}</li> 030 </ol></p> 031 032 <h3>{@code {@.codelet}}: Format</h3> 033 034 <p><code>{@.codelet <i>fully.qualified.ClassName</i>[:<a href="CustomizationInstructions.html#overview">customizerFunction</a>()]}</code></p> 035 036 <p>The customizer portion is optional, but when provided, must be preceded by a {@linkplain CodeletInstance#CUSTOMIZER_PREFIX_CHAR percent sign} ({@code '%'}).</p> 037 038 <p><b>Examples:</b></p> 039 040<blockquote>{@code {@.codelet fully.qualified.examples.ExampleClassName}}</blockquote> 041 042 <p>Prints out all lines in (assuming Windows) 043 <br/> {@code fully\qualified\examples\ExampleClassName.java} 044 <br/>Where {@code "fully"} is in the {@linkplain CodeletBaseConfig#EXAMPLE_CLASS_SRC_BASE_DIR example-code base directory} as configured.</p> 045 046<blockquote><code>{@.codelet fully.qualified.examples.ExampleClassName:{@link com.github.aliteralmind.codelet.BasicCustomizers#lineRange(CodeletInstance, CodeletType, Integer, Boolean, String, Integer, Boolean, String, String) lineRange}(1, false, "text in start line", 1, false, "text in end line")}</code></blockquote> 047 048 <p>Same as above, but only displays a <a href="{@docRoot}/overview-summary.html#xmpl_snippet">portion</a> of the lines, starting and ending with lines that contain specific text (inclusive).</p> 049 050 * @see #CONSOLE_OUT 051 * @see #SOURCE_AND_OUT 052 * @see #FILE_TEXT 053 * @see #isSourceCode() 054 * @see com.github.aliteralmind.codelet.type.SourceCodeProcessor 055 * @see com.github.aliteralmind.codelet.type.SourceCodeTemplate 056 * @see com.github.aliteralmind.codelet.CodeletBaseConfig#DEFAULT_SRC_CODE_TMPL_PATH CodeletBaseConfig#DEFAULT_SRC_CODE_TMPL_PATH 057 */ 058 SOURCE_CODE(".codelet", "getSourceConfig_"), 059 //The value of the second parameter ("getSourceConfig_") must be the 060 //same for both SOURCE_CODE and SOURCE_AND_OUT 061 /** 062 <p>{@code {@.codelet.out}}: A taglet that displays the example code's console output (via <code>java.lang.{@link java.lang.System System}.{@link java.lang.System#out out}</code>).</p> 063 064 <p>This sets<ol> 065 <li>{@link #getName() getName}{@code ()} to {@code ".codelet.out"}</li> 066 <li>{@link #getDefaultLineProcNamePrefix() getDefaultLineProcNamePrefix}{@code ()} to {@code "getConsoleOutConfig_"}</li> 067 </ol></p> 068 069 <h3>{@code {@.codelet.out}}: Format</h3> 070 071 <p><code>{@.codelet.out <i>fully.qualified.ClassName</i>[("Command line params", false, -1)][:<a href="CustomizationInstructions.html#overview">customizerFunction</a>()]}</code></p> 072 073 <p><ul> 074 <li>The command-line parameters are optional. When not provided, an empty string array is passed to the example-code's <a href="http://docs.oracle.com/javase/tutorial/getStarted/application/index.html#MAIN">{@code main} function</a>. When provided, it must be formatted as specified by 075 <br/> <code>com.github.xbn.util.{@link com.github.aliteralmind.codelet.simplesig.SimpleMethodSignature SimpleMethodSignature}.{@link com.github.aliteralmind.codelet.simplesig.SimpleMethodSignature#newFromStringAndDefaults(Class, Object, String, Class[], Appendable) newFromStringAndDefaults}</code> 076 <li>The customizer portion is optional.</li> 077 </ul></p> 078 079 <p><b>Examples:</b></p> 080 081<blockquote>{@code {@.codelet.out fully.qualified.examples.ExampleClassName}}</blockquote> 082 083 <p>ReplacedInEachInput the taglet with the entire console output.</p> 084 085<blockquote>{@code {@.codelet fully.qualified.examples.ExampleClassName("command", -1, "line", true, "params")}}</blockquote> 086 087 <p>Same as above, but passes a five-element string array to the main function.</p> 088 089 * @see #SOURCE_CODE 090 * @see #isConsoleOut() 091 * @see com.github.aliteralmind.codelet.type.ConsoleOutProcessor 092 * @see com.github.aliteralmind.codelet.type.ConsoleOutTemplate 093 * @see com.github.aliteralmind.codelet.CodeletBaseConfig#DEFAULT_SRC_CODE_TMPL_PATH CodeletBaseConfig#DEFAULT_SRC_CODE_TMPL_PATH 094 */ 095 CONSOLE_OUT(".codelet.out", "getConsoleOutConfig_"), 096 /** 097 <p>{@code {@.codelet.and.out}}: A taglet that displays the example code's source code and console output.</p> 098 099 <p>This sets<ol> 100 <li>{@link #getName() getName}{@code ()} to {@code ".codelet.and.out"}</li> 101 <li>{@link #getDefaultLineProcNamePrefix() getDefaultLineProcNamePrefix}{@code ()} to {@code "getSourceConfig_"}</li> 102 </ol></p> 103 104 <h3>{@code {@.codelet.and.out}}: Format</h3> 105 106 <p><code>{@.codelet.and.out <i>fully.qualified.ClassName</i>[("Command line params", false, -1)][:customizerFunction()]}</code></p> 107 108 <p>See the format requirements for both {@link #SOURCE_CODE {@.codelet}} and {@link #CONSOLE_OUT {@.codelet.out}} for examples.</p> 109 110<blockquote>{@code {@.codelet.and.out fully.qualified.examples.ExampleClassName("command", -1, "line", true, "params"):customizerFunction()}}</blockquote></p> 111 112 <p>is essentially equal to</p> 113 114<blockquote>{@code {@.codelet fully.qualified.examples.ExampleClassName:customizerFunction()}{@.codelet.out fully.qualified.examples.ExampleClassName("command", -1, "line", true, "params")}}</blockquote></p> 115 116 <p>A customizer in a {@code {@.codelet.and.out}} taglet is only applied to the source code. To also customize the output, use</p> 117 118 <P style="font-size: 125%;"><b><code>{@.codelet com.github.aliteralmind.codelet.examples.adder.AdderDemo%customizerForSourceCode()} 119 <br/>{@.codelet.out com.github.aliteralmind.codelet.examples.adder.AdderDemo%customizerForOutput()}</code></b></p> 120 121 * @see #SOURCE_CODE 122 * @see #isSourceAndOut() 123 * @see com.github.aliteralmind.codelet.type.SourceAndOutProcessor 124 * @see com.github.aliteralmind.codelet.type.SourceAndOutTemplate 125 * @see com.github.aliteralmind.codelet.CodeletBaseConfig#DEFAULT_AND_OUT_TMPL_PATH CodeletBaseConfig#DEFAULT_SRC_CODE_TMPL_PATH 126 */ 127 SOURCE_AND_OUT(".codelet.and.out", "getSourceConfig_"), 128 //The value of the second parameter ("getSourceConfig_") must be the 129 //same for both SOURCE_CODE and SOURCE_AND_OUT 130 /** 131 <p>{@code {@.file.textlet}}: A taglet that displays the contents of a plain text file.</p> 132 133 <p>This sets<ol> 134 <li>{@link #getName() getName}{@code ()} to {@code ".file.textlet"}</li> 135 <li>{@link #getDefaultLineProcNamePrefix() getDefaultLineProcNamePrefix}{@code ()} to {@code "getFileTextConfig_"}</li> 136 </ol></p> 137 138 <h3>{@code {@.file.textlet}}: Format</h3> 139 140 <p><code>{@.file.textlet <i>path\to\file.txt</i>[:<a href="CustomizationInstructions.html#overview">customizerFunction</a>()]}</code></p> 141 142 <p>Replaced with all lines in a plain-text file, such as for displaying an example code's input. The <b>customizer function</b> is optional. The <b>path</b> may be<ul> 143 <li><a href="http://docs.oracle.com/javase/tutorial/essential/io/path.html#relative">absolute</a>,</li> 144 <li>relative to the directory in which {@code javadoc.exe} was invoked, or,</li> 145 <li>relative to the directory of the taglet's {@linkplain CodeletInstance#getEnclosingFile() enclosing file}.</li> 146 </ul>This list also represents the order in which the search occurs.</p> 147 148 <p><i>(New for version {@code 0.1.3}):</i> Absolute paths must contain the <a href="http://en.wikipedia.org/wiki/Path_(computing)#Representations_of_paths_by_operating_system_and_shell">file separators exactly as required by your system</a> (such as {@code "C:\directory\subdir\file.txt"}). Otherwise all <i>single</i> url-slashes ({@code '/'}) used as file separators are changed to</p> 149 150<blockquote><pre>{@link java.lang.System}.{@link java.lang.System#getProperty(String) getProperty}("file.separator", "\\")</pre></blockquote> 151 152 <p>For example, on Microsoft Windows, {@code "java_code/input.txt"} is changed to {@code "java_code\input.txt"}.</p> 153 154 <p>A single environment variable may be used to prefix the path. For example:</p> 155 156<blockquote><pre>$<base_directory>/filelets/input.txt</pre></blockquote> 157 158 <p>When used, it is required that the first two characters in the path are <code>"$<"</code>, followed by the environment variable name, followed by a close sharp (<code>'>'</code>). This environment variable, as returned by <i>either</i></p> 159 160<blockquote><pre>{@link java.lang.System}.{@link java.lang.System#getProperty(String) getProperty}("base_directory")</pre></blockquote> 161 162or 163 164<blockquote><pre>System.{@link java.lang.System#getenv(String) getenv}("base_directory")</pre></blockquote> 165 166 <p>must be a non-null, non-empty value, and be either a system property or environment variable--not both. <i>(New for version {@code 0.1.3}, the idea from Stack Overflow user <a href="http://stackoverflow.com/users/3622940/unihedron">Unihedron</a>.)</i></p> 167 168 * @see #SOURCE_CODE 169 * @see #isFileText() 170 * @see com.github.aliteralmind.codelet.type.FileTextProcessor 171 * @see com.github.aliteralmind.codelet.type.FileTextTemplate 172 * @see com.github.aliteralmind.codelet.CodeletBaseConfig#DEFAULT_FILE_TEXT_TMPL_PATH CodeletBaseConfig#DEFAULT_FILE_TEXT_TMPL_PATH 173 */ 174 FILE_TEXT(".file.textlet", "getFileTextConfig_"); 175 176 private final String tagName; 177 private final String defaultLineProcNamePrefix; 178 /** 179 <p>Construct an {@code CodeletType}.</p> 180 181 * @param tag_name The name of the codelet. <i>Should</i> not be {@code null} or empty. Get with {@link #getName() getName}{@code ()} 182 * @param default_lineProcNamePrefix The default prefix for Customizers of this type. <i>Should</i> not be {@code null} or empty, and should end with an underscore ({@code '_'}). Get with {@link #getDefaultLineProcNamePrefix() getDefaultLineProcNamePrefix}{@code ()}. 183 * @see #SOURCE_CODE 184 */ 185 CodeletType(String tag_name, String default_lineProcNamePrefix) { 186 tagName = tag_name; 187 defaultLineProcNamePrefix = default_lineProcNamePrefix; 188 } 189 /** 190 <p>The {@linkplain com.sun.javadoc.Tag#name() name} of this taglet, as used in JavaDoc.</p> 191 192 * @return For example, if the taglet is 193 <br/> {@code {@.codelet.out my.package.examples.AnExample}} 194 <br/>this returns {@code ".codelet.out"}</p> 195 * @see #newTypeForTagletName(String, String) newTypeForTagletName(s,s) 196 */ 197 public String getName() { 198 return tagName; 199 } 200 /** 201 <p>The default prefix for Customizers of this type.</p> 202 203 <p>This is intended to be followed by either the example classes {@linkplain java.lang.Class#getSimpleName() simple name}, or the <i>explicitely-provided</i> function-name-postfix for the plain-text file being displayed.</p> 204 */ 205 public String getDefaultLineProcNamePrefix() { 206 return defaultLineProcNamePrefix; 207 } 208 /** 209 <p>Is this {@code CodeletType} equal to {@code SOURCE_CODE}?.</p> 210 211 * @return <code>this == {@link #SOURCE_CODE}</code> 212 213 * @see #isConsoleOut() 214 * @see #isFileText() 215 * @see #isSourceAndOut() 216 */ 217 public final boolean isSourceCode() { 218 return this == SOURCE_CODE; 219 } 220 /** 221 <p>Is this {@code CodeletType} equal to {@code CONSOLE_OUT}?.</p> 222 223 * @return <code>this == {@link #CONSOLE_OUT}</code> 224 * @see #isSourceCode() 225 */ 226 public final boolean isConsoleOut() { 227 return this == CONSOLE_OUT; 228 } 229 /** 230 <p>Is this {@code CodeletType} equal to {@code FILE_TEXT}?.</p> 231 232 * @return <code>this == {@link #FILE_TEXT}</code> 233 * @see #isSourceCode() 234 */ 235 public final boolean isFileText() { 236 return this == FILE_TEXT; 237 } 238 /** 239 <p>Is this {@code CodeletType} equal to {@code SOURCE_AND_OUT}?.</p> 240 241 * @return <code>this == {@link #SOURCE_AND_OUT}</code> 242 * @see #isSourceCode() 243 */ 244 public final boolean isSourceAndOut() { 245 return this == SOURCE_AND_OUT; 246 } 247 248 /** 249 <p>If an <code>CodeletType</code> is not a required value, crash.</p> 250 251 * <p>Equal to 252 <br/> <code>{@link com.github.xbn.util.EnumUtil EnumUtil}.{@link com.github.xbn.util.EnumUtil#crashIfNotRequiredValue(Enum, Enum, String, Object) crashIfNotRequiredValue}(this, e_rqd, s_thisEnumsVarNm, o_xtraInfo)</code></p> 253 * @see #crashIfForbiddenValue(CodeletType, String, Object) crashIfForbiddenValue(ert,s,o) 254 */ 255 public void crashIfNotRequiredValue(CodeletType e_rqd, String s_thisEnumsVarNm, Object o_xtraInfo) { 256 EnumUtil.crashIfNotRequiredValue(this, e_rqd, s_thisEnumsVarNm, o_xtraInfo); 257 } 258 /** 259 <p>If an <code>CodeletType</code> is a forbidden value, crash.</p> 260 261 * <p>Equal to 262 <br/> <code>{@link com.github.xbn.util.EnumUtil EnumUtil}.{@link com.github.xbn.util.EnumUtil#crashIfForbiddenValue(Enum, Enum, String, Object) crashIfForbiddenValue}(this, e_rqd, s_thisEnumsVarNm, o_xtraInfo)</code></p> 263 * @see #crashIfNotRequiredValue(CodeletType, String, Object) crashIfNotRequiredValue(ert,s,o) 264 */ 265 public void crashIfForbiddenValue(CodeletType e_rqd, String s_thisEnumsVarNm, Object o_xtraInfo) { 266 EnumUtil.crashIfForbiddenValue(this, e_rqd, s_thisEnumsVarNm, o_xtraInfo); 267 } 268 /** 269 <p>Is a string equal to <i>this</i> taglet type's name?.</p> 270 271 * @param name May not be {@code null}. 272 * @return <code>name.equals({@link #getName() getName}())</code> 273 */ 274 public boolean isNameEqualTo(String name) { 275 return isNameEqualTo(name, "name"); 276 } 277 private boolean isNameEqualTo(String name, String name_varName) { 278 try { 279 return name.equals(getName()); 280 } catch(RuntimeException rx) { 281 throw CrashIfObject.nullOrReturnCause(name, name_varName, null, rx); 282 } 283 } 284 /** 285 <p>Get a new {@code CodeletType} whose name is equal to a string value.</p> 286 287 * @param name The name, which must be non-{@code null}, and equal to a type's {@link #getName() getName}{@code ()}. 288 * @param name_varName Descriptive name of the {@code name} parameter, for the potential error message. <i>Should</i> not be {@code null} or empty. 289 * @exception IllegalArgumentException If {@code name} is not equal to a known codelet type. 290 */ 291 public static final CodeletType newTypeForTagletName(String name, String name_varName) { 292 if(CodeletType.SOURCE_CODE.isNameEqualTo(name, name_varName)) { 293 return CodeletType.SOURCE_CODE; 294 } 295 if(CodeletType.CONSOLE_OUT.isNameEqualTo(name, name_varName)) { 296 return CodeletType.CONSOLE_OUT; 297 } 298 if(CodeletType.FILE_TEXT.isNameEqualTo(name, name_varName)) { 299 return CodeletType.FILE_TEXT; 300 } 301 if(CodeletType.SOURCE_AND_OUT.isNameEqualTo(name, name_varName)) { 302 return CodeletType.SOURCE_AND_OUT; 303 } 304 305 throw new IllegalArgumentException(name_varName + " (\"" + name + "\") is not CodeletType.SOURCE_CODE.getName() (\"" + CodeletType.SOURCE_CODE.getName() + "\"), CodeletType.CONSOLE_OUT.getName() (\"" + CodeletType.CONSOLE_OUT.getName() + "\"), CodeletType.FILE_TEXT.getName() (\"" + CodeletType.FILE_TEXT.getName() + "\"), or CodeletType.SOURCE_AND_OUT.getName() (\"" + CodeletType.SOURCE_AND_OUT.getName() + "\")"); 306 } 307};