001: /*
002: * Primitive Collections for Java.
003: * Copyright (C) 2002, 2003 Søren Bak
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019: package bak.pcj.adapter;
020:
021: import bak.pcj.Adapter;
022: import bak.pcj.CharIterator;
023: import bak.pcj.set.CharSet;
024: import bak.pcj.set.AbstractCharSet;
025: import bak.pcj.adapter.IteratorToCharIteratorAdapter;
026: import bak.pcj.util.Exceptions;
027:
028: import java.util.Set;
029:
030: /**
031: * This class represents adaptions of Java Collections Framework
032: * sets to primitive sets of char values.
033: * The adapter is implemented as a wrapper around the set.
034: * Thus, changes to the underlying set are reflected by this
035: * set and vice versa.
036: *
037: * <p>
038: * Adapters from JCF collections to primitive collections will
039: * fail if the JCF collection contains <tt>null</tt> values or
040: * values of the wrong class. However, adapters are not fast
041: * failing in the case that the underlying collection should
042: * contain illegal values. To implement fast failure would require
043: * every operation to check every element of the underlying
044: * collection before doing anything. Instead validation methods
045: * are provided. They can be called using the assertion facility
046: * in the client code:
047: * <pre>
048: * SetToCharSetAdapter s;
049: * ...
050: * <b>assert</b> s.validate();
051: * </pre>
052: * or by letting the adapter throw an exception on illegal values:
053: * <pre>
054: * SetToCharSetAdapter s;
055: * ...
056: * s.evalidate(); // Throws an exception on illegal values
057: * </pre>
058: * Either way, validation must be invoked directly by the client
059: * code.
060: *
061: * @author Søren Bak
062: * @version 1.2 21-08-2003 19:04
063: * @since 1.0
064: */
065: public class SetToCharSetAdapter extends AbstractCharSet implements
066: CharSet {
067:
068: /** The underlying set. */
069: protected Set set;
070:
071: /**
072: * Creates a new adaption to a set of char
073: * values.
074: *
075: * @param set
076: * the underlying set. This set must
077: * consist of values of class
078: * {@link Character Character}. Otherwise a
079: * {@link ClassCastException ClassCastException}
080: * will be thrown by some methods.
081: *
082: * @throws NullPointerException
083: * if <tt>set</tt> is <tt>null</tt>.
084: */
085: public SetToCharSetAdapter(Set set) {
086: if (set == null)
087: Exceptions.nullArgument("set");
088: this .set = set;
089: }
090:
091: /**
092: * Creates a new adaption to a set of char
093: * values. The set to adapt is optionally validated.
094: *
095: * @param set
096: * the underlying set. This set must
097: * consist of values of class
098: * {@link Character Character}. Otherwise a
099: * {@link ClassCastException ClassCastException}
100: * will be thrown by some methods.
101: *
102: * @param validate
103: * indicates whether <tt>set</tt> should
104: * be checked for illegal values.
105: *
106: * @throws NullPointerException
107: * if <tt>set</tt> is <tt>null</tt>.
108: *
109: * @throws IllegalStateException
110: * if <tt>validate</tt> is <tt>true</tt> and
111: * <tt>set</tt> contains a <tt>null</tt> value
112: * or a value that is not of class
113: * {@link Character Character}.
114: */
115: public SetToCharSetAdapter(Set set, boolean validate) {
116: if (set == null)
117: Exceptions.nullArgument("set");
118: this .set = set;
119: if (validate)
120: evalidate();
121: }
122:
123: public boolean add(char v) {
124: return set.add(new Character(v));
125: }
126:
127: public void clear() {
128: set.clear();
129: }
130:
131: public boolean contains(char v) {
132: return set.contains(new Character(v));
133: }
134:
135: public int hashCode() {
136: return set.hashCode();
137: }
138:
139: public CharIterator iterator() {
140: return new IteratorToCharIteratorAdapter(set.iterator());
141: }
142:
143: public boolean remove(char v) {
144: return set.remove(new Character(v));
145: }
146:
147: public int size() {
148: return set.size();
149: }
150:
151: /**
152: * Indicates whether the underlying set is valid for
153: * this adapter. For the underlying set to be valid, it
154: * can only contain {@link Character Character} values and no <tt>null</tt>
155: * values.
156: *
157: * @return <tt>true</tt> if the underlying set is
158: * valid; returns <tt>false</tt> otherwise.
159: */
160: public boolean validate() {
161: return Adapter.isCharAdaptable(set);
162: }
163:
164: /**
165: * Validates the set underlying this adapter and throws
166: * an exception if it is invalid. For the underlying set
167: * to be valid, it can only contain {@link Character Character}
168: * values and no <tt>null</tt> values.
169: *
170: * @throws IllegalStateException
171: * if the underlying set is invalid.
172: */
173: public void evalidate() {
174: if (!validate())
175: Exceptions.cannotAdapt("set");
176: }
177:
178: }
|