RichEdit control classes
X-SVN-Rev: 1181
This commit is contained in:
parent
5f7a92e6c0
commit
5cfa36a1fe
529
icu4j/src/com/ibm/richtext/textlayout/attributes/AttributeMap.java
Executable file
529
icu4j/src/com/ibm/richtext/textlayout/attributes/AttributeMap.java
Executable file
@ -0,0 +1,529 @@
|
||||
/*
|
||||
* @(#)$RCSfile: AttributeMap.java,v $ $Revision: 1.1 $ $Date: 2000/04/20 17:33:31 $
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
|
||||
*
|
||||
* The program is provided "as is" without any warranty express or
|
||||
* implied, including the warranty of non-infringement and the implied
|
||||
* warranties of merchantibility and fitness for a particular purpose.
|
||||
* IBM will not be liable for any damages suffered by you as a result
|
||||
* of using the Program. In no event will IBM be liable for any
|
||||
* special, indirect or consequential damages or lost profits even if
|
||||
* IBM has been advised of the possibility of their occurrence. IBM
|
||||
* will not be liable for any third party claims against you.
|
||||
*/
|
||||
// Requires Java2
|
||||
package com.ibm.textlayout.attributes;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* AttributeMap is an immutable Map. Additionally, there are
|
||||
* several methods for common operations (union,
|
||||
* remove, intersect); these methods return new AttributeMap
|
||||
* instances.
|
||||
* <p>
|
||||
* Although any non-null Object can be a key or value in an
|
||||
* AttributeMap, typically the keys are fields of TextAttribute.
|
||||
* @see TextAttribute
|
||||
*/
|
||||
public final class AttributeMap implements java.util.Map,
|
||||
com.ibm.textlayout.attributes.Map,
|
||||
Externalizable {
|
||||
|
||||
static final String COPYRIGHT =
|
||||
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
|
||||
private static final int CURRENT_VERSION = 1;
|
||||
|
||||
private static final long serialVersionUID = 9510803;
|
||||
|
||||
private static final String errString = "StyleSets are immutable.";
|
||||
|
||||
// This is passed to the Hashtable constructor as the
|
||||
// load factor argument. It is chosen to avoid resizing
|
||||
// the Hashtable whenever possible. I think that 1
|
||||
// does this.
|
||||
private static final int LOAD_FACTOR = 1;
|
||||
|
||||
private Hashtable styleTable;
|
||||
private transient AttributeSet cachedKeySet = null;
|
||||
private transient Collection cachedValueCollection = null;
|
||||
private transient Set cachedEntrySet = null;
|
||||
|
||||
/**
|
||||
* An empty AttributeMap.
|
||||
*/
|
||||
public static final AttributeMap EMPTY_ATTRIBUTE_MAP = new AttributeMap();
|
||||
|
||||
// ==============
|
||||
// Constructors
|
||||
// ==============
|
||||
|
||||
/**
|
||||
* Create a new, empty AttributeMap. EMPTY_STYLE_SET can be used
|
||||
* in place of an AttributeMap produced by this constructor.
|
||||
*/
|
||||
public AttributeMap() {
|
||||
|
||||
styleTable = new Hashtable(1, LOAD_FACTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an AttributeMap with the same key-value
|
||||
* entries as the given Map.
|
||||
* @param map a Map whose key-value entries will
|
||||
* become the entries for this AttributeMap. <code>map</code>
|
||||
* is not modified, and must not contain null keys or values.
|
||||
*/
|
||||
public AttributeMap(java.util.Map map) {
|
||||
|
||||
styleTable = new Hashtable(map.size(), LOAD_FACTOR);
|
||||
styleTable.putAll(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an AttributeMap with the same key-value
|
||||
* entries as the given Hashtable.
|
||||
* @param table a Hashtable whose key-value entries will
|
||||
* become the entries for this AttributeMap. <code>table</code>
|
||||
* is not modified.
|
||||
*/
|
||||
public AttributeMap(Hashtable hashtable) {
|
||||
|
||||
this((java.util.Map) hashtable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an AttributeMap with a single entry of
|
||||
* <code>{attribute, value}</code>.
|
||||
* @param attribute the key in this AttributeMap's single entry
|
||||
* @param value the value in this AttributeMap's single entry
|
||||
*/
|
||||
public AttributeMap(Object key, Object value) {
|
||||
|
||||
styleTable = new Hashtable(1, LOAD_FACTOR);
|
||||
|
||||
// hashtable checks value for null
|
||||
styleTable.put(key, value);
|
||||
}
|
||||
|
||||
// For internal use only.
|
||||
private AttributeMap(Hashtable table, boolean clone) {
|
||||
|
||||
if (clone) {
|
||||
styleTable = (Hashtable) table.clone();
|
||||
}
|
||||
else {
|
||||
this.styleTable = table;
|
||||
}
|
||||
}
|
||||
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
|
||||
out.writeInt(CURRENT_VERSION);
|
||||
out.writeInt(styleTable.size());
|
||||
Enumeration e = styleTable.keys();
|
||||
while (e.hasMoreElements()) {
|
||||
Object key = e.nextElement();
|
||||
out.writeObject(AttributeKey.mapAttributeToKey(key));
|
||||
out.writeObject(styleTable.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
public void readExternal(ObjectInput in) throws IOException,
|
||||
ClassNotFoundException {
|
||||
|
||||
if (in.readInt() != CURRENT_VERSION) {
|
||||
throw new IOException("Invalid version of StyleBuffer");
|
||||
}
|
||||
|
||||
int count = in.readInt();
|
||||
for (int i=0; i < count; i += 1) {
|
||||
Object key = AttributeKey.mapKeyToAttribute(in.readObject());
|
||||
Object value = in.readObject();
|
||||
styleTable.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
// ==============
|
||||
// Map interface
|
||||
// ==============
|
||||
|
||||
// queries
|
||||
/**
|
||||
* Return the number of entries in the AttributeMap.
|
||||
* @return the number of entries in the AttributeMap
|
||||
*/
|
||||
public int size() {
|
||||
|
||||
return styleTable.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the number of entries in the AttributeMap
|
||||
* is 0.
|
||||
* @return true if the number of entries in the AttributeMap
|
||||
* is 0
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
|
||||
return styleTable.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given key is in this AttributeMap.
|
||||
* @param key the key to test
|
||||
* @return true if <code>key</code> is in this AttributeMap
|
||||
*/
|
||||
public boolean containsKey(Object key) {
|
||||
|
||||
return styleTable.containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given value is in this AttributeMap.
|
||||
* @param key the value to test
|
||||
* @return true if <code>value</code> is in this AttributeMap
|
||||
*/
|
||||
public boolean containsValue(Object value) {
|
||||
|
||||
return styleTable.containsValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value associated with the given key. If the
|
||||
* key is not in this AttributeMap null is returned.
|
||||
* @param key the key to look up
|
||||
* @return the value associated with <code>key</code>, or
|
||||
* null if <code>key</code> is not in this AttributeMap
|
||||
*/
|
||||
public Object get(Object key) {
|
||||
|
||||
return styleTable.get(key);
|
||||
}
|
||||
|
||||
// modifiers - all throw exceptions
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #addAttribute
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public Object put(Object key, Object value) {
|
||||
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #removeAttributes
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public Object remove(Object key) {
|
||||
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #addAttributes
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public void putAll(java.util.Map t) {
|
||||
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #EMPTY_ATTRIBUTE_MAP
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public void clear() {
|
||||
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
// views
|
||||
|
||||
/**
|
||||
* Return an AttributeSet containing every key in this AttributeMap.
|
||||
* @return an AttributeSet containing every key in this AttributeMap
|
||||
*/
|
||||
public Set keySet() {
|
||||
|
||||
return getKeySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an AttributeSet containing every key in this AttributeMap.
|
||||
* @return an AttributeSet containing every key in this AttributeMap
|
||||
*/
|
||||
public AttributeSet getKeySet() {
|
||||
|
||||
AttributeSet result = cachedKeySet;
|
||||
|
||||
if (result == null) {
|
||||
result = AttributeSet.createKeySet(styleTable);
|
||||
cachedKeySet = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Collection containing every value in this AttributeMap.
|
||||
* @return a Collection containing every value in this AttributeMap
|
||||
*/
|
||||
public Collection values() {
|
||||
|
||||
Collection result = cachedValueCollection;
|
||||
|
||||
if (result == null) {
|
||||
result = Collections.unmodifiableCollection(styleTable.values());
|
||||
cachedValueCollection = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Set containing all entries in this AttributeMap.
|
||||
*/
|
||||
public Set entrySet() {
|
||||
|
||||
Set result = cachedEntrySet;
|
||||
|
||||
if (result == null) {
|
||||
result = Collections.unmodifiableSet(styleTable.entrySet());
|
||||
cachedEntrySet = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean equals(Object rhs) {
|
||||
|
||||
if (rhs == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AttributeMap rhsStyleSet = null;
|
||||
|
||||
try {
|
||||
rhsStyleSet = (AttributeMap) rhs;
|
||||
}
|
||||
catch(ClassCastException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return styleTable.equals(rhsStyleSet.styleTable);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
|
||||
return styleTable.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
||||
return styleTable.toString();
|
||||
}
|
||||
|
||||
// ==============
|
||||
// Operations
|
||||
// ==============
|
||||
|
||||
/**
|
||||
* Return a AttributeMap which contains entries in this AttributeMap,
|
||||
* along with an entry for <attribute, value>. If attribute
|
||||
* is already present in this AttributeMap its value becomes value.
|
||||
*/
|
||||
public AttributeMap addAttribute(Object key, Object value) {
|
||||
|
||||
// try to optimize for case where <key, value> is already there?
|
||||
Hashtable newTable = new Hashtable(styleTable.size() + 1, LOAD_FACTOR);
|
||||
newTable.putAll(styleTable);
|
||||
newTable.put(key, value);
|
||||
return new AttributeMap(newTable, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a AttributeMap which contains entries in this AttributeMap
|
||||
* and in rhs. If an attribute appears in both StyleSets the
|
||||
* value from rhs is used.
|
||||
*/
|
||||
public AttributeMap addAttributes(AttributeMap rhs) {
|
||||
|
||||
int thisSize = size();
|
||||
|
||||
if (thisSize == 0) {
|
||||
return rhs;
|
||||
}
|
||||
|
||||
int otherSize = rhs.size();
|
||||
|
||||
if (otherSize == 0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
Hashtable newTable = new Hashtable(thisSize + otherSize, LOAD_FACTOR);
|
||||
|
||||
newTable.putAll(styleTable);
|
||||
newTable.putAll(rhs);
|
||||
|
||||
return new AttributeMap(newTable, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a AttributeMap which contains entries in this AttributeMap
|
||||
* and in rhs. If an attribute appears in both StyleSets the
|
||||
* value from rhs is used.
|
||||
* The Map's keys and values must be non-null.
|
||||
*/
|
||||
public AttributeMap addAttributes(java.util.Map rhs) {
|
||||
|
||||
if (rhs instanceof AttributeMap) {
|
||||
return addAttributes((AttributeMap)rhs);
|
||||
}
|
||||
|
||||
Hashtable newTable = new Hashtable(size() + rhs.size(), LOAD_FACTOR);
|
||||
|
||||
newTable.putAll(styleTable);
|
||||
newTable.putAll(rhs);
|
||||
|
||||
return new AttributeMap(newTable, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a AttributeMap with the entries in this AttributeMap, but
|
||||
* without attribute as a key.
|
||||
*/
|
||||
public AttributeMap removeAttribute(Object attribute) {
|
||||
|
||||
if (!containsKey(attribute)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
Hashtable newTable = new Hashtable(styleTable.size(), LOAD_FACTOR);
|
||||
newTable.putAll(styleTable);
|
||||
newTable.remove(attribute);
|
||||
|
||||
return new AttributeMap(newTable, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a AttributeMap with the entries of this AttributeMap whose
|
||||
* attributes are <b>not</b> in the Set.
|
||||
*/
|
||||
public AttributeMap removeAttributes(AttributeSet attributes) {
|
||||
|
||||
Set set = attributes;
|
||||
return removeAttributes(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a AttributeMap with the entries of this AttributeMap whose
|
||||
* attributes are <b>not</b> in the Set.
|
||||
*/
|
||||
public AttributeMap removeAttributes(Set attributes) {
|
||||
|
||||
// Create newTable on demand; if null at
|
||||
// end of iteration then return this set.
|
||||
// Should we intersect styleTable.keySet with
|
||||
// attributes instead?
|
||||
|
||||
Hashtable newTable = null;
|
||||
Iterator attrIter = attributes.iterator();
|
||||
while (attrIter.hasNext()) {
|
||||
Object current = attrIter.next();
|
||||
if (current != null && styleTable.containsKey(current)) {
|
||||
if (newTable == null) {
|
||||
newTable = new Hashtable(styleTable.size(), LOAD_FACTOR);
|
||||
newTable.putAll(styleTable);
|
||||
}
|
||||
newTable.remove(current);
|
||||
}
|
||||
}
|
||||
|
||||
if (newTable != null) {
|
||||
return new AttributeMap(newTable, false);
|
||||
}
|
||||
else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a AttributeMap with the keys of this AttributeMap which
|
||||
* are also in the Set. The set must not contain null.
|
||||
*/
|
||||
public AttributeMap intersectWith(AttributeSet attributes) {
|
||||
|
||||
Set set = attributes;
|
||||
return intersectWith(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a AttributeMap with the keys of this AttributeMap which
|
||||
* are also in the Set. The set must not contain null.
|
||||
*/
|
||||
public AttributeMap intersectWith(Set attributes) {
|
||||
|
||||
// For now, forget about optimizing for the case when
|
||||
// the return value is equivalent to this set.
|
||||
|
||||
int attrSize = attributes.size();
|
||||
int styleTableSize = styleTable.size();
|
||||
int size = Math.min(attrSize, styleTableSize);
|
||||
Hashtable newTable = new Hashtable(size, LOAD_FACTOR);
|
||||
|
||||
if (attrSize < styleTableSize) {
|
||||
Iterator attrIter = attributes.iterator();
|
||||
while (attrIter.hasNext()) {
|
||||
Object current = attrIter.next();
|
||||
if (current != null) {
|
||||
Object value = styleTable.get(current);
|
||||
if (value != null) {
|
||||
newTable.put(current, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Iterator attrIter = keySet().iterator();
|
||||
while (attrIter.hasNext()) {
|
||||
Object current = attrIter.next();
|
||||
if (attributes.contains(current)) {
|
||||
newTable.put(current, styleTable.get(current));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new AttributeMap(newTable, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put all entries in this AttributeMap into the given Map.
|
||||
* @param rhs the Map into which entries are placed
|
||||
*/
|
||||
public void putAllInto(java.util.Map rhs) {
|
||||
|
||||
rhs.putAll(this);
|
||||
}
|
||||
}
|
345
icu4j/src/com/ibm/richtext/textlayout/attributes/AttributeSet.java
Executable file
345
icu4j/src/com/ibm/richtext/textlayout/attributes/AttributeSet.java
Executable file
@ -0,0 +1,345 @@
|
||||
/*
|
||||
* @(#)$RCSfile: AttributeSet.java,v $ $Revision: 1.1 $ $Date: 2000/04/20 17:33:31 $
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
|
||||
*
|
||||
* The program is provided "as is" without any warranty express or
|
||||
* implied, including the warranty of non-infringement and the implied
|
||||
* warranties of merchantibility and fitness for a particular purpose.
|
||||
* IBM will not be liable for any damages suffered by you as a result
|
||||
* of using the Program. In no event will IBM be liable for any
|
||||
* special, indirect or consequential damages or lost profits even if
|
||||
* IBM has been advised of the possibility of their occurrence. IBM
|
||||
* will not be liable for any third party claims against you.
|
||||
*/
|
||||
// Requires Java2
|
||||
package com.ibm.textlayout.attributes;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* An AttributeSet is an immutable collection of unique Objects.
|
||||
* It has several operations
|
||||
* which return new AttributeSet instances.
|
||||
*/
|
||||
public final class AttributeSet implements Set {
|
||||
|
||||
static final String COPYRIGHT =
|
||||
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
|
||||
|
||||
/**
|
||||
* An AttributeSet with no members.
|
||||
*/
|
||||
public static final AttributeSet EMPTY_SET = new AttributeSet();
|
||||
|
||||
private Hashtable elements;
|
||||
|
||||
private static final String errString = "AttributeSet is immutable.";
|
||||
|
||||
private AttributeSet(Hashtable elements) {
|
||||
|
||||
this.elements = elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Package only. For AttributeMap use.
|
||||
*/
|
||||
static AttributeSet createKeySet(Hashtable hashtable) {
|
||||
|
||||
Hashtable newElements = new Hashtable();
|
||||
|
||||
Enumeration e = hashtable.keys();
|
||||
while (e.hasMoreElements()) {
|
||||
Object next = e.nextElement();
|
||||
newElements.put(next, next);
|
||||
}
|
||||
|
||||
return new AttributeSet(newElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new, empty AttributeSet. The set is semantically
|
||||
* equivalent to EMPTY_SET.
|
||||
*/
|
||||
public AttributeSet() {
|
||||
|
||||
elements = new Hashtable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new AttributeSet with the single element elem.
|
||||
*/
|
||||
public AttributeSet(Object elem) {
|
||||
|
||||
elements = new Hashtable(1, 1);
|
||||
elements.put(elem, elem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new AttributeSet containing the items in the array elems.
|
||||
*/
|
||||
public AttributeSet(Object[] elems) {
|
||||
|
||||
elements = new Hashtable(elems.length, 1);
|
||||
for (int i=0; i < elems.length; i++) {
|
||||
Object next = elems[i];
|
||||
elements.put(next, next);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the number of elements in this set is 0.
|
||||
* @return true if the number of elements in this set is 0
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
|
||||
return elements.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of elements in this set.
|
||||
* @return the number of elements in this set
|
||||
*/
|
||||
public int size() {
|
||||
|
||||
return elements.size();
|
||||
}
|
||||
|
||||
public boolean equals(Object rhs) {
|
||||
|
||||
try {
|
||||
return equals((AttributeSet) rhs);
|
||||
}
|
||||
catch(ClassCastException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(AttributeSet rhs) {
|
||||
|
||||
if (rhs == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return elements.equals(rhs.elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this set contains the given Object
|
||||
* @return true if this set contains <code>o</code>
|
||||
*/
|
||||
public boolean contains(Object o) {
|
||||
|
||||
Object value = elements.get(o);
|
||||
return value != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this set contains all elements in the given
|
||||
* Collection
|
||||
* @param coll the collection to compare with
|
||||
* @return true if this set contains all elements in the given
|
||||
* Collection
|
||||
*/
|
||||
public boolean containsAll(Collection coll) {
|
||||
|
||||
return elements.keySet().containsAll(coll);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an Enumeration of the elements in this set.
|
||||
* @return an Enumeration of the elements in this set
|
||||
*/
|
||||
public Enumeration elements() {
|
||||
|
||||
return elements.keys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an Iterator with the elements in this set.
|
||||
* @return an Iterator with the elements in this set.
|
||||
* The Iterator cannot be used to modify this AttributeSet.
|
||||
*/
|
||||
public Iterator iterator() {
|
||||
|
||||
return new EnumerationIterator(elements.keys());
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in the given array with the elements in this set.
|
||||
* @param storage an array to fill with this set's elements.
|
||||
* The array cannot be null.
|
||||
* @return the <tt>storage</tt> array.
|
||||
*/
|
||||
public Object[] toArray(Object[] storage) {
|
||||
|
||||
Enumeration keys = elements.keys();
|
||||
int n=0;
|
||||
while (keys.hasMoreElements()) {
|
||||
storage[n++] = keys.nextElement();
|
||||
}
|
||||
return storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array with the elements in this set.
|
||||
* @return an array with the elements in this set
|
||||
*/
|
||||
public Object[] toArray() {
|
||||
|
||||
return toArray(new Object[size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #addElement
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public boolean add(Object o){
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public boolean remove(Object o) {
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #unionWith
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public boolean addAll(Collection coll) {
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #subtract
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public boolean removeAll(Collection coll) {
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #intersectWith
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public boolean retainAll(Collection coll) {
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #EMPTY_SET
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public void clear() {
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an AttributeSet containing the elements of this set
|
||||
* and the given element
|
||||
* @param element the element to add
|
||||
* @return an AttributeSet like this one, with <code>element</code>
|
||||
* added
|
||||
*/
|
||||
public AttributeSet addElement(Object element) {
|
||||
|
||||
Hashtable newElements = (Hashtable) elements.clone();
|
||||
newElements.put(element, element);
|
||||
return new AttributeSet(newElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an AttributeSet which is the union of
|
||||
* this set with the given set.
|
||||
* @param s the set to union with
|
||||
* @return an AttributeSet of the elements in this set or
|
||||
* in <code>s</code>
|
||||
*/
|
||||
public AttributeSet unionWith(AttributeSet s) {
|
||||
|
||||
Hashtable newElements = (Hashtable) elements.clone();
|
||||
|
||||
Iterator iter = s.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Object next = iter.next();
|
||||
newElements.put(next, next);
|
||||
}
|
||||
|
||||
return new AttributeSet(newElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an AttributeSet which is the intersection of
|
||||
* this set with the given set.
|
||||
* @param s the set to intersect with
|
||||
* @return an AttributeSet of the elements in this set which
|
||||
* are in <code>s</code>
|
||||
*/
|
||||
public AttributeSet intersectWith(AttributeSet s) {
|
||||
|
||||
Hashtable newElements = new Hashtable();
|
||||
|
||||
Iterator iter = s.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Object next = iter.next();
|
||||
if (elements.get(next) != null) {
|
||||
newElements.put(next, next);
|
||||
}
|
||||
}
|
||||
|
||||
return new AttributeSet(newElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an AttributeSet with the elements in this set which
|
||||
* are not in the given set.
|
||||
* @param s the set of elements to exclude
|
||||
* @return an AttributeSet of the elements in this set which
|
||||
* are not in <code>s</code>
|
||||
*/
|
||||
public AttributeSet subtract(AttributeSet s) {
|
||||
|
||||
Hashtable newElements = (Hashtable) elements.clone();
|
||||
|
||||
Iterator iter = s.iterator();
|
||||
while (iter.hasNext()) {
|
||||
newElements.remove(iter.next());
|
||||
}
|
||||
|
||||
return new AttributeSet(newElements);
|
||||
}
|
||||
|
||||
private static final class EnumerationIterator implements Iterator {
|
||||
|
||||
private Enumeration e;
|
||||
|
||||
EnumerationIterator(Enumeration e) {
|
||||
this.e = e;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return e.hasMoreElements();
|
||||
}
|
||||
|
||||
public Object next() {
|
||||
return e.nextElement();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
}
|
||||
}
|
529
icu4j/src/com/ibm/textlayout/attributes/AttributeMap.java
Executable file
529
icu4j/src/com/ibm/textlayout/attributes/AttributeMap.java
Executable file
@ -0,0 +1,529 @@
|
||||
/*
|
||||
* @(#)$RCSfile: AttributeMap.java,v $ $Revision: 1.1 $ $Date: 2000/04/20 17:33:31 $
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
|
||||
*
|
||||
* The program is provided "as is" without any warranty express or
|
||||
* implied, including the warranty of non-infringement and the implied
|
||||
* warranties of merchantibility and fitness for a particular purpose.
|
||||
* IBM will not be liable for any damages suffered by you as a result
|
||||
* of using the Program. In no event will IBM be liable for any
|
||||
* special, indirect or consequential damages or lost profits even if
|
||||
* IBM has been advised of the possibility of their occurrence. IBM
|
||||
* will not be liable for any third party claims against you.
|
||||
*/
|
||||
// Requires Java2
|
||||
package com.ibm.textlayout.attributes;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* AttributeMap is an immutable Map. Additionally, there are
|
||||
* several methods for common operations (union,
|
||||
* remove, intersect); these methods return new AttributeMap
|
||||
* instances.
|
||||
* <p>
|
||||
* Although any non-null Object can be a key or value in an
|
||||
* AttributeMap, typically the keys are fields of TextAttribute.
|
||||
* @see TextAttribute
|
||||
*/
|
||||
public final class AttributeMap implements java.util.Map,
|
||||
com.ibm.textlayout.attributes.Map,
|
||||
Externalizable {
|
||||
|
||||
static final String COPYRIGHT =
|
||||
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
|
||||
private static final int CURRENT_VERSION = 1;
|
||||
|
||||
private static final long serialVersionUID = 9510803;
|
||||
|
||||
private static final String errString = "StyleSets are immutable.";
|
||||
|
||||
// This is passed to the Hashtable constructor as the
|
||||
// load factor argument. It is chosen to avoid resizing
|
||||
// the Hashtable whenever possible. I think that 1
|
||||
// does this.
|
||||
private static final int LOAD_FACTOR = 1;
|
||||
|
||||
private Hashtable styleTable;
|
||||
private transient AttributeSet cachedKeySet = null;
|
||||
private transient Collection cachedValueCollection = null;
|
||||
private transient Set cachedEntrySet = null;
|
||||
|
||||
/**
|
||||
* An empty AttributeMap.
|
||||
*/
|
||||
public static final AttributeMap EMPTY_ATTRIBUTE_MAP = new AttributeMap();
|
||||
|
||||
// ==============
|
||||
// Constructors
|
||||
// ==============
|
||||
|
||||
/**
|
||||
* Create a new, empty AttributeMap. EMPTY_STYLE_SET can be used
|
||||
* in place of an AttributeMap produced by this constructor.
|
||||
*/
|
||||
public AttributeMap() {
|
||||
|
||||
styleTable = new Hashtable(1, LOAD_FACTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an AttributeMap with the same key-value
|
||||
* entries as the given Map.
|
||||
* @param map a Map whose key-value entries will
|
||||
* become the entries for this AttributeMap. <code>map</code>
|
||||
* is not modified, and must not contain null keys or values.
|
||||
*/
|
||||
public AttributeMap(java.util.Map map) {
|
||||
|
||||
styleTable = new Hashtable(map.size(), LOAD_FACTOR);
|
||||
styleTable.putAll(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an AttributeMap with the same key-value
|
||||
* entries as the given Hashtable.
|
||||
* @param table a Hashtable whose key-value entries will
|
||||
* become the entries for this AttributeMap. <code>table</code>
|
||||
* is not modified.
|
||||
*/
|
||||
public AttributeMap(Hashtable hashtable) {
|
||||
|
||||
this((java.util.Map) hashtable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an AttributeMap with a single entry of
|
||||
* <code>{attribute, value}</code>.
|
||||
* @param attribute the key in this AttributeMap's single entry
|
||||
* @param value the value in this AttributeMap's single entry
|
||||
*/
|
||||
public AttributeMap(Object key, Object value) {
|
||||
|
||||
styleTable = new Hashtable(1, LOAD_FACTOR);
|
||||
|
||||
// hashtable checks value for null
|
||||
styleTable.put(key, value);
|
||||
}
|
||||
|
||||
// For internal use only.
|
||||
private AttributeMap(Hashtable table, boolean clone) {
|
||||
|
||||
if (clone) {
|
||||
styleTable = (Hashtable) table.clone();
|
||||
}
|
||||
else {
|
||||
this.styleTable = table;
|
||||
}
|
||||
}
|
||||
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
|
||||
out.writeInt(CURRENT_VERSION);
|
||||
out.writeInt(styleTable.size());
|
||||
Enumeration e = styleTable.keys();
|
||||
while (e.hasMoreElements()) {
|
||||
Object key = e.nextElement();
|
||||
out.writeObject(AttributeKey.mapAttributeToKey(key));
|
||||
out.writeObject(styleTable.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
public void readExternal(ObjectInput in) throws IOException,
|
||||
ClassNotFoundException {
|
||||
|
||||
if (in.readInt() != CURRENT_VERSION) {
|
||||
throw new IOException("Invalid version of StyleBuffer");
|
||||
}
|
||||
|
||||
int count = in.readInt();
|
||||
for (int i=0; i < count; i += 1) {
|
||||
Object key = AttributeKey.mapKeyToAttribute(in.readObject());
|
||||
Object value = in.readObject();
|
||||
styleTable.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
// ==============
|
||||
// Map interface
|
||||
// ==============
|
||||
|
||||
// queries
|
||||
/**
|
||||
* Return the number of entries in the AttributeMap.
|
||||
* @return the number of entries in the AttributeMap
|
||||
*/
|
||||
public int size() {
|
||||
|
||||
return styleTable.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the number of entries in the AttributeMap
|
||||
* is 0.
|
||||
* @return true if the number of entries in the AttributeMap
|
||||
* is 0
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
|
||||
return styleTable.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given key is in this AttributeMap.
|
||||
* @param key the key to test
|
||||
* @return true if <code>key</code> is in this AttributeMap
|
||||
*/
|
||||
public boolean containsKey(Object key) {
|
||||
|
||||
return styleTable.containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given value is in this AttributeMap.
|
||||
* @param key the value to test
|
||||
* @return true if <code>value</code> is in this AttributeMap
|
||||
*/
|
||||
public boolean containsValue(Object value) {
|
||||
|
||||
return styleTable.containsValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value associated with the given key. If the
|
||||
* key is not in this AttributeMap null is returned.
|
||||
* @param key the key to look up
|
||||
* @return the value associated with <code>key</code>, or
|
||||
* null if <code>key</code> is not in this AttributeMap
|
||||
*/
|
||||
public Object get(Object key) {
|
||||
|
||||
return styleTable.get(key);
|
||||
}
|
||||
|
||||
// modifiers - all throw exceptions
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #addAttribute
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public Object put(Object key, Object value) {
|
||||
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #removeAttributes
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public Object remove(Object key) {
|
||||
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #addAttributes
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public void putAll(java.util.Map t) {
|
||||
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #EMPTY_ATTRIBUTE_MAP
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public void clear() {
|
||||
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
// views
|
||||
|
||||
/**
|
||||
* Return an AttributeSet containing every key in this AttributeMap.
|
||||
* @return an AttributeSet containing every key in this AttributeMap
|
||||
*/
|
||||
public Set keySet() {
|
||||
|
||||
return getKeySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an AttributeSet containing every key in this AttributeMap.
|
||||
* @return an AttributeSet containing every key in this AttributeMap
|
||||
*/
|
||||
public AttributeSet getKeySet() {
|
||||
|
||||
AttributeSet result = cachedKeySet;
|
||||
|
||||
if (result == null) {
|
||||
result = AttributeSet.createKeySet(styleTable);
|
||||
cachedKeySet = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Collection containing every value in this AttributeMap.
|
||||
* @return a Collection containing every value in this AttributeMap
|
||||
*/
|
||||
public Collection values() {
|
||||
|
||||
Collection result = cachedValueCollection;
|
||||
|
||||
if (result == null) {
|
||||
result = Collections.unmodifiableCollection(styleTable.values());
|
||||
cachedValueCollection = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Set containing all entries in this AttributeMap.
|
||||
*/
|
||||
public Set entrySet() {
|
||||
|
||||
Set result = cachedEntrySet;
|
||||
|
||||
if (result == null) {
|
||||
result = Collections.unmodifiableSet(styleTable.entrySet());
|
||||
cachedEntrySet = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean equals(Object rhs) {
|
||||
|
||||
if (rhs == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AttributeMap rhsStyleSet = null;
|
||||
|
||||
try {
|
||||
rhsStyleSet = (AttributeMap) rhs;
|
||||
}
|
||||
catch(ClassCastException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return styleTable.equals(rhsStyleSet.styleTable);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
|
||||
return styleTable.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
||||
return styleTable.toString();
|
||||
}
|
||||
|
||||
// ==============
|
||||
// Operations
|
||||
// ==============
|
||||
|
||||
/**
|
||||
* Return a AttributeMap which contains entries in this AttributeMap,
|
||||
* along with an entry for <attribute, value>. If attribute
|
||||
* is already present in this AttributeMap its value becomes value.
|
||||
*/
|
||||
public AttributeMap addAttribute(Object key, Object value) {
|
||||
|
||||
// try to optimize for case where <key, value> is already there?
|
||||
Hashtable newTable = new Hashtable(styleTable.size() + 1, LOAD_FACTOR);
|
||||
newTable.putAll(styleTable);
|
||||
newTable.put(key, value);
|
||||
return new AttributeMap(newTable, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a AttributeMap which contains entries in this AttributeMap
|
||||
* and in rhs. If an attribute appears in both StyleSets the
|
||||
* value from rhs is used.
|
||||
*/
|
||||
public AttributeMap addAttributes(AttributeMap rhs) {
|
||||
|
||||
int thisSize = size();
|
||||
|
||||
if (thisSize == 0) {
|
||||
return rhs;
|
||||
}
|
||||
|
||||
int otherSize = rhs.size();
|
||||
|
||||
if (otherSize == 0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
Hashtable newTable = new Hashtable(thisSize + otherSize, LOAD_FACTOR);
|
||||
|
||||
newTable.putAll(styleTable);
|
||||
newTable.putAll(rhs);
|
||||
|
||||
return new AttributeMap(newTable, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a AttributeMap which contains entries in this AttributeMap
|
||||
* and in rhs. If an attribute appears in both StyleSets the
|
||||
* value from rhs is used.
|
||||
* The Map's keys and values must be non-null.
|
||||
*/
|
||||
public AttributeMap addAttributes(java.util.Map rhs) {
|
||||
|
||||
if (rhs instanceof AttributeMap) {
|
||||
return addAttributes((AttributeMap)rhs);
|
||||
}
|
||||
|
||||
Hashtable newTable = new Hashtable(size() + rhs.size(), LOAD_FACTOR);
|
||||
|
||||
newTable.putAll(styleTable);
|
||||
newTable.putAll(rhs);
|
||||
|
||||
return new AttributeMap(newTable, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a AttributeMap with the entries in this AttributeMap, but
|
||||
* without attribute as a key.
|
||||
*/
|
||||
public AttributeMap removeAttribute(Object attribute) {
|
||||
|
||||
if (!containsKey(attribute)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
Hashtable newTable = new Hashtable(styleTable.size(), LOAD_FACTOR);
|
||||
newTable.putAll(styleTable);
|
||||
newTable.remove(attribute);
|
||||
|
||||
return new AttributeMap(newTable, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a AttributeMap with the entries of this AttributeMap whose
|
||||
* attributes are <b>not</b> in the Set.
|
||||
*/
|
||||
public AttributeMap removeAttributes(AttributeSet attributes) {
|
||||
|
||||
Set set = attributes;
|
||||
return removeAttributes(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a AttributeMap with the entries of this AttributeMap whose
|
||||
* attributes are <b>not</b> in the Set.
|
||||
*/
|
||||
public AttributeMap removeAttributes(Set attributes) {
|
||||
|
||||
// Create newTable on demand; if null at
|
||||
// end of iteration then return this set.
|
||||
// Should we intersect styleTable.keySet with
|
||||
// attributes instead?
|
||||
|
||||
Hashtable newTable = null;
|
||||
Iterator attrIter = attributes.iterator();
|
||||
while (attrIter.hasNext()) {
|
||||
Object current = attrIter.next();
|
||||
if (current != null && styleTable.containsKey(current)) {
|
||||
if (newTable == null) {
|
||||
newTable = new Hashtable(styleTable.size(), LOAD_FACTOR);
|
||||
newTable.putAll(styleTable);
|
||||
}
|
||||
newTable.remove(current);
|
||||
}
|
||||
}
|
||||
|
||||
if (newTable != null) {
|
||||
return new AttributeMap(newTable, false);
|
||||
}
|
||||
else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a AttributeMap with the keys of this AttributeMap which
|
||||
* are also in the Set. The set must not contain null.
|
||||
*/
|
||||
public AttributeMap intersectWith(AttributeSet attributes) {
|
||||
|
||||
Set set = attributes;
|
||||
return intersectWith(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a AttributeMap with the keys of this AttributeMap which
|
||||
* are also in the Set. The set must not contain null.
|
||||
*/
|
||||
public AttributeMap intersectWith(Set attributes) {
|
||||
|
||||
// For now, forget about optimizing for the case when
|
||||
// the return value is equivalent to this set.
|
||||
|
||||
int attrSize = attributes.size();
|
||||
int styleTableSize = styleTable.size();
|
||||
int size = Math.min(attrSize, styleTableSize);
|
||||
Hashtable newTable = new Hashtable(size, LOAD_FACTOR);
|
||||
|
||||
if (attrSize < styleTableSize) {
|
||||
Iterator attrIter = attributes.iterator();
|
||||
while (attrIter.hasNext()) {
|
||||
Object current = attrIter.next();
|
||||
if (current != null) {
|
||||
Object value = styleTable.get(current);
|
||||
if (value != null) {
|
||||
newTable.put(current, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Iterator attrIter = keySet().iterator();
|
||||
while (attrIter.hasNext()) {
|
||||
Object current = attrIter.next();
|
||||
if (attributes.contains(current)) {
|
||||
newTable.put(current, styleTable.get(current));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new AttributeMap(newTable, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put all entries in this AttributeMap into the given Map.
|
||||
* @param rhs the Map into which entries are placed
|
||||
*/
|
||||
public void putAllInto(java.util.Map rhs) {
|
||||
|
||||
rhs.putAll(this);
|
||||
}
|
||||
}
|
345
icu4j/src/com/ibm/textlayout/attributes/AttributeSet.java
Executable file
345
icu4j/src/com/ibm/textlayout/attributes/AttributeSet.java
Executable file
@ -0,0 +1,345 @@
|
||||
/*
|
||||
* @(#)$RCSfile: AttributeSet.java,v $ $Revision: 1.1 $ $Date: 2000/04/20 17:33:31 $
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
|
||||
*
|
||||
* The program is provided "as is" without any warranty express or
|
||||
* implied, including the warranty of non-infringement and the implied
|
||||
* warranties of merchantibility and fitness for a particular purpose.
|
||||
* IBM will not be liable for any damages suffered by you as a result
|
||||
* of using the Program. In no event will IBM be liable for any
|
||||
* special, indirect or consequential damages or lost profits even if
|
||||
* IBM has been advised of the possibility of their occurrence. IBM
|
||||
* will not be liable for any third party claims against you.
|
||||
*/
|
||||
// Requires Java2
|
||||
package com.ibm.textlayout.attributes;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* An AttributeSet is an immutable collection of unique Objects.
|
||||
* It has several operations
|
||||
* which return new AttributeSet instances.
|
||||
*/
|
||||
public final class AttributeSet implements Set {
|
||||
|
||||
static final String COPYRIGHT =
|
||||
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
|
||||
|
||||
/**
|
||||
* An AttributeSet with no members.
|
||||
*/
|
||||
public static final AttributeSet EMPTY_SET = new AttributeSet();
|
||||
|
||||
private Hashtable elements;
|
||||
|
||||
private static final String errString = "AttributeSet is immutable.";
|
||||
|
||||
private AttributeSet(Hashtable elements) {
|
||||
|
||||
this.elements = elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Package only. For AttributeMap use.
|
||||
*/
|
||||
static AttributeSet createKeySet(Hashtable hashtable) {
|
||||
|
||||
Hashtable newElements = new Hashtable();
|
||||
|
||||
Enumeration e = hashtable.keys();
|
||||
while (e.hasMoreElements()) {
|
||||
Object next = e.nextElement();
|
||||
newElements.put(next, next);
|
||||
}
|
||||
|
||||
return new AttributeSet(newElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new, empty AttributeSet. The set is semantically
|
||||
* equivalent to EMPTY_SET.
|
||||
*/
|
||||
public AttributeSet() {
|
||||
|
||||
elements = new Hashtable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new AttributeSet with the single element elem.
|
||||
*/
|
||||
public AttributeSet(Object elem) {
|
||||
|
||||
elements = new Hashtable(1, 1);
|
||||
elements.put(elem, elem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new AttributeSet containing the items in the array elems.
|
||||
*/
|
||||
public AttributeSet(Object[] elems) {
|
||||
|
||||
elements = new Hashtable(elems.length, 1);
|
||||
for (int i=0; i < elems.length; i++) {
|
||||
Object next = elems[i];
|
||||
elements.put(next, next);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the number of elements in this set is 0.
|
||||
* @return true if the number of elements in this set is 0
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
|
||||
return elements.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of elements in this set.
|
||||
* @return the number of elements in this set
|
||||
*/
|
||||
public int size() {
|
||||
|
||||
return elements.size();
|
||||
}
|
||||
|
||||
public boolean equals(Object rhs) {
|
||||
|
||||
try {
|
||||
return equals((AttributeSet) rhs);
|
||||
}
|
||||
catch(ClassCastException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(AttributeSet rhs) {
|
||||
|
||||
if (rhs == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return elements.equals(rhs.elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this set contains the given Object
|
||||
* @return true if this set contains <code>o</code>
|
||||
*/
|
||||
public boolean contains(Object o) {
|
||||
|
||||
Object value = elements.get(o);
|
||||
return value != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this set contains all elements in the given
|
||||
* Collection
|
||||
* @param coll the collection to compare with
|
||||
* @return true if this set contains all elements in the given
|
||||
* Collection
|
||||
*/
|
||||
public boolean containsAll(Collection coll) {
|
||||
|
||||
return elements.keySet().containsAll(coll);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an Enumeration of the elements in this set.
|
||||
* @return an Enumeration of the elements in this set
|
||||
*/
|
||||
public Enumeration elements() {
|
||||
|
||||
return elements.keys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an Iterator with the elements in this set.
|
||||
* @return an Iterator with the elements in this set.
|
||||
* The Iterator cannot be used to modify this AttributeSet.
|
||||
*/
|
||||
public Iterator iterator() {
|
||||
|
||||
return new EnumerationIterator(elements.keys());
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in the given array with the elements in this set.
|
||||
* @param storage an array to fill with this set's elements.
|
||||
* The array cannot be null.
|
||||
* @return the <tt>storage</tt> array.
|
||||
*/
|
||||
public Object[] toArray(Object[] storage) {
|
||||
|
||||
Enumeration keys = elements.keys();
|
||||
int n=0;
|
||||
while (keys.hasMoreElements()) {
|
||||
storage[n++] = keys.nextElement();
|
||||
}
|
||||
return storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array with the elements in this set.
|
||||
* @return an array with the elements in this set
|
||||
*/
|
||||
public Object[] toArray() {
|
||||
|
||||
return toArray(new Object[size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #addElement
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public boolean add(Object o){
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public boolean remove(Object o) {
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #unionWith
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public boolean addAll(Collection coll) {
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #subtract
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public boolean removeAll(Collection coll) {
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #intersectWith
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public boolean retainAll(Collection coll) {
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws UnsupportedOperationException.
|
||||
* @see #EMPTY_SET
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public void clear() {
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an AttributeSet containing the elements of this set
|
||||
* and the given element
|
||||
* @param element the element to add
|
||||
* @return an AttributeSet like this one, with <code>element</code>
|
||||
* added
|
||||
*/
|
||||
public AttributeSet addElement(Object element) {
|
||||
|
||||
Hashtable newElements = (Hashtable) elements.clone();
|
||||
newElements.put(element, element);
|
||||
return new AttributeSet(newElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an AttributeSet which is the union of
|
||||
* this set with the given set.
|
||||
* @param s the set to union with
|
||||
* @return an AttributeSet of the elements in this set or
|
||||
* in <code>s</code>
|
||||
*/
|
||||
public AttributeSet unionWith(AttributeSet s) {
|
||||
|
||||
Hashtable newElements = (Hashtable) elements.clone();
|
||||
|
||||
Iterator iter = s.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Object next = iter.next();
|
||||
newElements.put(next, next);
|
||||
}
|
||||
|
||||
return new AttributeSet(newElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an AttributeSet which is the intersection of
|
||||
* this set with the given set.
|
||||
* @param s the set to intersect with
|
||||
* @return an AttributeSet of the elements in this set which
|
||||
* are in <code>s</code>
|
||||
*/
|
||||
public AttributeSet intersectWith(AttributeSet s) {
|
||||
|
||||
Hashtable newElements = new Hashtable();
|
||||
|
||||
Iterator iter = s.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Object next = iter.next();
|
||||
if (elements.get(next) != null) {
|
||||
newElements.put(next, next);
|
||||
}
|
||||
}
|
||||
|
||||
return new AttributeSet(newElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an AttributeSet with the elements in this set which
|
||||
* are not in the given set.
|
||||
* @param s the set of elements to exclude
|
||||
* @return an AttributeSet of the elements in this set which
|
||||
* are not in <code>s</code>
|
||||
*/
|
||||
public AttributeSet subtract(AttributeSet s) {
|
||||
|
||||
Hashtable newElements = (Hashtable) elements.clone();
|
||||
|
||||
Iterator iter = s.iterator();
|
||||
while (iter.hasNext()) {
|
||||
newElements.remove(iter.next());
|
||||
}
|
||||
|
||||
return new AttributeSet(newElements);
|
||||
}
|
||||
|
||||
private static final class EnumerationIterator implements Iterator {
|
||||
|
||||
private Enumeration e;
|
||||
|
||||
EnumerationIterator(Enumeration e) {
|
||||
this.e = e;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return e.hasMoreElements();
|
||||
}
|
||||
|
||||
public Object next() {
|
||||
return e.nextElement();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException(errString);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user