/[classpath]/inetlib/source/gnu/inet/nntp/FileNewsrc.java
ViewVC logotype

Diff of /inetlib/source/gnu/inet/nntp/FileNewsrc.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by dog, Thu Oct 21 15:21:55 2004 UTC revision 1.6 by dog, Thu Nov 25 22:15:05 2004 UTC
# Line 1  Line 1 
1  /*  /*
2   * $Id$   * FileNewsrc.java
3   * Copyright (C) 2002 The Free Software Foundation   * Copyright (C) 2002 The Free Software Foundation
4   *   *
5   * This file is part of GNU inetlib, a library.   * This file is part of GNU inetlib, a library.
# Line 57  import java.util.Map; Line 57  import java.util.Map;
57   * A .newsrc configuration on a filesystem.   * A .newsrc configuration on a filesystem.
58   *   *
59   * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>   * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
  * @version $Revision$ $Date$  
60   */   */
61  public class FileNewsrc implements Newsrc  public class FileNewsrc
62      implements Newsrc
63  {  {
64    
65    private static final String NEWSRC_ENCODING = "US-ASCII";    private static final String NEWSRC_ENCODING = "US-ASCII";
# Line 77  public class FileNewsrc implements Newsr Line 77  public class FileNewsrc implements Newsr
77     * @param file the disk file     * @param file the disk file
78     * @param debug for debugging information on stderr     * @param debug for debugging information on stderr
79     */     */
80    public FileNewsrc (File file, boolean debug)    public FileNewsrc(File file, boolean debug)
81    {    {
82      this.file = file;      this.file = file;
83      this.debug = debug;      this.debug = debug;
84    }    }
85    
86    public void close ()    public void close()
87    {    {
88      if (!dirty)      if (!dirty)
89        {        {
90          return;          return;
91        }        }
92      save ();      save();
93    }    }
94        
95    /**    /**
96     * Load the file.     * Load the file.
97     */     */
98    void load ()    void load()
99    {    {
100      long fs = file.length ();      long fs = file.length();
101      long max = (long) Integer.MAX_VALUE;      long max = (long) Integer.MAX_VALUE;
102      int bs = (int) (fs > max ? max : fs);      int bs = (int) (fs > max ? max : fs);
103            
104      groups = new LinkedList ();      groups = new LinkedList();
105      lines = new HashMap (bs / 20);      lines = new HashMap(bs / 20);
106      subs = new LinkedList ();      subs = new LinkedList();
107            
108      // Load      // Load
109      try      try
110        {        {
111          long t1 = System.currentTimeMillis ();          long t1 = System.currentTimeMillis();
112          if (debug)          if (debug)
113            {            {
114              System.err.println ("DEBUG: nntp: newsrc loading " +              System.err.println("DEBUG: nntp: newsrc loading " +
115                                  file.getPath ());                                 file.getPath());
116            }            }
117                    
118          FileInputStream fr = new FileInputStream (file);          FileInputStream fr = new FileInputStream(file);
119          InputStreamReader ir = new InputStreamReader (fr, NEWSRC_ENCODING);          InputStreamReader ir = new InputStreamReader(fr, NEWSRC_ENCODING);
120          BufferedReader reader = new BufferedReader (ir, bs);          BufferedReader reader = new BufferedReader(ir, bs);
121          String line = reader.readLine ();          String line = reader.readLine();
122          while (line != null)          while (line != null)
123            {            {
124              int cp = line.indexOf (':');              int cp = line.indexOf(':');
125              if (cp > -1)              if (cp > -1)
126                {                {
127                  // Subscribed newsgroup                  // Subscribed newsgroup
128                  String name = line.substring (0, cp);                  String name = line.substring(0, cp);
129                  groups.add (name);                  groups.add(name);
130                  subs.add (name);                  subs.add(name);
131                  cp++;                  cp++;
132                  if (cp < line.length ())                  if (cp < line.length())
133                    {                    {
134                      String tail = line.substring (cp).trim ();                      String tail = line.substring(cp).trim();
135                      if (tail.length() > 0)                      if (tail.length() > 0)
136                        {                        {
137                          lines.put (name, tail);                          lines.put(name, tail);
138                        }                        }
139                    }                    }
140                }                }
141              else              else
142                {                {
143                  int pp = line.indexOf ('!');                  int pp = line.indexOf('!');
144                  if (pp > -1)                  if (pp > -1)
145                    {                    {
146                      // Unsubscribed newsgroup                      // Unsubscribed newsgroup
147                      String name = line.substring (0, pp);                      String name = line.substring(0, pp);
148                      groups.add (name);                      groups.add(name);
149                      pp++;                      pp++;
150                      if (pp < line.length ())                      if (pp < line.length())
151                        {                        {
152                          String tail = line.substring (pp).trim ();                          String tail = line.substring(pp).trim();
153                          if (tail.length () > 0)                          if (tail.length() > 0)
154                            {                            {
155                              lines.put (name, tail);                              lines.put(name, tail);
156                            }                            }
157                        }                        }
158                    }                    }
159                  // else ignore - comments etc will not be saved!                  // else ignore - comments etc will not be saved!
160                }                }
161              line = reader.readLine ();              line = reader.readLine();
162            }            }
163          reader.close ();          reader.close();
164          long t2 = System.currentTimeMillis ();          long t2 = System.currentTimeMillis();
165          if (debug)          if (debug)
166            {            {
167              System.err.println ("DEBUG: nntp: newsrc load: " +              System.err.println("DEBUG: nntp: newsrc load: " +
168                                  groups.size () + " groups in " +                                 groups.size() + " groups in " +
169                                  (t2 - t1) + "ms");                                 (t2 - t1) + "ms");
170            }            }
171        }        }
172      catch (FileNotFoundException e)      catch (FileNotFoundException e)
# Line 174  public class FileNewsrc implements Newsr Line 174  public class FileNewsrc implements Newsr
174        }        }
175      catch (IOException e)      catch (IOException e)
176        {        {
177          System.err.println ("WARNING: nntp: unable to read newsrc file");          System.err.println("WARNING: nntp: unable to read newsrc file");
178          if (debug)          if (debug)
179            {            {
180              e.printStackTrace (System.err);              e.printStackTrace(System.err);
181            }            }
182        }        }
183      catch (SecurityException e)      catch (SecurityException e)
184        {        {
185          System.err.println ("WARNING: nntp: " +          System.err.println("WARNING: nntp: " +
186                              "no read permission on newsrc file");                             "no read permission on newsrc file");
187        }        }
188      dirty = false;      dirty = false;
189    }    }
# Line 191  public class FileNewsrc implements Newsr Line 191  public class FileNewsrc implements Newsr
191    /**    /**
192     * Save the file.     * Save the file.
193     */     */
194    void save ()    void save()
195    {    {
196      try      try
197        {        {
198          long t1 = System.currentTimeMillis ();          long t1 = System.currentTimeMillis();
199          if (debug)          if (debug)
200            {            {
201              System.err.println ("DEBUG: nntp: newsrc saving " +              System.err.println("DEBUG: nntp: newsrc saving " +
202                                  file.getPath ());                                 file.getPath());
203            }            }
204    
205          int bs = (groups.size() * 20);    // guess an average line length          int bs = (groups.size() * 20);    // guess an average line length
206          FileOutputStream fw = new FileOutputStream (file);          FileOutputStream fw = new FileOutputStream(file);
207          BufferedOutputStream writer = new BufferedOutputStream (fw, bs);          BufferedOutputStream writer = new BufferedOutputStream(fw, bs);
208          for (Iterator i = groups.iterator (); i.hasNext ();)          for (Iterator i = groups.iterator(); i.hasNext();)
209            {            {
210              String group = (String) i.next ();              String group = (String) i.next();
211              StringBuffer buffer = new StringBuffer (group);              StringBuffer buffer = new StringBuffer(group);
212              if (subs.contains (group))              if (subs.contains(group))
213                {                {
214                  buffer.append (':');                  buffer.append(':');
215                }                }
216              else              else
217                {                {
218                  buffer.append ('!');                  buffer.append('!');
219                }                }
220              Object r = lines.get (group);              Object r = lines.get(group);
221              if (r instanceof String)              if (r instanceof String)
222                {                {
223                  buffer.append ((String) r);                  buffer.append((String) r);
224                }                }
225              else              else
226                {                {
227                  RangeList ranges = (RangeList) r;                  RangeList ranges = (RangeList) r;
228                  if (ranges != null)                  if (ranges != null)
229                    {                    {
230                      buffer.append (ranges.toString ());                      buffer.append(ranges.toString());
231                    }                    }
232                }                }
233              buffer.append ('\n');              buffer.append('\n');
234    
235              byte[] bytes = buffer.toString ().getBytes (NEWSRC_ENCODING);              byte[] bytes = buffer.toString().getBytes(NEWSRC_ENCODING);
236              writer.write (bytes);              writer.write(bytes);
237            }            }
238          writer.flush ();          writer.flush();
239          writer.close ();          writer.close();
240    
241          long t2 = System.currentTimeMillis ();          long t2 = System.currentTimeMillis();
242          if (debug)          if (debug)
243            {            {
244              System.err.println("DEBUG: nntp: newsrc save: " +              System.err.println("DEBUG: nntp: newsrc save: " +
245                                 groups.size () + " groups in " +                                 groups.size() + " groups in " +
246                                 (t2 - t1) + "ms");                                 (t2 - t1) + "ms");
247            }            }
248        }        }
249      catch (IOException e)      catch (IOException e)
250        {        {
251          System.err.println ("WARNING: nntp: unable to save newsrc file");          System.err.println("WARNING: nntp: unable to save newsrc file");
252          if (debug)          if (debug)
253            {            {
254              e.printStackTrace (System.err);              e.printStackTrace(System.err);
255            }            }
256        }        }
257      dirty = false;      dirty = false;
# Line 261  public class FileNewsrc implements Newsr Line 261  public class FileNewsrc implements Newsr
261     * Returns an iterator over the names of the currently subscribed     * Returns an iterator over the names of the currently subscribed
262     * newsgroups.     * newsgroups.
263     */     */
264    public Iterator list ()    public Iterator list()
265    {    {
266      if (subs == null)      if (subs == null)
267        {        {
268          load ();          load();
269        }        }
270      return subs.iterator ();      return subs.iterator();
271    }    }
272    
273    public boolean isSubscribed (String newsgroup)    public boolean isSubscribed(String newsgroup)
274    {    {
275      if (subs == null)      if (subs == null)
276        {        {
277          load ();          load();
278        }        }
279      return (subs.contains (newsgroup));      return (subs.contains(newsgroup));
280    }    }
281    
282    public void setSubscribed (String newsgroup, boolean flag)    public void setSubscribed(String newsgroup, boolean flag)
283    {    {
284      if (subs == null)      if (subs == null)
285        {        {
286          load ();          load();
287        }        }
288      if (flag && !groups.contains (newsgroup))      if (flag && !groups.contains(newsgroup))
289        {        {
290          groups.add (newsgroup);          groups.add(newsgroup);
291        }        }
292      boolean subscribed = subs.contains (newsgroup);      boolean subscribed = subs.contains(newsgroup);
293      if (flag && !subscribed)      if (flag && !subscribed)
294        {        {
295          subs.add (newsgroup);          subs.add(newsgroup);
296          dirty = true;          dirty = true;
297        }        }
298      else if (!flag && subscribed)      else if (!flag && subscribed)
299        {        {
300          subs.remove (newsgroup);          subs.remove(newsgroup);
301          dirty = true;          dirty = true;
302        }        }
303    }    }
304    
305    public boolean isSeen (String newsgroup, int article)    public boolean isSeen(String newsgroup, int article)
306    {    {
307      if (subs == null)      if (subs == null)
308        {        {
309          load ();          load();
310        }        }
311      Object value = lines.get (newsgroup);      Object value = lines.get(newsgroup);
312      if (value instanceof String)      if (value instanceof String)
313        {        {
314          value = new RangeList ((String) value);          value = new RangeList((String) value);
315        }        }
316      RangeList ranges = (RangeList) value;      RangeList ranges = (RangeList) value;
317      if (ranges != null)      if (ranges != null)
318        {        {
319          return ranges.isSeen (article);          return ranges.isSeen(article);
320        }        }
321      return false;      return false;
322    }    }
323    
324    public void setSeen (String newsgroup, int article, boolean flag)    public void setSeen(String newsgroup, int article, boolean flag)
325    {    {
326      if (subs == null)      if (subs == null)
327        {        {
328          load ();          load();
329        }        }
330      Object value = lines.get (newsgroup);      Object value = lines.get(newsgroup);
331      if (value instanceof String)      if (value instanceof String)
332        {        {
333          value = new RangeList ((String) value);          value = new RangeList((String) value);
334        }        }
335      RangeList ranges = (RangeList) value;      RangeList ranges = (RangeList) value;
336      if (ranges == null)      if (ranges == null)
337        {        {
338          ranges = new RangeList ();          ranges = new RangeList();
339          lines.put (newsgroup, ranges);          lines.put(newsgroup, ranges);
340          dirty = true;          dirty = true;
341        }        }
342      if (ranges.isSeen (article) != flag)      if (ranges.isSeen(article) != flag)
343        {        {
344          ranges.setSeen (article, flag);          ranges.setSeen(article, flag);
345          dirty = true;          dirty = true;
346        }        }
347    }    }
# Line 355  public class FileNewsrc implements Newsr Line 355  public class FileNewsrc implements Newsr
355    
356      List seen;      List seen;
357    
358      RangeList ()      RangeList()
359      {      {
360        seen = new ArrayList ();        seen = new ArrayList();
361      }      }
362    
363      RangeList (String line)      RangeList(String line)
364      {      {
365        this ();        this();
366        try        try
367          {          {
368            // Parse the line at comma delimiters.            // Parse the line at comma delimiters.
369            int start = 0;            int start = 0;
370            int end = line.indexOf (',');            int end = line.indexOf(',');
371            while (end > start)            while (end > start)
372              {              {
373                String token = line.substring (start, end);                String token = line.substring(start, end);
374                addToken (token);                addToken(token);
375                start = end + 1;                start = end + 1;
376                end = line.indexOf (',', start);                end = line.indexOf(',', start);
377              }              }
378            addToken (line.substring (start));            addToken(line.substring(start));
379          }          }
380        catch (NumberFormatException e)        catch (NumberFormatException e)
381          {          {
382            System.err.println ("ERROR: nntp: bad newsrc format: " + line);            System.err.println("ERROR: nntp: bad newsrc format: " + line);
383          }          }
384      }      }
385    
386      /*      /*
387       * Used during initial parse.       * Used during initial parse.
388       */       */
389      private void addToken (String token) throws NumberFormatException      private void addToken(String token) throws NumberFormatException
390      {      {
391        int hp = token.indexOf ('-');        int hp = token.indexOf('-');
392        if (hp > -1)        if (hp > -1)
393          {          {
394            // Range            // Range
395            String fs = token.substring (0, hp);            String fs = token.substring(0, hp);
396            String ts = token.substring (hp + 1);            String ts = token.substring(hp + 1);
397            int from = Integer.parseInt (fs);            int from = Integer.parseInt(fs);
398            int to = Integer.parseInt (ts);            int to = Integer.parseInt(ts);
399            if (from > -1 && to > -1)            if (from > -1 && to > -1)
400              {              {
401                insert (from, to);                insert(from, to);
402              }              }
403          }          }
404        else        else
405          {          {
406            // Single number            // Single number
407            int number = Integer.parseInt (token);            int number = Integer.parseInt(token);
408            if (number > -1)            if (number > -1)
409              {              {
410                insert (number);                insert(number);
411              }              }
412          }          }
413      }      }
# Line 415  public class FileNewsrc implements Newsr Line 415  public class FileNewsrc implements Newsr
415      /**      /**
416       * Indicates whether the specified article is seen.       * Indicates whether the specified article is seen.
417       */       */
418      public boolean isSeen (int num)      public boolean isSeen(int num)
419      {      {
420        int len = seen.size ();        int len = seen.size();
421        Range[] r = new Range[len];        Range[] r = new Range[len];
422        seen.toArray (r);        seen.toArray(r);
423        for (int i = 0; i < len; i++)        for (int i = 0; i < len; i++)
424          {          {
425            if (r[i].contains (num))            if (r[i].contains(num))
426              {              {
427                return true;                return true;
428              }              }
# Line 433  public class FileNewsrc implements Newsr Line 433  public class FileNewsrc implements Newsr
433      /**      /**
434       * Sets whether the specified article is seen.       * Sets whether the specified article is seen.
435       */       */
436      public void setSeen (int num, boolean flag)      public void setSeen(int num, boolean flag)
437      {      {
438        if (flag)        if (flag)
439          {          {
440            insert (num);            insert(num);
441          }          }
442        else        else
443          {          {
444            remove (num);            remove(num);
445          }          }
446      }      }
447    
# Line 449  public class FileNewsrc implements Newsr Line 449  public class FileNewsrc implements Newsr
449       * Find the index within seen to insert the specified article.       * Find the index within seen to insert the specified article.
450       * The range object at the returned index may already contain num.       * The range object at the returned index may already contain num.
451       */       */
452      int indexOf (int num)      int indexOf(int num)
453      {      {
454        int len = seen.size ();        int len = seen.size();
455        Range[] r = new Range[len];        Range[] r = new Range[len];
456        seen.toArray (r);        seen.toArray(r);
457        for (int i = 0; i < len; i++)        for (int i = 0; i < len; i++)
458          {          {
459            if (r[i].contains (num))            if (r[i].contains(num))
460              {              {
461                return i;                return i;
462              }              }
# Line 472  public class FileNewsrc implements Newsr Line 472  public class FileNewsrc implements Newsr
472        return len;        return len;
473      }      }
474    
475      void insert (int start, int end)      void insert(int start, int end)
476      {      {
477        Range range = new Range (start, end);        Range range = new Range(start, end);
478        int i1 = indexOf (range.from);        int i1 = indexOf(range.from);
479        // range is at end        // range is at end
480        if (i1 == seen.size ())        if (i1 == seen.size())
481          {          {
482            seen.add (range);            seen.add(range);
483            return;            return;
484          }          }
485        Range r1 = (Range) seen.get (i1);        Range r1 = (Range) seen.get(i1);
486        // range is before r1        // range is before r1
487        if (range.to < r1.from)        if (range.to < r1.from)
488          {          {
489            seen.add (i1, range);            seen.add(i1, range);
490            return;            return;
491          }          }
492        // range is a subset of r1        // range is a subset of r1
# Line 495  public class FileNewsrc implements Newsr Line 495  public class FileNewsrc implements Newsr
495            return;            return;
496          }          }
497        // range is a superset of r1        // range is a superset of r1
498        int i2 = indexOf (range.to);        int i2 = indexOf(range.to);
499        Range r2 = (Range) seen.get (i2);        Range r2 = (Range) seen.get(i2);
500        System.err.println ("r2 " + r2 + " i2 " + i2);        System.err.println("r2 " + r2 + " i2 " + i2);
501        // remove all ranges between        // remove all ranges between
502        for (int i = i2; i >= i1; i--)        for (int i = i2; i >= i1; i--)
503          {          {
504            seen.remove (i);            seen.remove(i);
505          }          }
506        // merge        // merge
507        int f = (range.from < r1.from) ? range.from : r1.from;        int f = (range.from < r1.from) ? range.from : r1.from;
508        int t = (range.to > r2.to) ? range.to : r2.to;        int t = (range.to > r2.to) ? range.to : r2.to;
509        range = new Range (f, t);        range = new Range(f, t);
510        seen.add (i1, range);        seen.add(i1, range);
511      }      }
512    
513      void insert (int num)      void insert(int num)
514      {      {
515        insert (num, num);        insert(num, num);
516      }      }
517    
518      void remove (int num)      void remove(int num)
519      {      {
520        int i = indexOf (num);        int i = indexOf(num);
521        Range r = (Range) seen.get (i);        Range r = (Range) seen.get(i);
522        seen.remove (i);        seen.remove(i);
523        // num == r        // num == r
524        if ((r.from == r.to) && (r.to == num))        if ((r.from == r.to) &&(r.to == num))
525          {          {
526            return;            return;
527          }          }
528        // split r        // split r
529        if (r.to > num)        if (r.to > num)
530          {          {
531            Range r2 = new Range (num + 1, r.to);            Range r2 = new Range(num + 1, r.to);
532            seen.add (i, r2);            seen.add(i, r2);
533          }          }
534        if (r.from < num)        if (r.from < num)
535          {          {
536            Range r2 = new Range (r.from, num - 1);            Range r2 = new Range(r.from, num - 1);
537            seen.add (i, r2);            seen.add(i, r2);
538          }          }
539      }      }
540    
541      public String toString ()      public String toString()
542      {      {
543        StringBuffer buf = new StringBuffer ();        StringBuffer buf = new StringBuffer();
544        int len = seen.size ();        int len = seen.size();
545        for (int i = 0; i < len; i++)        for (int i = 0; i < len; i++)
546          {          {
547            Range range = (Range) seen.get (i);            Range range = (Range) seen.get(i);
548            if (i > 0)            if (i > 0)
549              {              {
550                buf.append (',');                buf.append(',');
551              }              }
552            buf.append (range.toString ());            buf.append(range.toString());
553          }          }
554        return buf.toString ();        return buf.toString();
555      }      }
556    
557    }    }
# Line 564  public class FileNewsrc implements Newsr Line 564  public class FileNewsrc implements Newsr
564      int from;      int from;
565      int to;      int to;
566    
567      public Range (int i)      public Range(int i)
568      {      {
569        from = to = i;        from = to = i;
570      }      }
571    
572      public Range (int f, int t)      public Range(int f, int t)
573      {      {
574        if (f > t)        if (f > t)
575          {          {
# Line 583  public class FileNewsrc implements Newsr Line 583  public class FileNewsrc implements Newsr
583          }          }
584      }      }
585    
586      public boolean contains (int num)      public boolean contains(int num)
587      {      {
588        return (num >= from && num <= to);        return (num >= from && num <= to);
589      }      }
590    
591      public String toString ()      public String toString()
592      {      {
593        if (from != to)        if (from != to)
594          {          {
595            return new StringBuffer ()            return new StringBuffer()
596              .append (from)              .append(from)
597              .append ('-')              .append('-')
598              .append (to)              .append(to)
599              .toString ();              .toString();
600          }          }
601        else        else
602          {          {
603            return Integer.toString (from);            return Integer.toString(from);
604          }          }
605      }      }
606    
607    }    }
608    
609  }  }
610    

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26