GazetteerList.java
001 /*
002  *  GazetteerList.java
003  *
004  *  Copyright (c) 1995-2010, 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  *  borislav popov 02/2002
013  *
014  *  $Id: GazetteerList.java 12919 2010-08-03 10:31:37Z valyt $
015  */
016 
017 package gate.creole.gazetteer;
018 
019 import java.io.*;
020 import java.net.URL;
021 import java.util.*;
022 
023 import gate.creole.ResourceInstantiationException;
024 import gate.util.BomStrippingInputStreamReader;
025 import gate.util.Files;
026 
027 
028 /** Gazetteer List provides the means for uploading, managing and
029  *  storing the data in the gazetteer list files. */
030 public class GazetteerList extends gate.creole.AbstractLanguageResource
031 implements List {
032 
033   /** indicates list representation of the gazetteer list*/
034   public final static int LIST_MODE = 0;
035 
036   /** indicates representation of the gaz list as a single string */
037   public final static int STRING_MODE = 1;
038 
039   /** the url of this list */
040   private URL url;
041 
042   /**the encoding of the list */
043   private String encoding = "UTF-8";
044 
045   /** indicates the current mode
046    *of the gazetteer list(e.g. STRING_MODE,LIST_MODE) */
047   private int mode = ;
048 
049   /** flag indicating whether the list has been modified after loading/storing */
050   private boolean isModified = false;
051 
052   /** the entries of this list */
053   private List entries = new ArrayList();
054 
055   /** the content of this list */
056   private String content = null;
057 
058   /** the separator used to delimit feature name-value pairs in gazetteer lists */
059   private String separator;
060 
061   /** create a new gazetteer list */
062   public GazetteerList() {
063   }
064 
065   /** @return true if the list has been modified after load/store  */
066   public boolean isModified() {
067     return isModified;
068   }
069 
070   /**Sets the modified status of the current list
071    @param modified is modified flag   */
072   public void setModified(boolean modified) {
073     isModified = modified;
074   }
075 
076   /** Retrieves the current mode of the gaz list
077    *  @return the current mode   */
078   public int getMode() { return mode; }
079 
080   /**Sets mode of the gazetteer list
081    @param m the mode to be set    */
082   public void setMode(int m) {
083     if (m!=mode) {
084     switch (m){
085         case LIST_MODE :{
086           mode = m;
087           updateContent(content);
088           break;
089         // LIST_MODE
090         case STRING_MODE:{
091           content = this.toString();
092           mode = m;
093           break;
094         //STRING_MODE
095         default:{
096           throw new gate.util.GateRuntimeException("Invalid Mode ="+mode
097           +"\nValid modes are:\nLIST_MODE = "+LIST_MODE
098           +"\nSTRING_MODE = "+STRING_MODE);
099         // default
100       // switch
101     // only if different from the current
102   // setMode(int)
103 
104 
105   /** Sets the encoding of the list
106    *  @param encod the encoding to be set */
107   public void setEncoding(String encod) {
108     encoding = encod;
109   }
110 
111   /** Gets the encoding of the list
112    *  @return the encoding of the list*/
113   public String getEncoding() {
114     return encoding;
115   }
116 
117   /**
118    * Loads a gazetteer list
119    @throws ResourceInstantiationException when the resource cannot be created
120    */
121   public void load() throws ResourceInstantiationException {
122     load(false);
123   }
124 
125   /**
126    * Loads a gazetteer list
127    @param isOrdered true if the feature maps used should be ordered
128    @throws ResourceInstantiationException when the resource cannot be created
129    */
130   public void load(boolean isOrderedthrows ResourceInstantiationException {
131     try {
132       if (null == url) {
133         throw new ResourceInstantiationException("URL not specified (null).");
134       }
135 
136       BufferedReader listReader;
137 
138       listReader = new BomStrippingInputStreamReader(
139                               (url).openStream(), encoding);
140       String line;
141       while (null != (line = listReader.readLine())) {
142         entries.add(new GazetteerNode(line, separator, isOrdered));
143       //while
144 
145       listReader.close();
146     catch (Exception x) {
147       throw new ResourceInstantiationException(x.getClass()+":"+x.getMessage());
148     }
149     isModified = false;
150   // load ()
151 
152   /**
153    * Stores the list to the specified url
154    @throws ResourceInstantiationException
155    */
156   public void store() throws ResourceInstantiationException{
157     try {
158       if (null == url) {
159         throw new ResourceInstantiationException("URL not specified (null)");
160       }
161 
162       URL tempUrl = url;
163       if (-!= url.getProtocol().indexOf("gate")) {
164         tempUrl = gate.util.protocols.gate.Handler.class.getResource(
165                       gate.util.Files.getResourcePath() + url.getPath()
166                     );
167       // if gate:path url
168 
169       File fileo = Files.fileFromURL(tempUrl);
170 
171       fileo.delete();
172       OutputStreamWriter listWriter  = new OutputStreamWriter(
173                     new FileOutputStream(fileo), encoding);
174 //      BufferedWriter listWriter = new BufferedWriter(new FileWriter(fileo));
175       Iterator iter = entries.iterator();
176       while (iter.hasNext()) {
177         listWriter.write(iter.next().toString());
178         listWriter.write(13);
179         listWriter.write(10);
180       }
181       listWriter.close();
182     catch (Exception x) {
183       throw new ResourceInstantiationException(x.getClass()+":"+x.getMessage());
184     }
185     isModified = false;
186   // store()
187 
188 
189   /**
190    * Sets the URL of the list
191    @param theUrl the URL of the List
192    */
193   public void setURL(URL theUrl) {
194     url = theUrl;
195     isModified = true;
196   }
197 
198   /**
199    * Gets the URL of the list
200    @return the URL of the list
201    */
202   public URL getURL() {
203     return url;
204   }
205 
206 
207   /**
208    @return the seperator
209    */
210   public String getSeparator() {
211     return separator;
212   }
213 
214   /**
215    @param separator the separator to set
216    */
217   public void setSeparator(String separator) {
218     this.separator = separator;
219   }
220 
221 
222 /*--------------implementation of java.util.List--------------------*/
223   public int size() {
224     return entries.size();
225   }
226 
227   public boolean isEmpty() {
228     return (== entries.size());
229   }
230 
231   public boolean contains(Object o) {
232     return entries.contains(o);
233   // contains()
234 
235   /**Gets an iterator over the list. It is not dangerous if the iterator is modified since there
236   are no dependencies of entries to other members  */
237   public Iterator iterator() {
238     return entries.iterator();
239   }
240 
241   public Object[] toArray() {
242     return entries.toArray();
243   }
244 
245   public Object[] toArray(Object[] a) {
246     return entries.toArray(a);
247   }
248 
249   public boolean add(Object o) {
250     boolean result = false;
251     if (instanceof GazetteerNode) {
252       result = entries.add(o);
253     }
254     isModified |= result;
255     return result;
256   // add()
257 
258   public boolean remove(Object o) {
259     boolean result = entries.remove(o);
260     isModified |= result;
261     return result;
262   }
263 
264   public boolean containsAll(Collection c) {
265     return entries.containsAll(c);
266   }
267 
268   /**
269    * Adds entire collection
270    @param c a collection to be addded
271    @return true if all the elements where Strings and all are sucessfully added
272    */
273   public boolean addAll(Collection c) {
274     Iterator iter = c.iterator();
275     Object o;
276     boolean result = false;
277 
278     while (iter.hasNext()) {
279       o = iter.next();
280       if (instanceof GazetteerNode) {
281         result |= entries.add(o);
282       }
283     // while
284     isModified |= result;
285 
286     return result;
287   // addAll(Collection)
288 
289   public boolean addAll(int index, Collection c) {
290     boolean result = entries.addAll(index,c);
291     isModified |= result;
292     return result;
293   //addAll(int,Collection)
294 
295 
296   public boolean removeAll(Collection c) {
297     boolean result = entries.removeAll(c);
298     isModified |= result;
299     return result;
300   }
301 
302   public boolean retainAll(Collection c) {
303     boolean result = entries.retainAll(c);
304     isModified |= result;
305     return result;
306   }
307 
308   public void clear() {
309     if (< entries.size())
310       isModified = true;
311     entries.clear();
312   }
313 
314 
315   public boolean equals(Object o) {
316     boolean result = false;
317     if (instanceof GazetteerList) {
318       result = true;
319       GazetteerList list2 = (GazetteerListo;
320       result &= entries.equals(list2.entries);
321     // if
322     return result;
323   // equals()
324 
325 
326 
327   public Object get(int index) {
328     return entries.get(index);
329   }
330 
331   public Object set(int index, Object element) {
332     isModified=true;
333     return entries.set(index,element);
334   }
335 
336   public void add(int index, Object element) {
337     isModified = true;
338     entries.add(index,element);
339   }
340 
341   public Object remove(int index) {
342     int size = entries.size();
343     Object result = entries.remove(index);
344     isModified |= (size!=entries.size());
345     return result;
346   }
347 
348   public int indexOf(Object o) {
349     return entries.indexOf(o);
350   }
351 
352   public int lastIndexOf(Object o) {
353     return entries.lastIndexOf(o);
354   }
355 
356   public ListIterator listIterator() {
357     return entries.listIterator();
358   }
359 
360   public ListIterator listIterator(int index) {
361     return entries.listIterator(index);
362   }
363 
364   public List subList(int fromIndex, int toIndex) {
365     return entries.subList(fromIndex,toIndex);
366   }
367 
368 
369   /** Retrieves the string representation of the gaz list
370    *  according to its mode. If
371    *  {@link #LIST_MODE} then all
372    *  the entries are dumped sequentially to a string. If
373    *  {@link #STRING_MODE} then
374    *  the content (a string) of the gaz list is retrieved.
375    *  @return the string representation of the gaz list*/
376   public String toString() {
377     String stres = null;
378     switch (mode) {
379       case LIST_MODE : {
380         StringBuffer result = new StringBuffer();
381         String entry = null;
382         for(int i = 0; i < entries.size(); i++) {
383           GazetteerNode node = (GazetteerNode)entries.get(i);
384           entry = node.getEntry().trim();
385           if(entry.length() 0) {
386             result.append(entry);
387             Map featureMap = node.getFeatureMap();
388             if(featureMap != null && (featureMap.size() 0)) {
389               result.append(node.featureMapToString(featureMap));
390             }
391             result.append("\n");
392           }// if
393         }// for
394         stres = result.toString();
395         break;
396       }
397       case STRING_MODE : {
398         stres = content;
399         break;
400       }
401       default{
402         throw new gate.util.GateRuntimeException("Invalid Mode ="+mode
403         +"\nValid modes are:\nLIST_MODE = "+LIST_MODE
404         +"\nSTRING_MODE = "+STRING_MODE);
405       }
406     // switch
407     return stres;
408   }//toString()
409 
410   /** Updates the content of the gaz list with the given parameter.
411    *  Depends on the mode of the gaz list.
412    *  In the case of {@link #LIST_MODE}
413    *  the new content is parsed and loaded as single nodes through the
414    *  {@link java.util.List} interface. In the case of
415    *  {@link #STRING_MODE} the new content
416    *  is stored as a String and is not parsed.
417    *  @param newContent the new content of the gazetteer list */
418   public void updateContent(String newContent) {
419     switch (mode) {
420       case STRING_MODE : {
421         content = newContent;
422         break;
423       }
424       case LIST_MODE : {
425         BufferedReader listReader;
426         listReader = new BufferedReader(new StringReader(newContent));
427         String line;
428         List tempEntries = new ArrayList();
429         try {
430           while (null != (line = listReader.readLine())) {
431             tempEntries.add(new GazetteerNode(line,separator));
432           //while
433           listReader.close();
434         catch (IOException x) {
435           /**should never be thrown*/
436           throw new gate.util.LuckyException("IOException :"+x.getMessage());
437         }
438 
439         isModified = !tempEntries.equals(entries);
440         clear();
441         entries = tempEntries;
442         break;
443       // LIST_MODE
444       default{
445         throw new gate.util.GateRuntimeException("Invalid Mode ="+mode
446         +"\nValid modes are:\nLIST_MODE = "+LIST_MODE
447         +"\nSTRING_MODE = "+STRING_MODE);
448       }// default
449     // switch mode
450   // updateContent(String)
451 
452 
453 // Class GazetteerList