61 * @see DirContext#getAttributes
62 * @see DirContext#modifyAttributes
63 * @see DirContext#bind
64 * @see DirContext#rebind
65 * @see DirContext#createSubcontext
66 * @see DirContext#search
67 * @since 1.3
68 */
69
70 public class BasicAttributes implements Attributes {
71 /**
72 * Indicates whether case of attribute ids is ignored.
73 * @serial
74 */
75 private boolean ignoreCase = false;
76
77 // The 'key' in attrs is stored in the 'right case'.
78 // If ignoreCase is true, key is aways lowercase.
79 // If ignoreCase is false, key is stored as supplied by put().
80 // %%% Not declared "private" due to bug 4064984.
81 transient Hashtable attrs = new Hashtable(11);
82
83 /**
84 * Constructs a new instance of Attributes.
85 * The character case of attribute identifiers
86 * is significant when subsequently retrieving or adding attributes.
87 */
88 public BasicAttributes() {
89 }
90
91 /**
92 * Constructs a new instance of Attributes.
93 * If <code>ignoreCase</code> is true, the character case of attribute
94 * identifiers is ignored; otherwise the case is significant.
95 * @param ignoreCase true means this attribute set will ignore
96 * the case of its attribute identifiers
97 * when retrieving or adding attributes;
98 * false means case is respected.
99 */
100 public BasicAttributes(boolean ignoreCase) {
101 this.ignoreCase = ignoreCase;
121 * The attribute specified by attrID and val are added to the newly
122 * created attribute.
123 * If <code>ignoreCase</code> is true, the character case of attribute
124 * identifiers is ignored; otherwise the case is significant.
125 * @param attrID non-null The id of the attribute to add.
126 * If this attribute set ignores the character
127 * case of its attribute ids, the case of attrID
128 * is ignored.
129 * @param val The value of the attribute to add. If null, a null
130 * value is added to the attribute.
131 * @param ignoreCase true means this attribute set will ignore
132 * the case of its attribute identifiers
133 * when retrieving or adding attributes;
134 * false means case is respected.
135 */
136 public BasicAttributes(String attrID, Object val, boolean ignoreCase) {
137 this(ignoreCase);
138 this.put(new BasicAttribute(attrID, val));
139 }
140
141 public Object clone() {
142 BasicAttributes attrset;
143 try {
144 attrset = (BasicAttributes)super.clone();
145 } catch (CloneNotSupportedException e) {
146 attrset = new BasicAttributes(ignoreCase);
147 }
148 attrset.attrs = (Hashtable)attrs.clone();
149 return attrset;
150 }
151
152 public boolean isCaseIgnored() {
153 return ignoreCase;
154 }
155
156 public int size() {
157 return attrs.size();
158 }
159
160 public Attribute get(String attrID) {
161 Attribute attr = (Attribute) attrs.get(
162 ignoreCase ? attrID.toLowerCase() : attrID);
163 return (attr);
164 }
165
166 public NamingEnumeration<Attribute> getAll() {
167 return new AttrEnumImpl();
168 }
169
170 public NamingEnumeration<String> getIDs() {
171 return new IDEnumImpl();
172 }
173
174 public Attribute put(String attrID, Object val) {
175 return this.put(new BasicAttribute(attrID, val));
176 }
177
178 public Attribute put(Attribute attr) {
179 String id = attr.getID();
180 if (ignoreCase) {
181 id = id.toLowerCase();
182 }
183 return (Attribute)attrs.put(id, attr);
184 }
185
186 public Attribute remove(String attrID) {
187 String id = (ignoreCase ? attrID.toLowerCase() : attrID);
188 return (Attribute)attrs.remove(id);
189 }
190
191 /**
192 * Generates the string representation of this attribute set.
193 * The string consists of each attribute identifier and the contents
194 * of each attribute. The contents of this string is useful
195 * for debugging and is not meant to be interpreted programmatically.
196 *
197 * @return A non-null string listing the contents of this attribute set.
198 */
199 public String toString() {
200 if (attrs.size() == 0) {
201 return("No attributes");
202 } else {
203 return attrs.toString();
204 }
205 }
206
207 /**
208 * Determines whether this <tt>BasicAttributes</tt> is equal to another
217 * it should override <tt>hashCode()</tt>
218 * as well so that two <tt>Attributes</tt> instances that are equal
219 * have the same hash code.
220 * @param obj the possibly null object to compare against.
221 *
222 * @return true If obj is equal to this BasicAttributes.
223 * @see #hashCode
224 */
225 public boolean equals(Object obj) {
226 if ((obj != null) && (obj instanceof Attributes)) {
227 Attributes target = (Attributes)obj;
228
229 // Check case first
230 if (ignoreCase != target.isCaseIgnored()) {
231 return false;
232 }
233
234 if (size() == target.size()) {
235 Attribute their, mine;
236 try {
237 NamingEnumeration theirs = target.getAll();
238 while (theirs.hasMore()) {
239 their = (Attribute)theirs.next();
240 mine = get(their.getID());
241 if (!their.equals(mine)) {
242 return false;
243 }
244 }
245 } catch (NamingException e) {
246 return false;
247 }
248 return true;
249 }
250 }
251 return false;
252 }
253
254 /**
255 * Calculates the hash code of this BasicAttributes.
256 *<p>
257 * The hash code is computed by adding the hash code of
258 * the attributes of this object. If this BasicAttributes
259 * ignores case of its attribute IDs, one is added to the hash code.
260 * If a subclass overrides <tt>hashCode()</tt>,
261 * it should override <tt>equals()</tt>
262 * as well so that two <tt>Attributes</tt> instances that are equal
263 * have the same hash code.
264 *
265 * @return an int representing the hash code of this BasicAttributes instance.
266 * @see #equals
267 */
268 public int hashCode() {
269 int hash = (ignoreCase ? 1 : 0);
270 try {
271 NamingEnumeration all = getAll();
272 while (all.hasMore()) {
273 hash += all.next().hashCode();
274 }
275 } catch (NamingException e) {}
276 return hash;
277 }
278
279 /**
280 * Overridden to avoid exposing implementation details.
281 * @serialData Default field (ignoreCase flag -- a boolean), followed by
282 * the number of attributes in the set
283 * (an int), and then the individual Attribute objects.
284 */
285 private void writeObject(java.io.ObjectOutputStream s)
286 throws java.io.IOException {
287 s.defaultWriteObject(); // write out the ignoreCase flag
288 s.writeInt(attrs.size());
289 Enumeration attrEnum = attrs.elements();
290 while (attrEnum.hasMoreElements()) {
291 s.writeObject(attrEnum.nextElement());
292 }
293 }
294
295 /**
296 * Overridden to avoid exposing implementation details.
297 */
298 private void readObject(java.io.ObjectInputStream s)
299 throws java.io.IOException, ClassNotFoundException {
300 s.defaultReadObject(); // read in the ignoreCase flag
301 int n = s.readInt(); // number of attributes
302 attrs = (n >= 1)
303 ? new Hashtable(n * 2)
304 : new Hashtable(2); // can't have initial size of 0 (grrr...)
305 while (--n >= 0) {
306 put((Attribute)s.readObject());
307 }
308 }
309
310
311 class AttrEnumImpl implements NamingEnumeration<Attribute> {
312
313 Enumeration<Attribute> elements;
314
315 public AttrEnumImpl() {
316 this.elements = attrs.elements();
317 }
318
319 public boolean hasMoreElements() {
320 return elements.hasMoreElements();
321 }
322
323 public Attribute nextElement() {
324 return elements.nextElement();
|
61 * @see DirContext#getAttributes
62 * @see DirContext#modifyAttributes
63 * @see DirContext#bind
64 * @see DirContext#rebind
65 * @see DirContext#createSubcontext
66 * @see DirContext#search
67 * @since 1.3
68 */
69
70 public class BasicAttributes implements Attributes {
71 /**
72 * Indicates whether case of attribute ids is ignored.
73 * @serial
74 */
75 private boolean ignoreCase = false;
76
77 // The 'key' in attrs is stored in the 'right case'.
78 // If ignoreCase is true, key is aways lowercase.
79 // If ignoreCase is false, key is stored as supplied by put().
80 // %%% Not declared "private" due to bug 4064984.
81 transient Hashtable<String,Attribute> attrs = new Hashtable<>(11);
82
83 /**
84 * Constructs a new instance of Attributes.
85 * The character case of attribute identifiers
86 * is significant when subsequently retrieving or adding attributes.
87 */
88 public BasicAttributes() {
89 }
90
91 /**
92 * Constructs a new instance of Attributes.
93 * If <code>ignoreCase</code> is true, the character case of attribute
94 * identifiers is ignored; otherwise the case is significant.
95 * @param ignoreCase true means this attribute set will ignore
96 * the case of its attribute identifiers
97 * when retrieving or adding attributes;
98 * false means case is respected.
99 */
100 public BasicAttributes(boolean ignoreCase) {
101 this.ignoreCase = ignoreCase;
121 * The attribute specified by attrID and val are added to the newly
122 * created attribute.
123 * If <code>ignoreCase</code> is true, the character case of attribute
124 * identifiers is ignored; otherwise the case is significant.
125 * @param attrID non-null The id of the attribute to add.
126 * If this attribute set ignores the character
127 * case of its attribute ids, the case of attrID
128 * is ignored.
129 * @param val The value of the attribute to add. If null, a null
130 * value is added to the attribute.
131 * @param ignoreCase true means this attribute set will ignore
132 * the case of its attribute identifiers
133 * when retrieving or adding attributes;
134 * false means case is respected.
135 */
136 public BasicAttributes(String attrID, Object val, boolean ignoreCase) {
137 this(ignoreCase);
138 this.put(new BasicAttribute(attrID, val));
139 }
140
141 @SuppressWarnings("unchecked")
142 public Object clone() {
143 BasicAttributes attrset;
144 try {
145 attrset = (BasicAttributes)super.clone();
146 } catch (CloneNotSupportedException e) {
147 attrset = new BasicAttributes(ignoreCase);
148 }
149 attrset.attrs = (Hashtable<String,Attribute>)attrs.clone();
150 return attrset;
151 }
152
153 public boolean isCaseIgnored() {
154 return ignoreCase;
155 }
156
157 public int size() {
158 return attrs.size();
159 }
160
161 public Attribute get(String attrID) {
162 Attribute attr = attrs.get(
163 ignoreCase ? attrID.toLowerCase() : attrID);
164 return (attr);
165 }
166
167 public NamingEnumeration<Attribute> getAll() {
168 return new AttrEnumImpl();
169 }
170
171 public NamingEnumeration<String> getIDs() {
172 return new IDEnumImpl();
173 }
174
175 public Attribute put(String attrID, Object val) {
176 return this.put(new BasicAttribute(attrID, val));
177 }
178
179 public Attribute put(Attribute attr) {
180 String id = attr.getID();
181 if (ignoreCase) {
182 id = id.toLowerCase();
183 }
184 return attrs.put(id, attr);
185 }
186
187 public Attribute remove(String attrID) {
188 String id = (ignoreCase ? attrID.toLowerCase() : attrID);
189 return attrs.remove(id);
190 }
191
192 /**
193 * Generates the string representation of this attribute set.
194 * The string consists of each attribute identifier and the contents
195 * of each attribute. The contents of this string is useful
196 * for debugging and is not meant to be interpreted programmatically.
197 *
198 * @return A non-null string listing the contents of this attribute set.
199 */
200 public String toString() {
201 if (attrs.size() == 0) {
202 return("No attributes");
203 } else {
204 return attrs.toString();
205 }
206 }
207
208 /**
209 * Determines whether this <tt>BasicAttributes</tt> is equal to another
218 * it should override <tt>hashCode()</tt>
219 * as well so that two <tt>Attributes</tt> instances that are equal
220 * have the same hash code.
221 * @param obj the possibly null object to compare against.
222 *
223 * @return true If obj is equal to this BasicAttributes.
224 * @see #hashCode
225 */
226 public boolean equals(Object obj) {
227 if ((obj != null) && (obj instanceof Attributes)) {
228 Attributes target = (Attributes)obj;
229
230 // Check case first
231 if (ignoreCase != target.isCaseIgnored()) {
232 return false;
233 }
234
235 if (size() == target.size()) {
236 Attribute their, mine;
237 try {
238 NamingEnumeration<?> theirs = target.getAll();
239 while (theirs.hasMore()) {
240 their = (Attribute)theirs.next();
241 mine = get(their.getID());
242 if (!their.equals(mine)) {
243 return false;
244 }
245 }
246 } catch (NamingException e) {
247 return false;
248 }
249 return true;
250 }
251 }
252 return false;
253 }
254
255 /**
256 * Calculates the hash code of this BasicAttributes.
257 *<p>
258 * The hash code is computed by adding the hash code of
259 * the attributes of this object. If this BasicAttributes
260 * ignores case of its attribute IDs, one is added to the hash code.
261 * If a subclass overrides <tt>hashCode()</tt>,
262 * it should override <tt>equals()</tt>
263 * as well so that two <tt>Attributes</tt> instances that are equal
264 * have the same hash code.
265 *
266 * @return an int representing the hash code of this BasicAttributes instance.
267 * @see #equals
268 */
269 public int hashCode() {
270 int hash = (ignoreCase ? 1 : 0);
271 try {
272 NamingEnumeration<?> all = getAll();
273 while (all.hasMore()) {
274 hash += all.next().hashCode();
275 }
276 } catch (NamingException e) {}
277 return hash;
278 }
279
280 /**
281 * Overridden to avoid exposing implementation details.
282 * @serialData Default field (ignoreCase flag -- a boolean), followed by
283 * the number of attributes in the set
284 * (an int), and then the individual Attribute objects.
285 */
286 private void writeObject(java.io.ObjectOutputStream s)
287 throws java.io.IOException {
288 s.defaultWriteObject(); // write out the ignoreCase flag
289 s.writeInt(attrs.size());
290 Enumeration<Attribute> attrEnum = attrs.elements();
291 while (attrEnum.hasMoreElements()) {
292 s.writeObject(attrEnum.nextElement());
293 }
294 }
295
296 /**
297 * Overridden to avoid exposing implementation details.
298 */
299 private void readObject(java.io.ObjectInputStream s)
300 throws java.io.IOException, ClassNotFoundException {
301 s.defaultReadObject(); // read in the ignoreCase flag
302 int n = s.readInt(); // number of attributes
303 attrs = (n >= 1)
304 ? new Hashtable<String,Attribute>(n * 2)
305 : new Hashtable<String,Attribute>(2); // can't have initial size of 0 (grrr...)
306 while (--n >= 0) {
307 put((Attribute)s.readObject());
308 }
309 }
310
311
312 class AttrEnumImpl implements NamingEnumeration<Attribute> {
313
314 Enumeration<Attribute> elements;
315
316 public AttrEnumImpl() {
317 this.elements = attrs.elements();
318 }
319
320 public boolean hasMoreElements() {
321 return elements.hasMoreElements();
322 }
323
324 public Attribute nextElement() {
325 return elements.nextElement();
|