Skip to content

Package: Utility$Condition

Utility$Condition

Coverage

1: /*
2: * Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
3: *
4: * This program and the accompanying materials are made available under the
5: * terms of the Eclipse Public License v. 2.0, which is available at
6: * http://www.eclipse.org/legal/epl-2.0.
7: *
8: * This Source Code may also be made available under the following Secondary
9: * Licenses when the conditions for such availability set forth in the
10: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11: * version 2 with the GNU Classpath Exception, which is available at
12: * https://www.gnu.org/software/classpath/license.html.
13: *
14: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15: */
16:
17: package org.eclipse.angus.mail.imap;
18:
19: import java.util.Arrays;
20: import java.util.Comparator;
21:
22: import jakarta.mail.*;
23:
24: import org.eclipse.angus.mail.imap.protocol.MessageSet;
25: import org.eclipse.angus.mail.imap.protocol.UIDSet;
26: import java.util.ArrayList;
27: import java.util.List;
28:
29: /**
30: * Holder for some static utility methods.
31: *
32: * @author John Mani
33: * @author Bill Shannon
34: */
35:
36: public final class Utility {
37:
38: // Cannot be initialized
39: private Utility() { }
40:
41: /**
42: * Run thru the given array of messages, apply the given
43: * Condition on each message and generate sets of contiguous
44: * sequence-numbers for the successful messages. If a message
45: * in the given array is found to be expunged, it is ignored.
46: *
47: * ASSERT: Since this method uses and returns message sequence
48: * numbers, you should use this method only when holding the
49: * messageCacheLock.
50: *
51: * @param        msgs        the messages
52: * @param        cond        the condition to check
53: * @return                the MessageSet array
54: */
55: public static MessageSet[] toMessageSet(Message[] msgs, Condition cond) {
56:         List<MessageSet> v = new ArrayList<>(1);
57:         int current, next;
58:
59:         IMAPMessage msg;
60:         for (int i = 0; i < msgs.length; i++) {
61:          msg = (IMAPMessage)msgs[i];
62:          if (msg.isExpunged()) // expunged message, skip it
63:                 continue;
64:
65:          current = msg.getSequenceNumber();
66:          // Apply the condition. If it fails, skip it.
67:          if ((cond != null) && !cond.test(msg))
68:                 continue;
69:         
70:          MessageSet set = new MessageSet();
71:          set.start = current;
72:
73:          // Look for contiguous sequence numbers
74:          for (++i; i < msgs.length; i++) {
75:                 // get next message
76:                 msg = (IMAPMessage)msgs[i];
77:
78:                 if (msg.isExpunged()) // expunged message, skip it
79:                  continue;
80:                 next = msg.getSequenceNumber();
81:
82:                 // Does this message match our condition ?
83:                 if ((cond != null) && !cond.test(msg))
84:                  continue;
85:                 
86:                 if (next == current+1)
87:                  current = next;
88:                 else { // break in sequence
89:                  // We need to reexamine this message at the top of
90:                  // the outer loop, so decrement 'i' to cancel the
91:                  // outer loop's autoincrement
92:                  i--;
93:                  break;
94:                 }
95:          }
96:          set.end = current;
97:          v.add(set);
98:         }
99:         
100:         if (v.isEmpty()) // No valid messages
101:          return null;
102:         else {
103:          return v.toArray(new MessageSet[v.size()]);
104:         }
105: }
106: /**
107: * Sort (a copy of) the given array of messages and then
108: * run thru the sorted array of messages, apply the given
109: * Condition on each message and generate sets of contiguous
110: * sequence-numbers for the successful messages. If a message
111: * in the given array is found to be expunged, it is ignored.
112: *
113: * ASSERT: Since this method uses and returns message sequence
114: * numbers, you should use this method only when holding the
115: * messageCacheLock.
116: *
117: * @param        msgs        the messages
118: * @param        cond        the condition to check
119: * @return                the MessageSet array
120: * @since JavaMail 1.5.4
121: */
122: public static MessageSet[] toMessageSetSorted(Message[] msgs,
123:                                                          Condition cond) {
124:         /*
125:          * XXX - This is quick and dirty. A more efficient strategy would be
126:          * to generate an array of message numbers by applying the condition
127:          * (with zero indicating the message doesn't satisfy the condition),
128:          * sort it, and then convert it to a MessageSet skipping all the zeroes.
129:          */
130:         msgs = msgs.clone();
131:         Arrays.sort(msgs,
132:          new Comparator<Message>() {
133:                 @Override
134:                 public int compare(Message msg1, Message msg2) {
135:                  return msg1.getMessageNumber() - msg2.getMessageNumber();
136:                 }
137:          });
138:         return toMessageSet(msgs, cond);
139: }
140:
141: /**
142: * Return UIDSets for the messages. Note that the UIDs
143: * must have already been fetched for the messages.
144: *
145: * @param        msgs        the messages
146: * @return                the UIDSet array
147: */
148: public static UIDSet[] toUIDSet(Message[] msgs) {
149:         List<UIDSet> v = new ArrayList<>(1);
150:         long current, next;
151:
152:         IMAPMessage msg;
153:         for (int i = 0; i < msgs.length; i++) {
154:          msg = (IMAPMessage)msgs[i];
155:          if (msg.isExpunged()) // expunged message, skip it
156:                 continue;
157:
158:          current = msg.getUID();
159:
160:          UIDSet set = new UIDSet();
161:          set.start = current;
162:
163:          // Look for contiguous UIDs
164:          for (++i; i < msgs.length; i++) {
165:                 // get next message
166:                 msg = (IMAPMessage)msgs[i];
167:
168:                 if (msg.isExpunged()) // expunged message, skip it
169:                  continue;
170:                 next = msg.getUID();
171:
172:                 if (next == current+1)
173:                  current = next;
174:                 else { // break in sequence
175:                  // We need to reexamine this message at the top of
176:                  // the outer loop, so decrement 'i' to cancel the
177:                  // outer loop's autoincrement
178:                  i--;
179:                  break;
180:                 }
181:          }
182:          set.end = current;
183:          v.add(set);
184:         }
185:
186:         if (v.isEmpty()) // No valid messages
187:          return null;
188:         else {
189:          return v.toArray(new UIDSet[v.size()]);
190:         }
191: }
192:
193: /**
194: * Make the ResyncData UIDSet available to IMAPProtocol,
195: * which is in a different package. Note that this class
196: * is not included in the public javadocs, thus "hiding"
197: * this method.
198: *
199: * @param        rd        the ResyncData
200: * @return                the UIDSet array
201: * @since        JavaMail 1.5.1
202: */
203: public static UIDSet[] getResyncUIDSet(ResyncData rd) {
204:         return rd.getUIDSet();
205: }
206:
207: /**
208: * This interface defines the test to be executed in
209: * <code>toMessageSet()</code>.
210: */
211: public static interface Condition {
212:         public boolean test(IMAPMessage message);
213: }
214: }