GazetteerLists.java
001 package gate.util.ant.packager;
002 
003 import gate.util.BomStrippingInputStreamReader;
004 
005 import java.io.BufferedReader;
006 import java.io.File;
007 import java.io.FileInputStream;
008 import java.io.IOException;
009 import java.io.InputStreamReader;
010 import java.util.ArrayList;
011 import java.util.Collections;
012 import java.util.HashSet;
013 import java.util.Iterator;
014 import java.util.List;
015 import java.util.Set;
016 
017 import org.apache.tools.ant.BuildException;
018 import org.apache.tools.ant.Project;
019 import org.apache.tools.ant.types.DataType;
020 import org.apache.tools.ant.types.ResourceCollection;
021 import org.apache.tools.ant.types.resources.FileResourceIterator;
022 import org.apache.tools.ant.util.FileUtils;
023 
024 /**
025  * Class that extracts the list of gazetteer .lst files from a .def.
026  * This class extends {@link Path} so it can be used as a nested element
027  * within the extraresourcespath of a packagegapp task.
028  */
029 public class GazetteerLists extends DataType implements ResourceCollection {
030 
031   /**
032    * The gazetteer list definition file (.def).
033    */
034   private File definition;
035 
036   /**
037    * The encoding used to read the def file. If null, the platform
038    * default encoding will be used.
039    */
040   private String encoding = null;
041 
042   /**
043    * The names of the gazetteer lists referenced by the definition.
044    */
045   private String[] listNames = null;
046 
047   /**
048    * Set the location of the definition file from which the lists should
049    * be extracted. The list definition file is parsed and the .lst files
050    * found are added as pathelements to this path.
051    *
052    @throws BuildException if an error occurs parsing the definition
053    *           file.
054    */
055   public void setDefinition(File definition) {
056     this.definition = definition;
057   }
058 
059   /**
060    * ResourceCollection interface: returns an iterator over the list
061    * files.
062    */
063   public Iterator iterator() {
064     load();
065 
066     if(listNames.length == 0) {
067       return Collections.EMPTY_LIST.iterator();
068     }
069     else {
070       return new FileResourceIterator(definition.getParentFile(), listNames);
071     }
072   }
073 
074   /**
075    * ResourceCollection interface: returns true (this collection always
076    * exposes only filesystem resources).
077    */
078   public boolean isFilesystemOnly() {
079     return true;
080   }
081 
082   /**
083    * ResourceCollection interface: returns the number of list files
084    * referenced by this definition.
085    */
086   public int size() {
087     load();
088     return listNames.length;
089   }
090 
091   /**
092    * Parse the definition and populate the array of list names.
093    */
094   private void load() {
095     log("Listing gazetteer lists", Project.MSG_VERBOSE);
096     if(definition == null) {
097       throw new BuildException(
098               "\"definition\" attribute is required for gazetteerlists");
099     }
100     log("definition file: " + definition, Project.MSG_VERBOSE);
101 
102     Set<String> lists = new HashSet<String>();
103     File definitionDir = definition.getParentFile();
104     try {
105       FileInputStream fis = new FileInputStream(definition);
106       try {
107         BufferedReader in = null;
108         if(encoding == null) {
109           in = new BomStrippingInputStreamReader(fis);
110         }
111         else {
112           in = new BomStrippingInputStreamReader(fis, encoding);
113         }
114 
115         String line;
116         while((line = in.readLine()) != null) {
117           int indexOfColon = line.indexOf(':');
118           // Ignore lines that don't include a colon.
119           if(indexOfColon > 0) {
120             String listFile = line.substring(0, indexOfColon);
121             lists.add(listFile);
122             log("Found list file " + listFile, Project.MSG_VERBOSE);
123           }
124         }
125       }
126       finally {
127         fis.close();
128       }
129     }
130     catch(IOException ioe) {
131       throw new BuildException("Error reading gazetteer definition file "
132               + definition, ioe);
133     }
134 
135     listNames = lists.toArray(new String[lists.size()]);
136   }
137 
138   /**
139    * Set the encoding used to read the definition file. If this is not
140    * set, the platform default encoding is used.
141    */
142   public void setEncoding(String encoding) {
143     this.encoding = encoding;
144   }
145 
146 }