|
|||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
Flags.java | 50% | 72.9% | 89.5% | 69.1% |
|
1 | /** | |
2 | * | |
3 | * Copyright 2003-2004 The Apache Software Foundation | |
4 | * | |
5 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | * you may not use this file except in compliance with the License. | |
7 | * You may obtain a copy of the License at | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, software | |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | * See the License for the specific language governing permissions and | |
15 | * limitations under the License. | |
16 | */ | |
17 | ||
18 | package javax.mail; | |
19 | ||
20 | import java.io.Serializable; | |
21 | import java.util.Hashtable; | |
22 | import java.util.Iterator; | |
23 | import java.util.LinkedList; | |
24 | import java.util.List; | |
25 | ||
26 | /** | |
27 | * Representation of flags that may be associated with a message. | |
28 | * Flags can either be system flags, defined by the {@link Flags.Flag Flag} inner class, | |
29 | * or user-defined flags defined by a String. The system flags represent those expected | |
30 | * to be provided by most folder systems; user-defined flags allow for additional flags | |
31 | * on a per-provider basis. | |
32 | * <p/> | |
33 | * This class is Serializable but compatibility is not guaranteed across releases. | |
34 | * | |
35 | * @version $Rev: 125713 $ $Date: 2005-01-19 21:07:59 -0800 (Wed, 19 Jan 2005) $ | |
36 | */ | |
37 | public class Flags implements Cloneable, Serializable { | |
38 | public static final class Flag { | |
39 | /** | |
40 | * Flag that indicates that the message has been replied to; has a bit value of 1. | |
41 | */ | |
42 | public static final Flag ANSWERED = new Flag(1); | |
43 | /** | |
44 | * Flag that indicates that the message has been marked for deletion and | |
45 | * should be removed on a subsequent expunge operation; has a bit value of 2. | |
46 | */ | |
47 | public static final Flag DELETED = new Flag(2); | |
48 | /** | |
49 | * Flag that indicates that the message is a draft; has a bit value of 4. | |
50 | */ | |
51 | public static final Flag DRAFT = new Flag(4); | |
52 | /** | |
53 | * Flag that indicates that the message has been flagged; has a bit value of 8. | |
54 | */ | |
55 | public static final Flag FLAGGED = new Flag(8); | |
56 | /** | |
57 | * Flag that indicates that the message has been delivered since the last time | |
58 | * this folder was opened; has a bit value of 16. | |
59 | */ | |
60 | public static final Flag RECENT = new Flag(16); | |
61 | /** | |
62 | * Flag that indicates that the message has been viewed; has a bit value of 32. | |
63 | * This flag is set by the {@link Message#getInputStream()} and {@link Message#getContent()} | |
64 | * methods. | |
65 | */ | |
66 | public static final Flag SEEN = new Flag(32); | |
67 | /** | |
68 | * Flags that indicates if this folder supports user-defined flags; has a bit value of 0x80000000. | |
69 | */ | |
70 | public static final Flag USER = new Flag(0x80000000); | |
71 | ||
72 | private final int mask; | |
73 | ||
74 | 7 | private Flag(int mask) { |
75 | 7 | this.mask = mask; |
76 | } | |
77 | } | |
78 | ||
79 | // the Serialized form of this class required the following two fields to be persisted | |
80 | // this leads to a specific type of implementation | |
81 | private int system_flags; | |
82 | private final Hashtable user_flags; | |
83 | ||
84 | /** | |
85 | * Construct a Flags instance with no flags set. | |
86 | */ | |
87 | 27 | public Flags() { |
88 | 27 | user_flags = new Hashtable(); |
89 | } | |
90 | ||
91 | /** | |
92 | * Construct a Flags instance with a supplied system flag set. | |
93 | * @param flag the system flag to set | |
94 | */ | |
95 | 0 | public Flags(Flag flag) { |
96 | 0 | system_flags = flag.mask; |
97 | 0 | user_flags = new Hashtable(); |
98 | } | |
99 | ||
100 | /** | |
101 | * Construct a Flags instance with a same flags set. | |
102 | * @param flags the instance to copy | |
103 | */ | |
104 | 1 | public Flags(Flags flags) { |
105 | 1 | system_flags = flags.system_flags; |
106 | 1 | user_flags = new Hashtable(flags.user_flags); |
107 | } | |
108 | ||
109 | /** | |
110 | * Construct a Flags instance with the supplied user flags set. | |
111 | * Question: should this automatically set the USER system flag? | |
112 | * @param name the user flag to set | |
113 | */ | |
114 | 0 | public Flags(String name) { |
115 | 0 | user_flags = new Hashtable(); |
116 | 0 | user_flags.put(name.toLowerCase(), name); |
117 | } | |
118 | ||
119 | /** | |
120 | * Set a system flag. | |
121 | * @param flag the system flag to set | |
122 | */ | |
123 | 13 | public void add(Flag flag) { |
124 | 13 | system_flags |= flag.mask; |
125 | } | |
126 | ||
127 | /** | |
128 | * Set all system and user flags from the supplied Flags. | |
129 | * Question: do we need to check compatibility of USER flags? | |
130 | * @param flags the Flags to add | |
131 | */ | |
132 | 2 | public void add(Flags flags) { |
133 | 2 | system_flags |= flags.system_flags; |
134 | 2 | user_flags.putAll(flags.user_flags); |
135 | } | |
136 | ||
137 | /** | |
138 | * Set a user flag. | |
139 | * Question: should this fail if the USER system flag is not set? | |
140 | * @param name the user flag to set | |
141 | */ | |
142 | 10 | public void add(String name) { |
143 | 10 | user_flags.put(name.toLowerCase(), name); |
144 | } | |
145 | ||
146 | /** | |
147 | * Return a copy of this instance. | |
148 | * @return a copy of this instance | |
149 | */ | |
150 | 1 | public Object clone() { |
151 | 1 | return new Flags(this); |
152 | } | |
153 | ||
154 | /** | |
155 | * See if the supplied system flags are set | |
156 | * @param flag the system flags to check for | |
157 | * @return true if the flags are set | |
158 | */ | |
159 | 20 | public boolean contains(Flag flag) { |
160 | 20 | return (system_flags & flag.mask) != 0; |
161 | } | |
162 | ||
163 | /** | |
164 | * See if all of the supplied Flags are set | |
165 | * @param flags the flags to check for | |
166 | * @return true if all the supplied system and user flags are set | |
167 | */ | |
168 | 3 | public boolean contains(Flags flags) { |
169 | 3 | return ((system_flags & flags.system_flags) == flags.system_flags) |
170 | && user_flags.keySet().containsAll(flags.user_flags.keySet()); | |
171 | } | |
172 | ||
173 | /** | |
174 | * See if the supplied user flag is set | |
175 | * @param name the user flag to check for | |
176 | * @return true if the flag is set | |
177 | */ | |
178 | 7 | public boolean contains(String name) { |
179 | 7 | return user_flags.containsKey(name.toLowerCase()); |
180 | } | |
181 | ||
182 | /** | |
183 | * Equality is defined as true if the other object is a instanceof Flags with the | |
184 | * same system and user flags set (using a case-insensitive name comparison for user flags). | |
185 | * @param other the instance to compare against | |
186 | * @return true if the two instance are the same | |
187 | */ | |
188 | 2 | public boolean equals(Object other) { |
189 | 0 | if (other == this) return true; |
190 | 0 | if (other instanceof Flags == false) return false; |
191 | 2 | final Flags flags = (Flags) other; |
192 | 2 | return system_flags == flags.system_flags && user_flags.keySet().equals(flags.user_flags.keySet()); |
193 | } | |
194 | ||
195 | /** | |
196 | * Calculate a hashCode for this instance | |
197 | * @return a hashCode for this instance | |
198 | */ | |
199 | 4 | public int hashCode() { |
200 | 4 | return system_flags ^ user_flags.keySet().hashCode(); |
201 | } | |
202 | ||
203 | /** | |
204 | * Return a list of {@link Flags.Flag Flags} containing the system flags that have been set | |
205 | * @return the system flags that have been set | |
206 | */ | |
207 | 1 | public Flag[] getSystemFlags() { |
208 | // assumption: it is quicker to calculate the size than it is to reallocate the array | |
209 | 1 | int size = 0; |
210 | 0 | if ((system_flags & Flag.ANSWERED.mask) != 0) size += 1; |
211 | 0 | if ((system_flags & Flag.DELETED.mask) != 0) size += 1; |
212 | 0 | if ((system_flags & Flag.DRAFT.mask) != 0) size += 1; |
213 | 1 | if ((system_flags & Flag.FLAGGED.mask) != 0) size += 1; |
214 | 1 | if ((system_flags & Flag.RECENT.mask) != 0) size += 1; |
215 | 0 | if ((system_flags & Flag.SEEN.mask) != 0) size += 1; |
216 | 0 | if ((system_flags & Flag.USER.mask) != 0) size += 1; |
217 | 1 | Flag[] result = new Flag[size]; |
218 | 0 | if ((system_flags & Flag.USER.mask) != 0) result[--size] = Flag.USER; |
219 | 0 | if ((system_flags & Flag.SEEN.mask) != 0) result[--size] = Flag.SEEN; |
220 | 1 | if ((system_flags & Flag.RECENT.mask) != 0) result[--size] = Flag.RECENT; |
221 | 1 | if ((system_flags & Flag.FLAGGED.mask) != 0) result[--size] = Flag.FLAGGED; |
222 | 0 | if ((system_flags & Flag.DRAFT.mask) != 0) result[--size] = Flag.DRAFT; |
223 | 0 | if ((system_flags & Flag.DELETED.mask) != 0) result[--size] = Flag.DELETED; |
224 | 0 | if ((system_flags & Flag.ANSWERED.mask) != 0) result[--size] = Flag.ANSWERED; |
225 | 1 | return result; |
226 | } | |
227 | ||
228 | /** | |
229 | * Return a list of user flags that have been set | |
230 | * @return a list of user flags | |
231 | */ | |
232 | 1 | public String[] getUserFlags() { |
233 | 1 | return (String[]) user_flags.values().toArray(new String[user_flags.values().size()]); |
234 | } | |
235 | ||
236 | /** | |
237 | * Unset the supplied system flag. | |
238 | * Question: what happens if we unset the USER flags and user flags are set? | |
239 | * @param flag the flag to clear | |
240 | */ | |
241 | 6 | public void remove(Flag flag) { |
242 | 6 | system_flags &= ~flag.mask; |
243 | } | |
244 | ||
245 | /** | |
246 | * Unset all flags from the supplied instance. | |
247 | * @param flags the flags to clear | |
248 | */ | |
249 | 1 | public void remove(Flags flags) { |
250 | 1 | system_flags &= ~flags.system_flags; |
251 | 1 | user_flags.keySet().removeAll(flags.user_flags.keySet()); |
252 | } | |
253 | ||
254 | /** | |
255 | * Unset the supplied user flag. | |
256 | * @param name the flag to clear | |
257 | */ | |
258 | 1 | public void remove(String name) { |
259 | 1 | user_flags.remove(name.toLowerCase()); |
260 | } | |
261 | } |
|