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