View Javadoc
1   package eu.simuline.m2latex.core;
2   
3   import java.io.File;
4   import java.util.Arrays;
5   
6   /**
7    * Describe class AbstractLatexProcessor here.
8    *
9    *
10   * Created: Thu Nov 17 12:29:36 2016
11   *
12   * @author <a href="mailto:rei3ner@arcor.de">Ernst Reissner</a>
13   * @version 1.0
14   */
15  abstract class AbstractLatexProcessor {
16  
17      // both LatexProcessor and LatexPreProcessor 
18      // LaTeX and mpost with option -recorder 
19      final static String SUFFIX_FLS = ".fls";
20      // both LatexProcessor and LatexPreProcessor 
21      // for LaTeX but also for mpost 
22      final static String SUFFIX_LOG = ".log";
23  
24      // both LatexProcessor and LatexPreProcessor 
25      final static String SUFFIX_PDF = ".pdf";
26  
27      // makeindex for glossary 
28      // needed by makeglossaries and for svg-conversion (hack) 
29      final static String SUFFIX_VOID = "";
30   
31      // both LatexProcessor and LatexPreProcessor 
32      protected final Settings settings;
33  
34      // both LatexProcessor and LatexPreProcessor 
35      protected final CommandExecutor executor;
36  
37      // both LatexProcessor and LatexPreProcessor 
38      protected final LogWrapper log;
39  
40      // both LatexProcessor and LatexPreProcessor 
41      protected final TexFileUtils fileUtils;
42  
43      /**
44       * Creates a new <code>AbstractLatexProcessor</code> instance.
45       *
46       */
47      public AbstractLatexProcessor(Settings settings, 
48  				  CommandExecutor executor, 
49  				  LogWrapper log, 
50  				  TexFileUtils fileUtils) {
51          this.settings = settings;
52          this.log = log;
53          this.executor = executor;
54          this.fileUtils = fileUtils;
55      }
56  
57      /**
58       * Logs if an error occurred running <code>command</code> 
59       * by detecting that the log file <code>logFile</code> has not been created 
60       * or by detecting the error pattern <code>pattern</code> 
61       * in <code>logFile</code>. 
62       * <p>
63       * Logging: 
64       * <ul>
65       * <li> EAP01 Running <code>command</code> failed. For details...
66       * <li> EAP02 Running <code>command</code> failed. No log file 
67       * <li> WAP04 if <code>logFile</code> is not readable. 
68       * <li> WFU03 cannot close 
69       * </ul>
70       * @see #logWarns(File, String, String) 
71       */
72       protected void logErrs(File logFile, String command, String pattern) {
73      	if (logFile.exists()) {
74  	    // hasErrsWarns may log warnings WFU03, WAP04 
75      	    if (hasErrsWarns(logFile, pattern)) {
76      		this.log.error("EAP01: Running " + command + 
77  			       " failed. Errors logged in '" + 
78  			       logFile.getName() + "'. ");
79      	    }
80      	} else {
81      	    this.log.error("EAP02: Running " + command + 
82  			   " failed: No log file '" + 
83      			   logFile.getName() + "' written. ");
84      	}
85      }
86  
87      /**
88       * Logs if a warning occurred running <code>command</code> 
89       * by detecting the warning pattern <code>pattern</code> 
90       * in <code>logFile</code>. 
91       * If <code>logFile</code> then an error occurred 
92       * making detection of warnings obsolete. 
93       * <p>
94       * Logging: 
95       * <ul>
96       * <li> WAP03 Running <code>command</code> emitted warnings. 
97       * <li> WAP04 if <code>logFile</code> is not readable. 
98       * <li> WFU03 cannot close 
99       * </ul>
100      *
101      * @see #logErrs(File, String, String) 
102      */
103     // for both LatexProcessor and LatexPreProcessor 
104     // FIXME: for LatexPreProcessor never needed. 
105     protected void logWarns(File logFile, String command, String pattern) {
106 	// hasErrsWarns may log warnings WFU03, WAP04 
107     	if (logFile.exists() && hasErrsWarns(logFile, pattern)) {
108 	    // logs warning WAP03: emitted warnings 
109 	    logWarn(logFile, command);
110     	}
111     }
112 
113     /**
114      * <p>
115      * Logging: 
116      * WAP03 Running <code>command</code> emitted warnings. 
117      */
118     // invoked by logWarns(File, String, String) and 
119     // LatexProcessor.logWarns(File, String)
120     protected void logWarn(File logFile, String command) {
121 	this.log.warn("WAP03: Running " + command + 
122 		      " emitted warnings logged in '" + 
123 		      logFile.getName() + "'. ");
124     }
125 
126     /**
127      *
128      * Logging: 
129      * <ul>
130      * <li> WFU03 cannot close 
131      * <li> WAP04 if <code>logFile</code> is not readable. 
132      * </ul>
133      */
134     // FIXME: not clear whether error or warning; also command not clear. 
135     // used in 
136     // logErrs (File, String, String)
137     // logWarns(File, String, String)
138     protected boolean hasErrsWarns(File logFile, String pattern) {
139 	assert logFile.exists() && !logFile.isDirectory()
140 	    : "Expected existing (regular) log file "+logFile;
141 	// may log warning WFU03 cannot close 
142 	Boolean res = this.fileUtils.matchInFile(logFile, pattern);
143 	if (res == null) {
144 	    this.log.warn("WAP04: Cannot read log file '" + logFile.getName() + 
145 			  "'; may hide warnings/errors. ");
146 	    return false;
147 	}
148 	return res;
149     }
150 
151     // for both LatexProcessor and LatexPreProcessor 
152     protected boolean update(File source, File target) {
153 	if (!target.exists()) {
154 	    return true;
155 	}
156 	assert source.exists() && !source.isDirectory()
157 	    : "Expected existing (regular) source "+source;
158 
159 	return source.lastModified() > target.lastModified();
160     }
161 
162     /**
163      * Returns an array of strings, 
164      * each entry with a single option given by <code>options</code> 
165      * except the last one which is the name of <code>file</code>. 
166      *
167      * @param options
168      *    the options string. The individual options 
169      *    are expected to be separated by a single blank. 
170      * @param file
171      *    the file argument 
172      * @return
173      *    An array of strings: 
174      *    The 0th entry is the file name, 
175      *    The others, if <code>options</code> is not empty, 
176      *    are the options in <code>options</code>. 
177      */
178     // for both LatexProcessor and LatexPreProcessor 
179     // and in tests 
180     protected static String[] buildArguments(String options, File file) {
181     	if (options.isEmpty()) {
182     	    return new String[] {file.getName()};
183     	}
184         String[] optionsArr = options.split(" ");
185         String[] args = Arrays.copyOf(optionsArr, optionsArr.length + 1);
186         args[optionsArr.length] = file.getName();
187 	
188     	return args;
189      }
190 }