DumpingPR.java
001 /*
002  *  DumpingPR.java
003  *
004  *  Copyright (c) 1995-2012, The University of Sheffield. See the file
005  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
006  *
007  *  This file is part of GATE (see http://gate.ac.uk/), and is free
008  *  software, licenced under the GNU Library General Public License,
009  *  Version 2, June 1991 (in the distribution as file licence.html,
010  *  and also available at http://gate.ac.uk/gate/licence.html).
011  *
012  *  Kalina Bontcheva, 19/10/2001
013  *
014  *  $Id: DumpingPR.java 17589 2014-03-08 08:13:46Z markagreenwood $
015  */
016 
017 package gate.creole.dumpingPR;
018 
019 import gate.Annotation;
020 import gate.AnnotationSet;
021 import gate.Gate;
022 import gate.ProcessingResource;
023 import gate.Resource;
024 import gate.corpora.DocumentImpl;
025 import gate.creole.AbstractLanguageAnalyser;
026 import gate.creole.ExecutionException;
027 import gate.creole.ResourceInstantiationException;
028 import gate.util.Files;
029 import gate.util.GateRuntimeException;
030 import gate.util.InvalidOffsetException;
031 import gate.util.Out;
032 
033 import java.io.File;
034 import java.io.FileOutputStream;
035 import java.io.IOException;
036 import java.io.OutputStreamWriter;
037 import java.net.URL;
038 import java.util.HashMap;
039 import java.util.HashSet;
040 import java.util.Iterator;
041 import java.util.List;
042 import java.util.Map;
043 import java.util.Set;
044 
045 /**
046  * This class implements a DumpingPR which exports a given set of annotation
047  * types + the original markup, back into the document's native format.
048  * The export might also include the GATE features of those annotations or
049  * not (the default). One can also control whether the export files have a
050  * new suffix (useSuffixForDumpFiles) and what this suffix is
051  * (suffixForDumpFiles). By default, a suffix is used and it is .gate.
052  */
053 public class DumpingPR extends AbstractLanguageAnalyser
054   implements ProcessingResource {
055 
056   private static final long serialVersionUID = -5279930527247392922L;
057 
058   public static final String
059     DPR_DOCUMENT_PARAMETER_NAME = "document";
060 
061   public static final String
062     DPR_ANN_SET_PARAMETER_NAME = "annotationSetName";
063 
064   public static final String
065     DPR_ANN_TYPES_PARAMETER_NAME = "annotationTypes";
066 
067   public static final String
068     DPR_DUMP_TYPES_PARAMETER_NAME = "dumpTypes";
069 
070   public static final String
071     DPR_OUTPUT_URL_PARAMETER_NAME = "outputDirectoryUrl";
072 
073   public static final String
074     DPR_INCLUDE_FEAT_PARAMETER_NAME = "includeFeatures";
075 
076   public static final String
077     DPR_USE_SUFFIX_PARAMETER_NAME = "useSuffixForDumpFiles";
078 
079   public static final String
080     DPR_FILE_SUFFIX_PARAMETER_NAME = "suffixForDumpFiles";
081 
082   private static final boolean DEBUG = true;
083 
084   /**
085    * A list of annotation types, which are to be dumped into the output file
086    */
087   protected List<String> annotationTypes;
088 
089   /**
090    * A list of strings specifying new names to be used instead of the original
091    * annotation types given in the annotationTypes parameter. For example, if
092    * annotationTypes was set to [Location, Date], then if dumpTypes is set to
093    * [Place, Date-expr], then the labels <Place> and <Date-expr> will be inserted
094    * instead of <Location> and <Date>.
095    */
096   protected List<String> dumpTypes;
097 
098   /**the name of the annotation set
099    * from which to take the annotations for dumping
100    */
101   protected String annotationSetName;
102 
103   /**
104    * Whether or not to include the annotation features during export
105    */
106   protected boolean includeFeatures = false;
107 
108   /**
109    * Whether or not to include the annotation features during export
110    */
111   protected boolean useStandOffXML = false;
112 
113   /**
114    * What suffix to use for the dump files. .gate by default, but can be
115    * changed via the set method.
116    */
117   protected String suffixForDumpFiles = ".gate";
118 
119   /**
120    * Whether or not to use the special suffix fo the dump files. True by
121    * default.
122    */
123   protected boolean useSuffixForDumpFiles = true;
124 
125   protected java.net.URL outputDirectoryUrl;
126 
127   private static final String DUMPING_PR_SET = "DumpingPRTempSet";
128 
129   /** Initialise this resource, and return it. */
130   @Override
131   public Resource init() throws ResourceInstantiationException
132   {
133     return super.init();
134   // init()
135 
136   /**
137   * Reinitialises the processing resource. After calling this method the
138   * resource should be in the state it is after calling init.
139   * If the resource depends on external resources (such as rules files) then
140   * the resource will re-read those resources. If the data used to create
141   * the resource has changed since the resource has been created then the
142   * resource will change too after calling reInit().
143   */
144   @Override
145   public void reInit() throws ResourceInstantiationException
146   {
147     init();
148   // reInit()
149 
150   /** Run the resource. */
151   @Override
152   public void execute() throws ExecutionException {
153     if(document == null)
154       throw new GateRuntimeException("No document to process!");
155 
156     //if we're saving into standOffXML, then the rest of the settings do
157     //not matter because that toXML method saves everything
158     if (this.useStandOffXML) {
159       write2File();
160       return;
161     }
162 
163     AnnotationSet allAnnots;
164     // get the annotations from document
165     if ((annotationSetName == null)|| (annotationSetName.equals("")))
166       allAnnots = document.getAnnotations();
167     else
168       allAnnots = document.getAnnotations(annotationSetName);
169 
170     //if none found, print warning and exit
171     if ((allAnnots == null|| allAnnots.isEmpty()) {
172       Out.prln("DumpingPR Warning: No annotations found for export. "
173                "Including only those from the Original markups set.");
174       write2File(null);
175       return;
176     }
177 
178     //if we're saving into standOffXML, then the rest of the settings do
179     //not matter because that toXML method saves everything
180     if (this.useStandOffXML) {
181       write2File();
182       return;
183     }
184 
185     //first transfer the annotation types from a list to a set
186     //don't I just hate this!
187     Set<String> types2Export = new HashSet<String>(annotationTypes);
188 
189     //then get the annotations for export
190     AnnotationSet annots2Export = allAnnots.get(types2Export);
191 
192     //check whether we want the annotations to be renamed before
193     //export (that's what dumpTypes is for)
194     if (dumpTypes != null && !dumpTypes.isEmpty()) {
195       Map<String,String> renameMap = new HashMap<String,String>();
196       for(int i=0; i<dumpTypes.size() && i<annotationTypes.size(); i++) {
197         //check if we have a corresponding annotationType and if yes,
198         //then add to the hash map for renaming
199         renameMap.put(annotationTypes.get(i), dumpTypes.get(i));
200       }//for
201       //if we have to rename annotations, then do so
202       if(!renameMap.isEmpty() && annots2Export != null)
203         annots2Export = renameAnnotations(annots2Export, renameMap);
204     }//if
205 
206     write2File(annots2Export);
207     document.removeAnnotationSet(DumpingPR.DUMPING_PR_SET);
208 
209   // execute()
210 
211   protected void write2File(AnnotationSet exportSet) {
212       File outputFile;
213       String fileName = null;
214       if(document.getSourceUrl() == null)
215         fileName = document.getName() "_" + Gate.genSym();
216       else 
217         fileName = getFileName(document.getSourceUrl());
218       
219       fileName = getNewFileName(outputDirectoryUrl, fileName);
220       StringBuffer tempBuff = new StringBuffer(fileName);
221       //now append the special suffix if we want to use it
222       if (useSuffixForDumpFiles)
223         tempBuff.append(this.suffixForDumpFiles);
224 
225       String outputPath = tempBuff.toString();
226 
227       if (DEBUG)
228         Out.prln(outputPath);
229       outputFile = new File(outputPath);
230 
231     try {
232       // Prepare to write into the xmlFile using the doc's encoding if there
233       OutputStreamWriter writer;
234       if (document instanceof DocumentImpl) {
235         String encoding = ((DocumentImpldocument).getEncoding();
236         if (encoding == null || "".equals(encoding))
237           writer = new OutputStreamWriter(new FileOutputStream(outputFile));
238         else
239           writer = new OutputStreamWriter(
240                             new FileOutputStream(outputFile), encoding);
241       else
242           writer = new OutputStreamWriter(
243                             new FileOutputStream(outputFile));
244 
245       // Write (test the toXml() method)
246       // This Action is added only when a gate.Document is created.
247       // So, is for sure that the resource is a gate.Document
248       writer.write(document.toXml(exportSet, includeFeatures));
249       writer.flush();
250       writer.close();
251     catch (IOException ex) {
252       throw new GateRuntimeException("Dumping PR: Error writing document "
253                                      + document.getName() ": "
254                                      + ex.getMessage());
255     }
256 
257 
258   }//write2File
259 
260   protected void write2File() {
261       File outputFile;
262       String fileName = null;
263       if(document.getSourceUrl() == null)
264         fileName = document.getName() "_" + Gate.genSym();
265       else 
266         fileName = getFileName(document.getSourceUrl());
267 
268       fileName = getNewFileName(outputDirectoryUrl, fileName);
269       StringBuffer tempBuff = new StringBuffer(fileName);
270       //now append the special suffix if we want to use it
271       if (useSuffixForDumpFiles)
272         tempBuff.append(this.suffixForDumpFiles);
273       String outputPath = tempBuff.toString();
274       if (DEBUG)
275         Out.prln(outputPath);
276       outputFile = new File(outputPath);
277 
278     try {
279       // Prepare to write into the xmlFile using the doc's encoding if there
280       OutputStreamWriter writer;
281       if (document instanceof DocumentImpl) {
282         String encoding = ((DocumentImpldocument).getEncoding();
283         if (encoding == null || "".equals(encoding))
284           writer = new OutputStreamWriter(new FileOutputStream(outputFile));
285         else
286           writer = new OutputStreamWriter(
287                             new FileOutputStream(outputFile), encoding);
288       else
289           writer = new OutputStreamWriter(
290                             new FileOutputStream(outputFile));
291 
292       // Write (test the toXml() method)
293       // This Action is added only when a gate.Document is created.
294       // So, is for sure that the resource is a gate.Document
295       writer.write(document.toXml());
296       writer.flush();
297       writer.close();
298     catch (IOException ex) {
299       throw new GateRuntimeException("Dumping PR: Error writing document "
300                                      + document.getName() ": "
301                                      + ex.getMessage());
302     }
303 
304 
305   }//write2File
306 
307 
308   protected String getFileName(URL url) {
309     String fileName = url.getFile();
310     int index = fileName.lastIndexOf("/");
311     if(index == -1index = fileName.lastIndexOf("\\");
312     if(index == -1)
313       return fileName;
314     else {
315       if(index + == fileName.length()) {
316         fileName = fileName.substring(0, fileName.length()-1);
317         index = fileName.lastIndexOf("/");
318         if(index == -1index = fileName.lastIndexOf("\\");
319         if(index == -1return fileName;
320       }
321       fileName = fileName.substring(index+1, fileName.length());
322     }
323     return fileName;
324   }
325 
326   protected String getNewFileName(URL dir, String file) {
327     return new File((dir == null?
328       new File(System.getProperty("java.io.tmpdir")) : Files.fileFromURL(dir),
329       file).getAbsolutePath();
330   }
331 
332   protected AnnotationSet renameAnnotations(AnnotationSet annots2Export,
333                                    Map<String,String> renameMap){
334     Iterator<Annotation> iter = annots2Export.iterator();
335     AnnotationSet as = document.getAnnotations(DUMPING_PR_SET);
336     if (!as.isEmpty())
337       as.clear();
338     while(iter.hasNext()) {
339       Annotation annot = iter.next();
340       //first check whether this type needs to be renamed
341       //if not, continue
342       if (!renameMap.containsKey(annot.getType()))
343         renameMap.put(annot.getType(), annot.getType());
344       try{
345         as.add(annot.getId(),
346             annot.getStartNode().getOffset(),
347             annot.getEndNode().getOffset(),
348             renameMap.get(annot.getType()),
349             annot.getFeatures());
350       catch (InvalidOffsetException ex) {
351         throw new GateRuntimeException("DumpingPR: " + ex.getMessage());
352       }
353     }//while
354     return as;
355   }//renameAnnotations
356 
357 
358   /**get the name of the annotation set*/
359   public String getAnnotationSetName() {
360     return annotationSetName;
361   }//getAnnotationSetName
362 
363   /** set the annotation set name*/
364   public void setAnnotationSetName(String newAnnotationSetName) {
365     this.annotationSetName = newAnnotationSetName;
366   }//setAnnotationSetName
367 
368   public List<String> getAnnotationTypes() {
369     return this.annotationTypes;
370   }
371 
372   public void setAnnotationTypes(List<String> newTypes) {
373     this.annotationTypes = newTypes;
374   }
375 
376   public List<String> getDumpTypes() {
377     return this.dumpTypes;
378   }
379 
380   public void setDumpTypes(List<String> newTypes) {
381     dumpTypes = newTypes;
382   }
383 
384   public URL getOutputDirectoryUrl() {
385     return this.outputDirectoryUrl;
386   }
387 
388   public void setOutputDirectoryUrl(URL file) {
389     this.outputDirectoryUrl = file;
390   }
391 
392   public void setIncludeFeatures(Boolean inclFeatures) {
393     if (inclFeatures != null)
394       includeFeatures = inclFeatures.booleanValue();
395   }
396 
397   public Boolean getIncludeFeatures() {
398     return new Boolean(includeFeatures);
399   }
400 
401   public void setUseStandOffXML(Boolean newValue) {
402     if (newValue != null)
403       useStandOffXML = newValue.booleanValue();
404   }
405 
406   public Boolean getUseStandOffXML() {
407     return new Boolean(useStandOffXML);
408   }
409 
410   public String getSuffixForDumpFiles() {
411     return suffixForDumpFiles;
412   }
413 
414   public void setSuffixForDumpFiles(String newSuffix) {
415     this.suffixForDumpFiles = newSuffix;
416   }
417 
418   public Boolean getUseSuffixForDumpFiles() {
419     return new Boolean(this.useSuffixForDumpFiles);
420   }
421 
422   public void setUseSuffixForDumpFiles(Boolean useOrNot) {
423     if (useOrNot != null)
424       this.useSuffixForDumpFiles = useOrNot.booleanValue();
425   }
426 
427 // class DumpingPR