YamCommand.java
001 /*
002  *  YamCommand.java
003  *  Copyright (c) 1998-2008, The University of Sheffield.
004  *
005  *  This code is from the GATE project (http://gate.ac.uk/) and is free
006  *  software licenced under the GNU General Public License version 3. It is
007  *  distributed without any warranty. For more details see COPYING.txt in the
008  *  top level directory (or at http://gatewiki.sf.net/COPYING.txt).
009  *  
010  *  Hamish Cunningham, 7th Feb 2007
011  */
012 
013 package gate.yam;
014 
015 import java.util.*;
016 import java.io.*;
017 import java.net.*;
018 import javax.swing.SwingUtilities;
019 import gnu.getopt.Getopt;
020 import org.apache.log4j.Logger;
021 import org.springframework.core.io.*;
022 import org.springframework.context.support.*;
023 import gate.*;
024 import gate.gui.MainFrame;
025 import gate.util.*;
026 import gate.yam.parse.*;
027 import gate.yam.translate.*;
028 
029 
030 /**
031  * Command-line programme for YAM translation.
032  <b>NOTE:</b> this class uses an outdated implementation of the top-level
033  * YAM API which should not be used by API clients. See {@link YamFile} for
034  * the real deal.
035  @author Hamish Cunningham
036  */
037 public class YamCommand
038 {
039   /** Construction. */
040   public YamCommand() { }
041 
042   /** The URL of the bibliography file used for citations in tests */
043   private static String BIB_URL = "http://gate.ac.uk/sale/bib/main.html";
044 
045   /** The anchor prefix used for citations in tests */
046   private static String BIB_ANCHOR_PREFIX = "X";
047 
048   /**
049    * Translate to a particular target language.
050    *
051    @param yamReader A reader which sources the YAM document.
052    @param outputWriter A writer to which the translation is streamed.
053    @param outputType A flag signalling which target to produce.
054    @param sourceDir A file pointing to the directory in which the source YAM
055    * document lives (used to find included files that are relative paths).
056    @return the parse tree.
057    @throws GateException if parsing or translation fails, or if
058    * the outputType is invalid.
059    */
060   public YamParseTree translate(
061     Reader yamReader, Writer outputWriter, YamFile.FileType outputType,
062     File sourceDir
063   )
064     throws GateException
065   {
066     // construct a parser and run it
067     YamParser parser = new YamParser(yamReader);
068     IOHandler ioHandler = new IOHandlerImpl();
069     ioHandler.setSourceDir(sourceDir);
070     ioHandler.setBibAnchorPrefix(BIB_ANCHOR_PREFIX);
071     try {
072       ioHandler.setBibPageUrl(new UrlResource(BIB_URL));
073     catch(MalformedURLException e) {
074       throw new GateException(e);
075     }
076     parser.setIOHandler(ioHandler);
077     YamParseTree parseTree = parser.parse();
078 
079     // translate
080     translate(outputType, outputWriter, parseTree, ioHandler);
081     
082     // return the results
083     return parseTree;
084   // translate(yamReader, outputWriter, outputType, sourceDir)
085 
086   /**
087    * Construct an appropriate translator for the target language and run it.
088    */
089   void translate(
090     YamFile.FileType outputType, Writer outputWriter, YamParseTree parseTree,
091     IOHandler ioHandler
092   throws GateException {
093     AbstractTranslator translator = null;
094     switch(outputType) {
095       case HTML:
096         translator = new HtmlTranslator();
097         break;
098       case LATEX:
099         translator = new LaTeXTranslator();
100         break;
101       case PDF:
102       //new latex translator and set pdf flag on it; Writer is for the .tex
103         break;
104       case TREE:
105         translator = new TreeTranslator();
106         break;
107       case YAM:
108       case PRETTY:
109         translator = new PrettyTranslator();
110         break;
111       default:
112         throw new GateException("unknown output type " + outputType);
113     }
114     translator.setIOHandler(ioHandler);
115     translator.setParseTree(parseTree);
116     translator.setWriter(outputWriter);
117     if(DEBUG && outputType == YamFile.FileType.PRETTY)
118       ((PrettyTranslatortranslator).pleaseLeakLotsOfMemory = true;
119     translator.translate();
120   // translate(FileType, Writer, YamParseTree, IOHandler)
121 
122   /**
123    * Get the language version number.
124    * Version 1 was derived from Terrence Parr's TML language (thanks Ter!
125    * See <a href=http://antlr.org>the ANTLR site</a>).
126    * Version 2 was the first version of YAM proper. Version 3 added
127    * various new facilities and was the basis for the first version of CLIE.
128    * Version 4 was a complete rewrite, for GATE version 4 and for use in
129    * <a href=http://gatewiki.sf.net/>CoW</a>. Version 5 is intended to be
130    * stable and backwards-compatible with future versions.
131    */
132   public String getVersion() { return "5.0"}
133 
134   /** Print errors and warnings from parsing. */
135   public String printErrors(YamParseTree parseTree) {
136     StringBuffer buf = new StringBuffer();
137     if(parseTree == null)
138       return "null parse tree in YamCommand.printErrors(YPT)\n";
139     List errors = parseTree.getErrors();
140     List warnings = parseTree.getWarnings();
141     if(errors.size() == && warnings.size() == 0)
142       return buf.toString();
143     buf.append("%%%%%%%%%%%%%%% errors and warnings %%%%%%%%%%%%%%%%%%\n");
144     for(int i=0; i<errors.size(); i++)
145       buf.append(((ParsingProblem)errors.get(i)).getMessage() "\n");
146     for(int i=0; i<warnings.size(); i++)
147       buf.append(((ParsingProblem)warnings.get(i)).getMessage() "\n");
148     buf.append("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
149     return buf.toString();
150   // printErrors()
151 
152 
153   //////////////////////////////////////////////////////////////////////////
154   /** Main function. */
155   public static void main(String[] args) {
156     String inFileName = null, outFileName = null, outputType = "html";
157     Getopt g = new Getopt("YAM main", args, "hi:o:l:");
158     int c;
159     YamFile.FileType outputTypeFlag = YamFile.FileType.HTML;
160 
161     while( (c = g.getopt()) != -)
162       switch(c) {
163         // -h
164         case 'h':
165           help();
166           usage();
167           System.exit(STATUS_NORMAL);
168           break;
169         // -l language
170         case 'l':
171           outputType = g.getOptarg();
172           break;
173         // -i in-file
174         case 'i':
175           inFileName = g.getOptarg();
176           break;
177         // -o in-file
178         case 'o':
179           outFileName = g.getOptarg();
180           break;
181         case '?':
182           // leave the warning to getopt
183           errorExit("");
184           break;
185         default:
186           // shouldn't happen!
187           errorExit("getopt() returned " + c + "\n");
188           break;
189       // getopt switch
190  
191     // validate args
192     if(inFileName == nullerrorExit("no input file specified");
193     if(outFileName == nullerrorExit("no output file specified");
194     if(outputType.equals("html"))
195       outputTypeFlag = YamFile.FileType.HTML;
196     else if(outputType.equals("latex"))
197       outputTypeFlag = YamFile.FileType.LATEX;
198     else if(outputType.equals("tree"))
199       outputTypeFlag = YamFile.FileType.TREE;
200     else if(outputType.equals("pretty"))
201       outputTypeFlag = YamFile.FileType.PRETTY;
202     else
203       errorExit("unknown output type: " + outputType);
204 
205     // run the GATE Developer UI for debugging (e.g. pretty-printing docs)
206     if(DEBUG) {
207       if(! gateMainFrameIsOn) {
208         SwingUtilities.invokeLater(new Runnable() {
209           public void run() {
210             MainFrame mainFrame = new MainFrame();
211             mainFrame.setVisible(true);
212           }
213         });
214         gateMainFrameIsOn = true;
215       }
216     }
217 
218     // set up the IO stuff
219     File inFile = new File(inFileName);
220     File outFile = new File(outFileName);
221     File sourceDir = inFile.getParentFile();
222     Reader yamReader = null;
223     Writer outputWriter = null;
224     try {
225       yamReader = new FileReader(inFile);
226     catch(IOException e) {
227       errorExit("can't open " + inFileName + ":\n" + e);
228     }
229     try {
230       outputWriter = new FileWriter(outFile);
231     catch(IOException e) {
232       errorExit("can't open " + outFileName + ":\n" + e);
233     }
234   
235     // do the parsing and translation
236     Out.prln("translating " + inFileName + " into " + outFileName);
237     YamCommand yam = null;
238     YamParseTree parseTree = null;
239     try {
240       yam = new YamCommand();
241       parseTree = 
242         yam.translate(yamReader, outputWriter, outputTypeFlag, sourceDir);
243       try {
244         yamReader.close();
245         outputWriter.close();
246       catch(IOException e) {
247         errorExit("couldn't close the input or output files");
248       }
249       Out.pr(yam.printErrors(parseTree));
250     catch(GateException e) {
251       Out.pr(yam.printErrors(parseTree));
252       errorExit("YAM error: " + e);
253     }
254 
255     if(! gateMainFrameIsOn)
256       System.exit(STATUS_NORMAL);
257   // main(String[])
258 
259 // TODO
260   static final boolean DEBUG = false;
261   static boolean gateMainFrameIsOn = false;
262 
263   /** Display a usage message */
264   static void usage() {
265     Out.prln(
266       "Usage: java yam.Main " "[ -h(elp) ] " +
267       "[ -language html|tex|tree|pretty ]" " -i inFileName -o outFileName"
268     );
269   // usage()
270 
271   /** Display a help message */
272   static void help() {
273     Out.prln(
274       "Please give generously."
275     );
276   // help()
277 
278   /** Display an error message and exit */
279   static void errorExit(String message) {
280     Err.prln(message + "\n");
281     System.exit(STATUS_ERROR);
282   // errorExit(String)
283 
284   /** Status flag for normal exit. */
285   private static final int STATUS_NORMAL = 0;
286 
287   /** Status flag for error exit. */
288   private static final int STATUS_ERROR = 1;
289 
290   /** SInS (plain) logger */
291   static Logger slgr = Logger.getLogger("gate.sins");
292 
293   /** Initialise GATE if it hasn't already been done. */
294   static {
295     if(! Gate.isInitialised()) {
296     /*
297       File cowGate =
298         new File(System.getProperty("user.dir"), "web-app/WEB-INF/gate");
299       System.setProperty(
300         "gate.user.session",
301         new File(cowGate, "user-gate.session").getAbsolutePath()
302       );
303       System.setProperty(
304         "gate.user.config",
305         new File(cowGate, "user-gate.xml").getAbsolutePath()
306       );
307       System.setProperty(
308         "gate.site.config",
309         new File(cowGate, "site-gate.xml").getAbsolutePath()
310       );
311       Gate.setGateHome(cowGate);
312     */
313       try {
314         Gate.init();
315       catch(GateException e) {
316         slgr.error("couldn't init Gate");
317         slgr.error(e);
318       }
319     }
320   // static block
321 
322 // YamCommand