View Javadoc

1   /*
2    * Copyright (C) 2004-2006 Christian Siefkes <christian@siefkes.net>.
3    * Development of this software is supported by the German Research Society,
4    * Berlin-Brandenburg Graduate School in Distributed Information Systems
5    * (DFG grant no. GRK 316).
6    *
7    * This program is free software; you can redistribute it and/or modify
8    * it under the terms of the GNU General Public License as published by
9    * the Free Software Foundation; either version 2 of the License, or
10   * (at your option) any later version.
11   *
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with this program; if not, visit
19   * http://www.gnu.org/licenses/gpl.html or write to the Free Software
20   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21   */
22  package de.fu_berlin.ties;
23  
24  import java.util.Iterator;
25  import java.util.List;
26  
27  import org.apache.commons.lang.ArrayUtils;
28  
29  import de.fu_berlin.ties.util.TaskRunner;
30  import de.fu_berlin.ties.util.Util;
31  
32  /***
33   * A static class that provides a main external
34   * entry point to TIE. The {@link #main(String[])} method executes a specified
35   * {@link de.fu_berlin.ties.Processor} on a series of input arguments (typically
36   * files or URLs).
37   *
38   * <p>No instances of this class can be created, only the static members
39   * should be used.
40   *
41   * @author Christian Siefkes
42   * @version $Revision: 1.31 $, $Date: 2007/01/29 19:14:35 $, $Author: siefkes $
43   */
44  public final class Main {
45  
46      /***
47       * The name of this software.
48       */
49      public static final String NAME = "Trainable Information Extractor";
50  
51      /***
52       * The current version number of this software.
53       */
54      public static final String VERSION_NO = "1.0";
55  
56      /***
57       * Main method: execute the given goal (first argument) on the given
58       * arguments.
59       *
60       * @param args the command-line parameters: first element must be the name
61       * of the {@link Processor} to execute (mapped as configured in "goal"
62       * section), each further element is given as input to an invocation of the
63       * {@link Processor#process(String)} method; elements starting with "+" or
64       * "-" are processed as configuration options (cf.
65       * {@link TiesConfiguration#configureFromArgs(String[])})
66       */
67      public static void main(final String[] args) {
68          final long startTime = System.currentTimeMillis();
69          Util.LOG.debug(NAME + ' ' + VERSION_NO + " running on "
70                  + System.getProperty("java.vm.name") + ' '
71                  + System.getProperty("java.vm.version") + " installed in "
72                  + System.getProperty("java.home"));
73  
74          // ensure the default task runner is always available
75          TaskRunner.registerInterest();
76  
77          try {
78              // modify standard configuration + collect remaining arguments
79              List arguments = null;
80              try {
81                  arguments = TiesConfiguration.CONF.configureFromArgs(args);
82              } catch (Exception e) {
83                  Util.LOG.fatalError("Illegal option", e);
84                  return;
85              }
86  
87              if (arguments.size() < 2) {
88                  // not enough remaining arguments: print version info +
89                  // short help message to standard out and exit
90                  System.out.println(NAME + ' ' + VERSION_NO);
91                  System.out.println("Specify processing goal as first argument "
92                      + "and the files or URLs to process");
93                  System.out.println("as further arguments.");
94                  return;
95              }
96              final Iterator argIter = arguments.iterator();
97  
98              // reconfigure logger
99              Util.configureLog(TiesConfiguration.CONF);
100 
101             // check goal (we check above that there are enough arguments)
102             final String goalName = (String) argIter.next();
103             final String goalParam = TiesConfiguration.joinKey(
104                 TiesConfiguration.CONFIG_GOAL_PREFIX, goalName);
105 
106             if (!TiesConfiguration.CONF.containsKey(goalParam)) {
107                 // unknown goal: exit
108                 Util.LOG.error(goalName + " is not a registered goal");
109                 return;
110             }
111 
112             // first argument is class name, any further arguments are
113             // constructor parameters
114             final String[] goalDefinition =
115                 TiesConfiguration.CONF.getStringArray(goalParam);
116 
117             // try to load goal processor with specified arguments
118             final Processor goal;
119             String input;
120 
121             try {
122                 goal = (Processor) Util.createObject(goalDefinition);
123                 Util.LOG.debug("Executing " + goalName + " goal (definition: "
124                     + ArrayUtils.toString(goalDefinition) + ")");
125             } catch (Exception e) {
126                 // unable to load goal: exit
127                 Util.LOG.error("Could not initialize processor for " + goalName
128                     + " goal (definition: "
129                     + ArrayUtils.toString(goalDefinition) + ")", e);
130                 return;
131             }
132             int errorCount = 0;
133 
134             // feed each further argument to the goal's process method
135             try {
136                 while (argIter.hasNext()) {
137                     input = (String) argIter.next();
138                     try {
139                         goal.process(input);
140                     } catch (Exception e) {
141                         Util.LOG.error("Error while processing " + input, e);
142                         errorCount++;
143                         if (errorCount >= 2) {
144                             // exit after second error
145                             Util.LOG.fatalError("Too many errors");
146                             return;
147                         }
148                     }
149                 }
150             } finally {
151                 // close the processor if it implements the Closable interface
152                 if (goal instanceof Closeable) {
153                     final Closeable closeableGoal = (Closeable) goal;
154 
155                     try {
156                         closeableGoal.close(errorCount);
157                     } catch (Exception e) {
158                         Util.LOG.error("Error while closing goal processor", e);
159                         return;
160                     }
161                 }
162             }
163 
164             // print run time
165             Util.LOG.debug("Done (" + Util.showDuration(startTime) + ")");
166         } catch (Throwable t) {
167             Util.LOG.fatalError("Exiting due to fatal error", t);
168         } finally {
169             // always release the default task runner
170             TaskRunner.deregisterInterest();
171         }
172     }
173 
174     /***
175      * Private constructor prevents creation of instances.
176      */
177     private Main() {
178         super();
179     }
180 
181 }