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