1   /*
2    * GazetteerList.java
3    *
4    * Copyright (c) 2002, The University of Sheffield.
5    *
6    * This file is part of GATE (see http://gate.ac.uk/), and is free
7    * software, licenced under the GNU Library General Public License,
8    * Version 2, June1991.
9    *
10   * A copy of this licence is included in the distribution in the file
11   * licence.html, and is also available at http://gate.ac.uk/gate/licence.html.
12   *
13   * borislav popov 02/2002
14   *
15   */
16  
17  package gate.creole.gazetteer;
18  
19  import java.io.*;
20  import java.net.URL;
21  import java.util.*;
22  
23  import gate.creole.ResourceInstantiationException;
24  
25  
26  /** Gazetteer List provides the means for uploading, managing and
27   *  storing the data in the gazetteer list files. */
28  public class GazetteerList extends gate.creole.AbstractLanguageResource
29  implements List {
30  
31    /** indicates list representation of the gazetteer list*/
32    public final static int LIST_MODE = 0;
33  
34    /** indicates representation of the gaz list as a single string */
35    public final static int STRING_MODE = 1;
36  
37    /** the url of this list */
38    private URL url;
39  
40    /**the encoding of the list */
41    private String encoding = "UTF-8";
42  
43    /** indicates the current mode
44     *of the gazetteer list(e.g. STRING_MODE,LIST_MODE) */
45    private int mode = 0 ;
46  
47    /** flag indicating whether the list has been modified after loading/storing */
48    private boolean isModified = false;
49  
50    /** the entries of this list */
51    private List entries = new ArrayList();
52  
53    /** the content of this list */
54    private String content = null;
55  
56    /** create a new gazetteer list */
57    public GazetteerList() {
58    }
59  
60    /** @return true if the list has been modified after load/store  */
61    public boolean isModified() {
62      return isModified;
63    }
64  
65    /**Sets the modified status of the current list
66     * @param modified is modified flag   */
67    public void setModified(boolean modified) {
68      isModified = modified;
69    }
70  
71    /** Retrieves the current mode of the gaz list
72     *  @return the current mode   */
73    public int getMode() { return mode; }
74  
75    /**Sets mode of the gazetteer list
76     * @param m the mode to be set    */
77    public void setMode(int m) {
78      if (m!=mode) {
79      switch (m){
80          case LIST_MODE :{
81            mode = m;
82            updateContent(content);
83            break;
84          } // LIST_MODE
85          case STRING_MODE:{
86            content = this.toString();
87            mode = m;
88            break;
89          } //STRING_MODE
90          default:{
91            throw new gate.util.GateRuntimeException("Invalid Mode ="+mode
92            +"\nValid modes are:\nLIST_MODE = "+LIST_MODE
93            +"\nSTRING_MODE = "+STRING_MODE);
94          } // default
95        } // switch
96      } // only if different from the current
97    } // setMode(int)
98  
99  
100   /** Sets the encoding of the list
101    *  @param encod the encoding to be set */
102   public void setEncoding(String encod) {
103     encoding = encod;
104   }
105 
106   /** Gets the encoding of the list
107    *  @return the encoding of the list*/
108   public String getEncoding() {
109     return encoding;
110   }
111 
112   /**
113    * Loads a gazetteer list
114    * @throws ResourceInstantiationException
115    */
116   public void load() throws ResourceInstantiationException {
117     try {
118       if (null == url) {
119         throw new ResourceInstantiationException("URL not specified (null).");
120       }
121 
122       BufferedReader listReader;
123 
124       listReader = new BufferedReader(new InputStreamReader(
125                               (url).openStream(), encoding));
126       String line;
127       while (null != (line = listReader.readLine())) {
128         entries.add(line);
129       } //while
130 
131       listReader.close();
132     } catch (Exception x) {
133       throw new ResourceInstantiationException(x.getClass()+":"+x.getMessage());
134     }
135     isModified = false;
136   } // load ()
137 
138   /**
139    * Stores the list to the specified url
140    * @throws ResourceInstantiationException
141    */
142   public void store() throws ResourceInstantiationException{
143     try {
144       if (null == url) {
145         throw new ResourceInstantiationException("URL not specified (null)");
146       }
147 
148       URL tempUrl = url;
149       if (-1 != url.getProtocol().indexOf("gate")) {
150         tempUrl = gate.util.protocols.gate.Handler.class.getResource(
151                       gate.util.Files.getResourcePath() + url.getPath()
152                     );
153       } // if gate:path url
154 
155       File fileo = new File(tempUrl.getFile());
156 
157       fileo.delete();
158       OutputStreamWriter listWriter  = new OutputStreamWriter(
159                     new FileOutputStream(fileo), encoding);
160 //      BufferedWriter listWriter = new BufferedWriter(new FileWriter(fileo));
161       Iterator iter = entries.iterator();
162       while (iter.hasNext()) {
163         listWriter.write(iter.next().toString());
164         listWriter.write(13);
165         listWriter.write(10);
166       }
167       listWriter.close();
168     } catch (Exception x) {
169       throw new ResourceInstantiationException(x.getClass()+":"+x.getMessage());
170     }
171     isModified = false;
172   } // store()
173 
174 
175   /**
176    * Sets the URL of the list
177    * @param theUrl the URL of the List
178    */
179   public void setURL(URL theUrl) {
180     url = theUrl;
181     isModified = true;
182   }
183 
184   /**
185    * Gets the URL of the list
186    * @return the URL of the list
187    */
188   public URL getURL() {
189     return url;
190   }
191 
192 /*--------------implementation of java.util.List--------------------*/
193   public int size() {
194     return entries.size();
195   }
196 
197   public boolean isEmpty() {
198     return (0 == entries.size());
199   }
200 
201   public boolean contains(Object o) {
202     return entries.contains(o);
203   } // contains()
204 
205   /**Gets an iterator over the list. It is not dangerous if the iterator is modified since there
206   are no dependencies of entries to other members  */
207   public Iterator iterator() {
208     return entries.iterator();
209   }
210 
211   public Object[] toArray() {
212     return entries.toArray();
213   }
214 
215   public Object[] toArray(Object[] a) {
216     return toArray(a);
217   }
218 
219   public boolean add(Object o) {
220     boolean result = false;
221     if (o instanceof String) {
222       result = entries.add(o);
223     }
224     isModified |= result;
225     return result;
226   } // add()
227 
228   public boolean remove(Object o) {
229     boolean result = entries.remove(o);
230     isModified |= result;
231     return result;
232   }
233 
234   public boolean containsAll(Collection c) {
235     return entries.containsAll(c);
236   }
237 
238   /**
239    * Adds entire collection
240    * @param c a collection to be addded
241    * @return true if all the elements where Strings and all are sucessfully added
242    */
243   public boolean addAll(Collection c) {
244     Iterator iter = c.iterator();
245     Object o;
246     boolean result = false;
247 
248     while (iter.hasNext()) {
249       o = iter.next();
250       if (o instanceof String) {
251         result |= entries.add(o);
252       }
253     } // while
254     isModified |= result;
255 
256     return result;
257   } // addAll(Collection)
258 
259   public boolean addAll(int index, Collection c) {
260     boolean result = entries.addAll(index,c);
261     isModified |= result;
262     return result;
263   } //addAll(int,Collection)
264 
265 
266   public boolean removeAll(Collection c) {
267     boolean result = entries.removeAll(c);
268     isModified |= result;
269     return result;
270   }
271 
272   public boolean retainAll(Collection c) {
273     boolean result = entries.retainAll(c);
274     isModified |= result;
275     return result;
276   }
277 
278   public void clear() {
279     if (0 < entries.size())
280       isModified = true;
281     entries.clear();
282   }
283 
284 
285   public boolean equals(Object o) {
286     boolean result = false;
287     if (o instanceof GazetteerList) {
288       result = true;
289       GazetteerList list2 = (GazetteerList) o;
290       result &= entries.equals(list2.entries);
291     } // if
292     return result;
293   } // equals()
294 
295 
296 
297   public Object get(int index) {
298     return entries.get(index);
299   }
300 
301   public Object set(int index, Object element) {
302     isModified=true;
303     return entries.set(index,element);
304   }
305 
306   public void add(int index, Object element) {
307     isModified = true;
308     entries.add(index,element);
309   }
310 
311   public Object remove(int index) {
312     int size = entries.size();
313     Object result = entries.remove(index);
314     isModified |= (size!=entries.size());
315     return result;
316   }
317 
318   public int indexOf(Object o) {
319     return entries.indexOf(o);
320   }
321 
322   public int lastIndexOf(Object o) {
323     return entries.lastIndexOf(o);
324   }
325 
326   public ListIterator listIterator() {
327     return entries.listIterator();
328   }
329 
330   public ListIterator listIterator(int index) {
331     return entries.listIterator(index);
332   }
333 
334   public List subList(int fromIndex, int toIndex) {
335     return entries.subList(fromIndex,toIndex);
336   }
337 
338 
339   /** Retrieves the string representation of the gaz list
340    *  according to its mode. If
341    *  {@link #LIST_MODE} then all
342    *  the entries are dumped sequentially to a string. If
343    *  {@link #STRING_MODE} then
344    *  the content (a string) of the gaz list is retrieved.
345    *  @return the string representation of the gaz list*/
346   public String toString() {
347     String stres = null;
348     switch (mode) {
349       case LIST_MODE : {
350         StringBuffer result = new StringBuffer();
351         String entry = null;
352         for ( int i = 0 ; i < entries.size() ; i++) {
353           entry = ((String)entries.get(i)).trim();
354           if (entry.length()>0) {
355             result.append(entry);
356             result.append("\n");
357           }// if
358         }// for
359         stres = result.toString();
360         break;
361       }
362       case STRING_MODE : {
363         stres = content;
364         break;
365       }
366       default: {
367         throw new gate.util.GateRuntimeException("Invalid Mode ="+mode
368         +"\nValid modes are:\nLIST_MODE = "+LIST_MODE
369         +"\nSTRING_MODE = "+STRING_MODE);
370       }
371     } // switch
372     return stres;
373   }//toString()
374 
375   /** Updates the content of the gaz list with the given parameter.
376    *  Depends on the mode of the gaz list.
377    *  In the case of {@link #LIST_MODE}
378    *  the new content is parsed and loaded as single nodes through the
379    *  {@link java.util.List} interface. In the case of
380    *  {@link #STRING_MODE} the new content
381    *  is stored as a String and is not parsed.
382    *  @param newContent the new content of the gazetteer list */
383   public void updateContent(String newContent) {
384     switch (mode) {
385       case STRING_MODE : {
386         content = newContent;
387         break;
388       }
389       case LIST_MODE : {
390         BufferedReader listReader;
391         listReader = new BufferedReader(new StringReader(newContent));
392         String line;
393         List tempEntries = new ArrayList();
394         try {
395           while (null != (line = listReader.readLine())) {
396             tempEntries.add(line);
397           } //while
398           listReader.close();
399         } catch (IOException x) {
400           /**should never be thrown*/
401           throw new gate.util.LuckyException("IOException :"+x.getMessage());
402         }
403 
404         isModified = !tempEntries.equals(entries);
405         clear();
406         entries = tempEntries;
407         break;
408       } // LIST_MODE
409       default: {
410         throw new gate.util.GateRuntimeException("Invalid Mode ="+mode
411         +"\nValid modes are:\nLIST_MODE = "+LIST_MODE
412         +"\nSTRING_MODE = "+STRING_MODE);
413       }// default
414     } // switch mode
415   } // updateContent(String)
416 
417 } // Class GazetteerList
418