001: /*
002: * (C) Copyright IBM Corp. 1998-2004. All Rights Reserved.
003: *
004: * The program is provided "as is" without any warranty express or
005: * implied, including the warranty of non-infringement and the implied
006: * warranties of merchantibility and fitness for a particular purpose.
007: * IBM will not be liable for any damages suffered by you as a result
008: * of using the Program. In no event will IBM be liable for any
009: * special, indirect or consequential damages or lost profits even if
010: * IBM has been advised of the possibility of their occurrence. IBM
011: * will not be liable for any third party claims against you.
012: */
013: package com.ibm.richtext.textlayout.attributes;
014:
015: import java.io.Serializable;
016:
017: /**
018: * This class provides a cannonical mapping between fields in TextAttribute
019: * and instances of itself. It is used by AttributeMap to serialize
020: * and deserialize TextAttribute to preserve uniqueness of TextAttribute
021: * instances (ie so that TextAttribute instances remain singletons),
022: * and to provide compatability between 1.1 and 1.2 versions of
023: * TextAttribute.
024: * <p>
025: * Example use - instead of doing this:
026: * <blockquote><pre>
027: * out.writeObject(anAttribute);
028: * </pre></blockquote>
029: * do this:
030: * <blockquote><pre>
031: * out.writeObject(AttributeKey.mapAttributeToKey(anAttribute));
032: * </pre></blockquote>
033: * Similarly, instead of this:
034: * <blockquote><pre>
035: * anAttribute = in.readObject();
036: * </pre></blockquote>
037: * do this:
038: * <blockquote><pre>
039: * anAttribute = AttributeKey.mapKeyToAttribute(in.readObject());
040: * </pre></blockquote>
041: * <p>
042: * If anAttribute is not a known TextAttribute, then <code>mapAttributeToKey</code>
043: * will just return its argument. Similarly, <code>mapKeyToAttribute</code> will
044: * return its argument if the argument is not a known AttributeKey.
045: */
046:
047: /*public*/final class AttributeKey implements Serializable {
048:
049: /*
050: In this implementation, two parallel Vectors are
051: maintained. TextAttribute(i) maps to AttributeKey(i).
052: For compatability with existing data, this mapping must
053: be maintained in the future! So, when new attributes
054: are added, add them to the end of the list.
055: */
056: static final String COPYRIGHT = "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
057: private static final long serialVersionUID = 3772371253277107294L;
058:
059: private static Object[] fgTextAttributes;
060: private static Object[] fgAttributeKeys;
061:
062: static {
063: fgTextAttributes = new Object[] { TextAttribute.FONT,
064: TextAttribute.FAMILY, TextAttribute.WEIGHT,
065: TextAttribute.POSTURE, TextAttribute.SIZE,
066: TextAttribute.SUPERSCRIPT, TextAttribute.FOREGROUND,
067: TextAttribute.BACKGROUND, TextAttribute.UNDERLINE,
068: TextAttribute.STRIKETHROUGH,
069: TextAttribute.CHAR_REPLACEMENT,
070: TextAttribute.EXTRA_LINE_SPACING,
071: TextAttribute.FIRST_LINE_INDENT,
072: TextAttribute.MIN_LINE_SPACING,
073: TextAttribute.LINE_FLUSH, TextAttribute.LEADING_MARGIN,
074: TextAttribute.TRAILING_MARGIN, TextAttribute.TAB_RULER,
075: TextAttribute.RUN_DIRECTION,
076: TextAttribute.BIDI_EMBEDDING,
077: TextAttribute.JUSTIFICATION, };
078:
079: final int attrCount = fgTextAttributes.length;
080: fgAttributeKeys = new Object[attrCount];
081:
082: for (int i = 0; i < attrCount; i += 1) {
083: fgAttributeKeys[i] = new AttributeKey(i);
084: }
085: }
086:
087: /**
088: * Return the TextAttribute corresponding to the given key.
089: * If key is an instance of AttributeKey it will be mapped to
090: * a TextAttribute. Otherwise, the key is returned.
091: * @param key the key to map to a TextAttribute field
092: * @return the TextAttribute for <code>key</code> if <code>key</code>
093: * is an AttributeKey; otherwise <code>key</code> is returned
094: */
095: /*public*/static Object mapKeyToAttribute(Object key) {
096:
097: try {
098: AttributeKey aKey = (AttributeKey) key;
099: if (aKey.fId < fgTextAttributes.length) {
100: return fgTextAttributes[aKey.fId];
101: } else {
102: return key;
103: }
104: } catch (ClassCastException e) {
105: return key;
106: }
107: }
108:
109: /**
110: * If attribute is a known TextAttribute, return an AttributeKey
111: * for it. Otherwise the object is returned.
112: * @param attribute the attribute to map to an AttributeKey
113: * @return an AttributeKey for <code>attribute</code>
114: * if <code>attribute</code> is a known attribute; otherwise
115: * <code>attribute</code> is returned
116: */
117: /*public*/static Object mapAttributeToKey(Object attribute) {
118:
119: final int attrCount = fgTextAttributes.length;
120:
121: for (int index = 0; index < attrCount; index += 1) {
122: if (fgTextAttributes[index].equals(attribute)) {
123: return fgAttributeKeys[index];
124: }
125: }
126:
127: return attribute;
128: }
129:
130: private int fId;
131:
132: private AttributeKey(int id) {
133:
134: fId = id;
135: }
136:
137: public boolean equals(Object rhs) {
138:
139: try {
140: return ((AttributeKey) rhs).fId == fId;
141: } catch (ClassCastException e) {
142: return false;
143: }
144: }
145:
146: public int hashCode() {
147:
148: return fId;
149: }
150: }
|