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.aliteralmind.codelet.type.SourceAndOutProcessor;
017   import  com.github.aliteralmind.codelet.type.FileTextProcessor;
018   import  com.github.aliteralmind.codelet.type.ConsoleOutProcessor;
019   import  com.github.aliteralmind.codelet.type.SourceCodeProcessor;
020   import  java.nio.file.AccessDeniedException;
021   import  java.nio.file.NoSuchFileException;
022   import  static com.github.aliteralmind.codelet.CodeletBaseConfig.*;
023/**
024   <p>Generates the output for a single Codelet of any type. This class--and this entire package--knows nothing of {@code com.sun}. This is the middleman between {@code com.sun} and {@link com.github.aliteralmind.codelet.TagletOfTypeProcessor}.</p>
025
026 * @since  0.1.0
027 * @author  Copyright (C) 2014, Jeff Epstein ({@code aliteralmind __DASH__ github __AT__ yahoo __DOT__ com}), dual-licensed under the LGPL (version 3.0 or later) or the ASL (version 2.0). See source code for details. <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>
028 **/
029public class TagletProcessor  {
030//      private static final CodeletBootstrap BOOTSTRAP = CodeletBootstrap.INSTANCE;
031   private final String fullyProcessed;
032   /**
033      <p>Create a new instance. Once constructed, the taglet's output may be obtained with {@link #get() get}{@code ()}.</p>
034
035      <p>This<ol>
036         <li>If this is the first encountered codelet-taglet, this {@linkplain CodeletBootstrap loads all configuration}.</li>
037         <li>If the enclosing file is {@linkplain CodeletBaseConfig#BLACK_WHITE_LIST_TYPE black-listed}, {@link #get() get}{@code ()} is set to <code>instance.{@link com.github.aliteralmind.codelet.CodeletInstance#getFullOriginalTaglet() getFullOriginalTaglet}()</code>, and this <i><b>exits</b></i>.</li>
038         <li>Otherwise, this constructs a new {@linkplain TagletOfTypeProcessor processor}, based on the instance's {@linkplain CodeletInstance#getType() type}:<ul>
039            <li>{@link com.github.aliteralmind.codelet.type.SourceCodeProcessor#SourceCodeProcessor(CodeletInstance) type.SourceCodeProcessor}</li>
040            <li>{@link com.github.aliteralmind.codelet.type.ConsoleOutProcessor#ConsoleOutProcessor(CodeletInstance) type.ConsoleOutProcessor}</li>
041            <li>{@link com.github.aliteralmind.codelet.type.FileTextProcessor#FileTextProcessor(CodeletInstance) FileTextProcessor}</li>
042            <li>{@link com.github.aliteralmind.codelet.type.SourceAndOutProcessor#SourceAndOutProcessor(CodeletInstance) SourceAndOutProcessor}</li>
043         </ul>and sets {@code get()} to its {@linkplain TagletOfTypeProcessor#getFullyCustomizedOutput() fully-customized text}.</li>
044      </ol></p>
045
046    * @param  instance  May not be {@code null}.
047    * @exception  IllegalStateException  If {@code instance} is of an unknown type (this is protection against a new type being added).
048    * @exception  ClassNotFoundException  Depending on the tag being used, and its format, if:<ul>
049         <li>The example class specified in the taglet does not exist (according to <code>{@link java.lang.Class Class}.{@link java.lang.Class#forName(String) forName}</code>)</li>
050         <li>The <i>explicitly specified</i> customizer class does not exist.</li>
051      </ul>
052    * @exception  NoSuchMethodException  If the customizer function does not exist, either in the explicitly specified or <a href="CustomizationInstructions.html#specifications">default classes</a>, or does not meet its requirements.
053    * @exception  NoSuchFileException  If the source-code or plain-text file does not exist.
054    * @exception  AccessDeniedException  If the file exists, but cannot be read.
055    */
056   public TagletProcessor(CodeletInstance instance) throws ClassNotFoundException, NoSuchMethodException, NoSuchFileException, AccessDeniedException, InterruptedException  {
057
058      if(!CodeletBootstrap.wasLoaded())  {
059         throw  new IllegalStateException("CodeletBootstrap.wasLoaded() is false.");
060      }
061
062      if(isDebugOn(instance, "zzTagletProcessor.codeletfound"))  {
063         debugln("Codelet found: " + instance);
064      }
065
066      if(!getBlackWhiteList().doAccept(instance.getEnclosingFullyQualifiedName()))  {
067         if(isDebugOn(instance, "zzTagletProcessor.codeletblacklisted"))  {
068            debugln("   Codelet blacklisted: " + instance);
069         }
070         fullyProcessed = "<i>[CODELET-BLACKLISTED]-</i>" + instance.getFullOriginalTaglet();
071         return;
072      }
073
074      TagletOfTypeProcessor<?> processor = null;
075      try  {
076         if(instance.getType().isSourceCode())  {
077            processor = new SourceCodeProcessor(instance);
078         }  else if(instance.getType().isConsoleOut())  {
079            processor = new ConsoleOutProcessor(instance);
080         }  else if(instance.getType().isFileText())  {
081            processor = new FileTextProcessor(instance);
082         }  else if(instance.getType().isSourceAndOut())  {
083            processor = new SourceAndOutProcessor(instance);
084         }  else  {
085            throw  new IllegalStateException("Unknown taglet type: " + instance.getType().getName());
086         }
087      }  catch(Exception x)  {
088         throw  new RuntimeException("Attempting to process taglet: " + instance.toString(), x);
089      }
090
091      fullyProcessed = processor.getFullyCustomizedOutput();
092
093      getDebugAptr().flushRtx();
094   }
095   /**
096      <p>Get the taglet's already-rendered output text.</p>
097
098    * @return  <code><i>[the-{@link com.github.aliteralmind.codelet.TagletOfTypeProcessor processor}]</i>.{@link com.github.aliteralmind.codelet.TagletOfTypeProcessor#getFullyCustomizedOutput() getFullyCustomizedOutput}()</code>
099    * @see  #TagletProcessor(CodeletInstance)
100    */
101   public String get()  {
102      return  fullyProcessed;
103   }
104}