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.type; 016 import java.nio.file.InvalidPathException; 017 import java.nio.file.Path; 018 import java.nio.file.Paths; 019 import com.github.xbn.io.PathMustBe; 020 import com.github.aliteralmind.codelet.CodeletFormatException; 021 import com.github.aliteralmind.codelet.CodeletInstance; 022 import com.github.aliteralmind.codelet.CodeletType; 023 import com.github.aliteralmind.codelet.CustomizationInstructions; 024 import com.github.aliteralmind.codelet.TagletOfTypeProcessor; 025 import com.github.aliteralmind.codelet.TagletTextUtil; 026 import com.github.xbn.io.PlainTextFileUtil; 027 import java.nio.file.AccessDeniedException; 028 import java.nio.file.NoSuchFileException; 029 import java.util.Iterator; 030 import static com.github.aliteralmind.codelet.CodeletBaseConfig.*; 031 import static com.github.xbn.lang.XbnConstants.*; 032/** 033 <P>Reads a {@link com.github.aliteralmind.codelet.CodeletType#FILE_TEXT {@.file.textlet}} taglet and outputs its replacement text.</P> 034 035 @since 0.1.0 036 @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> 037 **/ 038public class FileTextProcessor extends TagletOfTypeProcessor<FileTextTemplate> { 039 /** 040 <P>Create a new instance from an {@code CodeletInstance}.</P> 041 042 <P>Equal to <CODE>{@link com.github.aliteralmind.codelet.TagletOfTypeProcessor#TagletOfTypeProcessor(CodeletType, CodeletInstance) super}(CodeletType.FILE_TEXT, instance)</CODE> 043 **/ 044 public FileTextProcessor(CodeletInstance instance) throws ClassNotFoundException, NoSuchMethodException, NoSuchFileException, AccessDeniedException { 045 super(CodeletType.FILE_TEXT, instance); 046 047 if(getClassOrFilePortion().contains("(")) { 048 throw new CodeletFormatException(instance, "File-text taglets cannot contain command-line parameters"); 049 } 050 051 Iterator<String> fileTextLineItr = getLineIteratorFromCodeletPath(instance); 052 053// String strSig = getStringSigForFileText(); 054// SimpleMethodSignature sig = getCustomizerSigFromString(strSig); 055 056 CustomizationInstructions<FileTextTemplate> instructions = 057 ((getCustomizerPortion() != null) 058 ? getCustomCustomizationInstructions(CodeletType.FILE_TEXT) 059 : newInstructionsForDefaults( 060 new CustomizationInstructions<FileTextTemplate>(instance, CodeletType.FILE_TEXT))); 061 062 crashIfClassOrFileCannotUseCustomizer(instructions); 063 064 String fileTextCustomized = instructions.getCustomizedBody(instance, fileTextLineItr); 065 066 FileTextTemplate template = getTemplateFromInstructionsOverrideOrDefault( 067 instructions); 068 069 String finalOutput = template.fillBody(fileTextCustomized).getRendered(instance); 070 setFullyProcessedOutput(finalOutput); 071 } 072 private final Iterator<String> getLineIteratorFromCodeletPath(CodeletInstance instance) { 073 074 boolean doDebug = isDebugOn(instance, "zzFileTextProcessor.obtainingfile"); 075 076 //See CodeletInstance.FILE_TEXT 077 078 if(doDebug) { 079 debugln("Obtaining line iterator to {@.file.textlet} file (expected file-separator is '" + FILE_SEP + "')..."); 080 debugln(" - Raw file path from {@.file.textlet}: " + getClassOrFilePortion()); 081 debugln(" - TagletTextUtil.getFilePath(instance): " + TagletTextUtil.getFilePath(instance)); 082 } 083 084 Path path = Paths.get(TagletTextUtil.getFilePath(instance)); 085 086 PathMustBe pmb = new PathMustBe().existing().readable(); 087// String namePost = "TagletTextUtil.getFilePath(instance)]"; 088 089 //First assume absolute. This also works if the path is relative to 090 //the directory in which javadoc.exe was invoked. 091 092 if(pmb.isGood(path)) { 093 if(doDebug) { 094 debugln(" SUCCESS: Path is either absolute, or relative to the directory in which javadoc.exe was invoked."); 095 } 096 097 return PlainTextFileUtil.getLineIterator(path.toString(), "[path to file]"); 098 } 099 100 //It's not absolute or relative to the invoking directory. 101 //It must be relative to the enclosing file, or die. 102 103 String parentPath = instance.getEnclosingFile().getParent(); 104 105 if(!parentPath.endsWith(FILE_SEP)) { 106 parentPath += FILE_SEP; 107 } 108 109 if(doDebug) { 110 debugln(" Path to file is not absolute, and not relative to the javadoc.exe-invoking directory. It MUST be relative to the directory of its enclosing file:"); 111 debugln(" - File: " + instance.getEnclosingFile()); 112 debugln(" - Parent: " + parentPath); 113 } 114 115 try { 116 path = Paths.get(parentPath, path.toString()); 117 } catch(InvalidPathException ipx) { 118 throw new InvalidPathException(parentPath + path.toString(), "{@.file.textlet} path is invalid. Not absolute, not relative to javadoc.exe invoking directory, and not relative to enclosing file"); 119 } 120 121 return PlainTextFileUtil.getLineIterator(path.toString(), "[path to {@.file.textlet} file]"); 122 } 123 /** 124 <P>Get the string signature for a {@code {@.file.textlet}} taglets only. Except where noted, this does not validate the taglet text or the returned signature.</P> 125 126 <P>This follows the same steps as {@link com.github.aliteralmind.codelet.TagletOfTypeProcessor#getStringSignature() getStringSignature}, except<UL> 127 <LI>The customizer portion of the taglet, when provided, must contain either an underscore ({@code '_'}) postfix or the processor's full function name.</LI> 128 <LI>The {@linkplain com.github.aliteralmind.codelet.CodeletType#getDefaultLineProcNamePrefix() default function name prefix} is {@code "getFileTextConfig_"}</LI> 129 </UL></P> 130 131 @exception CodeletFormatException If no function name or underscore-postfix is provided. 132 **/ 133 public String getStringSigForFileText() { 134 String sig = getCustomizerPortion(); 135 136 boolean doDebug = isDebugOn(getInstance(), 137 "zzTagletOfTypeProcessor.getCustomizerSigFromString"); 138 139 if(sig == null) { 140 if(doDebug) { 141 debugln(" No Customizer"); 142 } 143 return null; 144 } 145 146 if(sig.equals("()")) { 147 throw new CodeletFormatException(getInstance(), "Customizer portion for a " + CodeletType.FILE_TEXT.getName() + " taglet is equal to \"()\". The processor's function name or underscore-postfix must be specified."); 148 } 149 150 return getSig2PrnsApnddForNameOrPostfix("", sig, doDebug); 151 } 152}