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>{&#64;.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/> &nbsp; &nbsp; {@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>{&#64;.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>{&#64;.codelet.out <i>fully.qualified.ClassName</i>[(&quot;Command line params&quot;, 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/> &nbsp; &nbsp; <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>{&#64;.codelet.and.out <i>fully.qualified.ClassName</i>[(&quot;Command line params&quot;, 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>{&#64;.codelet com.github.aliteralmind.codelet.examples.adder.AdderDemo%customizerForSourceCode()}
119   <br/>{&#64;.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>{&#64;.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", &quot;\\&quot;)</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>$&lt;base_directory&gt;/filelets/input.txt</pre></blockquote>
157
158      <p>When used, it is required that the first two characters in the path are <code>&quot;$&lt;&quot;</code>, followed by the environment variable name, followed by a close sharp (<code>'&gt;'</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}(&quot;base_directory&quot;)</pre></blockquote>
161
162or
163
164<blockquote><pre>System.{@link java.lang.System#getenv(String) getenv}(&quot;base_directory&quot;)</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/> &nbsp; &nbsp; {@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/> &nbsp; &nbsp; <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/> &nbsp; &nbsp; <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};