KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > columba > ristretto > imap > SequenceSet


1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is Ristretto Mail API.
15  *
16  * The Initial Developers of the Original Code are
17  * Timo Stich and Frederik Dietz.
18  * Portions created by the Initial Developers are Copyright (C) 2004
19  * All Rights Reserved.
20  *
21  * Contributor(s):
22  *
23  * Alternatively, the contents of this file may be used under the terms of
24  * either the GNU General Public License Version 2 or later (the "GPL"), or
25  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26  * in which case the provisions of the GPL or the LGPL are applicable instead
27  * of those above. If you wish to allow use of your version of this file only
28  * under the terms of either the GPL or the LGPL, and not to allow others to
29  * use your version of this file under the terms of the MPL, indicate your
30  * decision by deleting the provisions above and replace them with the notice
31  * and other provisions required by the GPL or the LGPL. If you do not delete
32  * the provisions above, a recipient may use your version of this file under
33  * the terms of any one of the MPL, the GPL or the LGPL.
34  *
35  * ***** END LICENSE BLOCK ***** */

36 package org.columba.ristretto.imap;
37
38 import java.util.Collections JavaDoc;
39 import java.util.Iterator JavaDoc;
40 import java.util.LinkedList JavaDoc;
41 import java.util.List JavaDoc;
42
43 /**
44  * A set of message indices or UIDs.
45  *
46  * @author tstich
47  */

48 public class SequenceSet {
49     
50     private final static SequenceSet all;
51     
52     static {
53         all = new SequenceSet();
54         all.addAll();
55     }
56
57     private List JavaDoc set;
58     
59     /**
60      * Constructs the SequenceSet.
61      *
62      */

63     public SequenceSet() {
64         set = new LinkedList JavaDoc();
65     }
66     
67     /**
68      * Constructs the SequenceSet.
69      *
70      * @param a
71      */

72     public SequenceSet(int a) {
73         this();
74         add(a);
75     }
76
77     /**
78      * Constructs the SequenceSet.
79      *
80      * @param a
81      * @param b
82      */

83     public SequenceSet(int a, int b) {
84         this();
85         add(a,b);
86     }
87
88     /**
89      * Constructs the SequenceSet.
90      *
91      * @param s
92      */

93     public SequenceSet(Integer JavaDoc[] s) {
94         this();
95         for( int i=0; i<s.length; i++) {
96             add( s[i].intValue());
97         }
98     }
99     
100
101     /**
102      * Constructs the SequenceSet.
103      *
104      * @param s
105      * @param offset
106      * @param length
107      */

108     public SequenceSet(int[] s, int offset, int length) {
109         this();
110         for( int i=offset; i<offset + length; i++) {
111             add( s[i]);
112         }
113     }
114     
115     /**
116      * Constructs the SequenceSet.
117      *
118      * @param l
119      */

120     public SequenceSet(List JavaDoc l) {
121         this();
122         Iterator JavaDoc it = l.iterator();
123         while( it.hasNext()) {
124             add(((Integer JavaDoc)it.next()).intValue());
125         }
126     }
127
128     /**
129      * The static set that stands for all messages in the mailbox.
130      *
131      * @return the sequenceset that represents all messages
132      */

133     public static SequenceSet getAll() {
134         return all;
135     }
136     
137     /**
138      * Add the index/UID to the set.
139      *
140      * @param a index/uid
141      */

142     public void add(int a) {
143         set.add(new SequenceEntry(a));
144     }
145     
146     /**
147      * Add the range of a:b to the set.
148      *
149      * @param a start index/uid
150      * @param b end index/uid
151      */

152     public void add(int a, int b) {
153         set.add(new SequenceEntry(a, b));
154     }
155
156     /**
157      * Add a open range (a:*) to the set.
158      *
159      * @param a start index/UID
160      */

161     public void addOpenRange(int a) {
162         set.add(new SequenceEntry(a, SequenceEntry.STAR));
163     }
164     
165     /**
166      * Add all messages to the set.
167      *
168      */

169     public void addAll() {
170         set.add(new SequenceEntry(1,SequenceEntry.STAR));
171     }
172     
173     /**
174      * Compress the set to the shortest possible
175      * representation.
176      *
177      */

178     public void pack() {
179         if( set.size() <= 1 ) return;
180         Collections.sort( set );
181         Iterator JavaDoc it = set.iterator();
182         
183         SequenceEntry a = (SequenceEntry) it.next();
184         SequenceEntry b;
185         
186         while( it.hasNext() ) {
187             b = (SequenceEntry) it.next();
188             if( a.canMergeWith(b)) {
189                 a.merge(b);
190                 it.remove();
191             } else {
192                 a = b;
193             }
194         }
195     }
196     
197
198     /**
199      * @see java.lang.Object#toString()
200      */

201     public String JavaDoc toString() {
202         pack();
203         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
204         Iterator JavaDoc it = set.iterator();
205         result.append( it.next().toString());
206         while( it.hasNext() ) {
207             result.append(',');
208             result.append(it.next().toString());
209         }
210         return result.toString();
211     }
212
213     /**
214      * Computes the length of this set. This method will work only
215      * on SequenceSets that represent indices!
216      *
217      * @param exists the number of exisiting messages in the mailbox
218      * @return the length of the SequenceSet
219      */

220     public int getLength(int exists) {
221         int length = 0;
222         
223         Iterator JavaDoc it = set.iterator();
224         while( it.hasNext() ) {
225             SequenceEntry entry = (SequenceEntry) it.next();
226             
227             switch( entry.getType() ) {
228                 case SequenceEntry.ALL : {
229                     return exists;
230                 }
231                 
232                 case SequenceEntry.OPEN_RANGE : {
233                     length += exists - entry.getA() + 1;
234                     break;
235                 }
236                 
237                 case SequenceEntry.RANGE : {
238                     length += entry.getB() - entry.getA() + 1;
239                     break;
240                 }
241                 
242                 case SequenceEntry.SINGLE : {
243                     length ++;
244                     break;
245                 }
246             }
247         }
248         
249         return length;
250     }
251     
252     /**
253      * Converts the SequenceSet to an array of integers. This method will work only
254      * on SequenceSets that represent indices!
255      *
256      * @param exists exists the number of exisiting messages in the mailbox
257      * @return the array of indices in the SequenceSet.
258      */

259     public int[] toArray(int exists) {
260         pack();
261         int[] result = new int[getLength(exists)];
262         int pos=0;
263         int index=1;
264         
265         Iterator JavaDoc it = set.iterator();
266         while( it.hasNext() ) {
267             SequenceEntry entry = (SequenceEntry) it.next();
268             
269             switch( entry.getType() ) {
270                 case SequenceEntry.ALL : {
271                     for( int i=0; i<exists; i++) {
272                         result[i]=i+1;
273                     }
274                 }
275                 
276                 case SequenceEntry.OPEN_RANGE : {
277                     for( index=entry.getA(); index <= exists ; index++ ) {
278                         result[pos++] = index;
279                     }
280                     break;
281                 }
282                 
283                 case SequenceEntry.RANGE : {
284                     for( index=entry.getA(); index <= entry.getB() ; index++ ) {
285                         result[pos++] = index;
286                     }
287                     break;
288                 }
289                 
290                 case SequenceEntry.SINGLE : {
291                     result[pos++] = entry.getA() == SequenceEntry.STAR ? exists: entry.getA();
292                     break;
293                 }
294             }
295         }
296         
297         
298         return result;
299     }
300 }
301
Popular Tags