OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [javax/] [swing/] [text/] [StyleContext.java] - Blame information for rev 772

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* StyleContext.java --
2
   Copyright (C) 2004 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package javax.swing.text;
40
 
41
import java.awt.Color;
42
import java.awt.Font;
43
import java.awt.FontMetrics;
44
import java.awt.Toolkit;
45
import java.io.IOException;
46
import java.io.NotSerializableException;
47
import java.io.ObjectInputStream;
48
import java.io.ObjectOutputStream;
49
import java.io.Serializable;
50
import java.lang.ref.WeakReference;
51
import java.util.Collections;
52
import java.util.Enumeration;
53
import java.util.EventListener;
54
import java.util.Hashtable;
55
import java.util.Iterator;
56
import java.util.Map;
57
import java.util.WeakHashMap;
58
 
59
import javax.swing.event.ChangeEvent;
60
import javax.swing.event.ChangeListener;
61
import javax.swing.event.EventListenerList;
62
 
63
public class StyleContext
64
  implements Serializable, AbstractDocument.AttributeContext
65
{
66
  /** The serialization UID (compatible with JDK1.5). */
67
  private static final long serialVersionUID = 8042858831190784241L;
68
 
69
  public class NamedStyle
70
    implements Serializable, Style
71
  {
72
    /** The serialization UID (compatible with JDK1.5). */
73
    private static final long serialVersionUID = -6690628971806226374L;
74
 
75
    protected transient ChangeEvent changeEvent;
76
    protected EventListenerList listenerList;
77
 
78
    private transient AttributeSet attributes;
79
 
80
    public NamedStyle()
81
    {
82
      this(null, null);
83
    }
84
 
85
    public NamedStyle(Style parent)
86
    {
87
      this(null, parent);
88
    }
89
 
90
    public NamedStyle(String name, Style parent)
91
    {
92
      attributes = getEmptySet();
93
      listenerList = new EventListenerList();
94
      if (name != null)
95
        setName(name);
96
      if (parent != null)
97
        setResolveParent(parent);
98
    }
99
 
100
    public String getName()
101
    {
102
      String name = null;
103
      if (isDefined(StyleConstants.NameAttribute))
104
        name = getAttribute(StyleConstants.NameAttribute).toString();
105
      return name;
106
    }
107
 
108
    public void setName(String n)
109
    {
110
      if (n != null)
111
        addAttribute(StyleConstants.NameAttribute, n);
112
    }
113
 
114
    public void addChangeListener(ChangeListener l)
115
    {
116
      listenerList.add(ChangeListener.class, l);
117
    }
118
 
119
    public void removeChangeListener(ChangeListener l)
120
    {
121
      listenerList.remove(ChangeListener.class, l);
122
    }
123
 
124
    public <T extends EventListener> T[] getListeners(Class<T> listenerType)
125
    {
126
      return listenerList.getListeners(listenerType);
127
    }
128
 
129
    public ChangeListener[] getChangeListeners()
130
    {
131
      return (ChangeListener[]) getListeners(ChangeListener.class);
132
    }
133
 
134
    protected  void fireStateChanged()
135
    {
136
      ChangeListener[] listeners = getChangeListeners();
137
      for (int i = 0; i < listeners.length; ++i)
138
        {
139
          // Lazily create event.
140
          if (changeEvent == null)
141
            changeEvent = new ChangeEvent(this);
142
          listeners[i].stateChanged(changeEvent);
143
        }
144
    }
145
 
146
    public void addAttribute(Object name, Object value)
147
    {
148
      attributes = StyleContext.this.addAttribute(attributes, name, value);
149
      fireStateChanged();
150
    }
151
 
152
    public void addAttributes(AttributeSet attr)
153
    {
154
      attributes = StyleContext.this.addAttributes(attributes, attr);
155
      fireStateChanged();
156
    }
157
 
158
    public boolean containsAttribute(Object name, Object value)
159
    {
160
      return attributes.containsAttribute(name, value);
161
    }
162
 
163
    public boolean containsAttributes(AttributeSet attrs)
164
    {
165
      return attributes.containsAttributes(attrs);
166
    }
167
 
168
    public AttributeSet copyAttributes()
169
    {
170
      // The RI returns a NamedStyle as copy, so do we.
171
      NamedStyle copy = new NamedStyle();
172
      copy.attributes = attributes.copyAttributes();
173
      return copy;
174
    }
175
 
176
    public Object getAttribute(Object attrName)
177
    {
178
      return attributes.getAttribute(attrName);
179
    }
180
 
181
    public int getAttributeCount()
182
    {
183
      return attributes.getAttributeCount();
184
    }
185
 
186
    public Enumeration<?> getAttributeNames()
187
    {
188
      return attributes.getAttributeNames();
189
    }
190
 
191
    public boolean isDefined(Object attrName)
192
    {
193
      return attributes.isDefined(attrName);
194
    }
195
 
196
    public boolean isEqual(AttributeSet attr)
197
    {
198
      return attributes.isEqual(attr);
199
    }
200
 
201
    public void removeAttribute(Object name)
202
    {
203
      attributes = StyleContext.this.removeAttribute(attributes, name);
204
      fireStateChanged();
205
    }
206
 
207
    public void removeAttributes(AttributeSet attrs)
208
    {
209
      attributes = StyleContext.this.removeAttributes(attributes, attrs);
210
      fireStateChanged();
211
    }
212
 
213
    public void removeAttributes(Enumeration<?> names)
214
    {
215
      attributes = StyleContext.this.removeAttributes(attributes, names);
216
      fireStateChanged();
217
    }
218
 
219
 
220
    public AttributeSet getResolveParent()
221
    {
222
      return attributes.getResolveParent();
223
    }
224
 
225
    public void setResolveParent(AttributeSet parent)
226
    {
227
      if (parent != null)
228
        addAttribute(StyleConstants.ResolveAttribute, parent);
229
      else
230
        removeAttribute(StyleConstants.ResolveAttribute);
231
    }
232
 
233
    public String toString()
234
    {
235
      return "NamedStyle:" + getName() + " " + attributes;
236
    }
237
 
238
    private void writeObject(ObjectOutputStream s)
239
      throws IOException
240
    {
241
      s.defaultWriteObject();
242
      writeAttributeSet(s, attributes);
243
    }
244
 
245
    private void readObject(ObjectInputStream s)
246
      throws ClassNotFoundException, IOException
247
    {
248
      s.defaultReadObject();
249
      attributes = SimpleAttributeSet.EMPTY;
250
      readAttributeSet(s, this);
251
    }
252
  }
253
 
254
  public class SmallAttributeSet
255
    implements AttributeSet
256
  {
257
    final Object [] attrs;
258
    private AttributeSet resolveParent;
259
    public SmallAttributeSet(AttributeSet a)
260
    {
261
      int n = a.getAttributeCount();
262
      int i = 0;
263
      attrs = new Object[n * 2];
264
      Enumeration e = a.getAttributeNames();
265
      while (e.hasMoreElements())
266
        {
267
          Object name = e.nextElement();
268
          Object value = a.getAttribute(name);
269
          if (name == ResolveAttribute)
270
            resolveParent = (AttributeSet) value;
271
          attrs[i++] = name;
272
          attrs[i++] = value;
273
        }
274
    }
275
 
276
    public SmallAttributeSet(Object [] a)
277
    {
278
      attrs = a;
279
      for (int i = 0; i < attrs.length; i += 2)
280
        {
281
          if (attrs[i] == ResolveAttribute)
282
            resolveParent = (AttributeSet) attrs[i + 1];
283
        }
284
    }
285
 
286
    public Object clone()
287
    {
288
      return this;
289
    }
290
 
291
    public boolean containsAttribute(Object name, Object value)
292
    {
293
      return value.equals(getAttribute(name));
294
    }
295
 
296
    public boolean containsAttributes(AttributeSet a)
297
    {
298
      boolean res = true;
299
      Enumeration e = a.getAttributeNames();
300
      while (e.hasMoreElements() && res)
301
        {
302
          Object name = e.nextElement();
303
          res = a.getAttribute(name).equals(getAttribute(name));
304
        }
305
      return res;
306
    }
307
 
308
    public AttributeSet copyAttributes()
309
    {
310
      return this;
311
    }
312
 
313
    public boolean equals(Object obj)
314
    {
315
      boolean eq = false;
316
      if (obj instanceof AttributeSet)
317
        {
318
          AttributeSet atts = (AttributeSet) obj;
319
          eq = getAttributeCount() == atts.getAttributeCount()
320
               && containsAttributes(atts);
321
        }
322
      return eq;
323
    }
324
 
325
    public Object getAttribute(Object key)
326
    {
327
      Object att = null;
328
      if (key == StyleConstants.ResolveAttribute)
329
        att = resolveParent;
330
 
331
      for (int i = 0; i < attrs.length && att == null; i += 2)
332
        {
333
          if (attrs[i].equals(key))
334
            att = attrs[i + 1];
335
        }
336
 
337
      // Check the resolve parent, unless we're looking for the
338
      // ResolveAttribute, which must not be looked up
339
      if (att == null)
340
          {
341
            AttributeSet parent = getResolveParent();
342
            if (parent != null)
343
              att = parent.getAttribute(key);
344
          }
345
 
346
      return att;
347
    }
348
 
349
    public int getAttributeCount()
350
    {
351
      return attrs.length / 2;
352
    }
353
 
354
    public Enumeration<?> getAttributeNames()
355
    {
356
      return new Enumeration()
357
        {
358
          int i = 0;
359
          public boolean hasMoreElements()
360
          {
361
            return i < attrs.length;
362
          }
363
          public Object nextElement()
364
          {
365
            i += 2;
366
            return attrs[i-2];
367
          }
368
        };
369
    }
370
 
371
    public AttributeSet getResolveParent()
372
    {
373
      return resolveParent;
374
    }
375
 
376
    public int hashCode()
377
    {
378
      return java.util.Arrays.asList(attrs).hashCode();
379
    }
380
 
381
    public boolean isDefined(Object key)
382
    {
383
      for (int i = 0; i < attrs.length; i += 2)
384
        {
385
          if (attrs[i].equals(key))
386
            return true;
387
        }
388
      return false;
389
    }
390
 
391
    public boolean isEqual(AttributeSet attr)
392
    {
393
      boolean eq;
394
      // If the other one is also a SmallAttributeSet, it is only considered
395
      // equal if it's the same instance.
396
      if (attr instanceof SmallAttributeSet)
397
        eq = attr == this;
398
      else
399
        eq = getAttributeCount() == attr.getAttributeCount()
400
             && this.containsAttributes(attr);
401
      return eq;
402
    }
403
 
404
    public String toString()
405
    {
406
      StringBuilder sb = new StringBuilder();
407
      sb.append('{');
408
      for (int i = 0; i < attrs.length; i += 2)
409
        {
410
          if (attrs[i + 1] instanceof AttributeSet)
411
            {
412
              sb.append(attrs[i]);
413
              sb.append("=AttributeSet,");
414
            }
415
          else
416
            {
417
              sb.append(attrs[i]);
418
              sb.append('=');
419
              sb.append(attrs[i + 1]);
420
              sb.append(',');
421
            }
422
        }
423
      sb.append("}");
424
      return sb.toString();
425
    }
426
  }
427
 
428
  /**
429
   * Register StyleConstant keys as static attribute keys for serialization.
430
   */
431
  static
432
  {
433
    // Don't let problems while doing this prevent class loading.
434
    try
435
      {
436
        for (Iterator i = StyleConstants.keys.iterator(); i.hasNext();)
437
          registerStaticAttributeKey(i.next());
438
      }
439
    catch (Throwable t)
440
      {
441
        t.printStackTrace();
442
      }
443
  }
444
 
445
  /**
446
   * The name of the default style.
447
   */
448
  public static final String DEFAULT_STYLE = "default";
449
 
450
  static Hashtable sharedAttributeSets = new Hashtable();
451
  static Hashtable sharedFonts = new Hashtable();
452
 
453
  static StyleContext defaultStyleContext;
454
  static final int compressionThreshold = 9;
455
 
456
  /**
457
   * These attribute keys are handled specially in serialization.
458
   */
459
  private static Hashtable writeAttributeKeys;
460
  private static Hashtable readAttributeKeys;
461
 
462
  private NamedStyle styles;
463
 
464
  /**
465
   * Used for searching attributes in the pool.
466
   */
467
  private transient MutableAttributeSet search = new SimpleAttributeSet();
468
 
469
  /**
470
   * A pool of immutable AttributeSets.
471
   */
472
  private transient Map attributeSetPool =
473
    Collections.synchronizedMap(new WeakHashMap());
474
 
475
  /**
476
   * Creates a new instance of the style context. Add the default style
477
   * to the style table.
478
   */
479
  public StyleContext()
480
  {
481
    styles = new NamedStyle(null);
482
    addStyle(DEFAULT_STYLE, null);
483
  }
484
 
485
  protected SmallAttributeSet createSmallAttributeSet(AttributeSet a)
486
  {
487
    return new SmallAttributeSet(a);
488
  }
489
 
490
  protected MutableAttributeSet createLargeAttributeSet(AttributeSet a)
491
  {
492
    return new SimpleAttributeSet(a);
493
  }
494
 
495
  public void addChangeListener(ChangeListener listener)
496
  {
497
    styles.addChangeListener(listener);
498
  }
499
 
500
  public void removeChangeListener(ChangeListener listener)
501
  {
502
    styles.removeChangeListener(listener);
503
  }
504
 
505
  public ChangeListener[] getChangeListeners()
506
  {
507
    return styles.getChangeListeners();
508
  }
509
 
510
  public Style addStyle(String name, Style parent)
511
  {
512
    Style newStyle = new NamedStyle(name, parent);
513
    if (name != null)
514
      styles.addAttribute(name, newStyle);
515
    return newStyle;
516
  }
517
 
518
  public void removeStyle(String name)
519
  {
520
    styles.removeAttribute(name);
521
  }
522
 
523
  /**
524
   * Get the style from the style table. If the passed name
525
   * matches {@link #DEFAULT_STYLE}, returns the default style.
526
   * Otherwise returns the previously defined style of
527
   * <code>null</code> if the style with the given name is not defined.
528
   *
529
   * @param name the name of the style.
530
   *
531
   * @return the style with the given name or null if no such defined.
532
   */
533
  public Style getStyle(String name)
534
  {
535
    return (Style) styles.getAttribute(name);
536
  }
537
 
538
  /**
539
   * Get the names of the style. The returned enumeration always
540
   * contains at least one member, the default style.
541
   */
542
  public Enumeration<?> getStyleNames()
543
  {
544
    return styles.getAttributeNames();
545
  }
546
 
547
  private void readObject(ObjectInputStream in)
548
    throws ClassNotFoundException, IOException
549
  {
550
    search = new SimpleAttributeSet();
551
    attributeSetPool = Collections.synchronizedMap(new WeakHashMap());
552
    in.defaultReadObject();
553
  }
554
 
555
  private void writeObject(ObjectOutputStream out)
556
    throws IOException
557
  {
558
    cleanupPool();
559
    out.defaultWriteObject();
560
  }
561
 
562
  //
563
  // StyleContexts only understand the "simple" model of fonts present in
564
  // pre-java2d systems: fonts are a family name, a size (integral number
565
  // of points), and a mask of style parameters (plain, bold, italic, or
566
  // bold|italic). We have an inner class here called SimpleFontSpec which
567
  // holds such triples.
568
  //
569
  // A SimpleFontSpec can be built for *any* AttributeSet because the size,
570
  // family, and style keys in an AttributeSet have default values (defined
571
  // over in StyleConstants).
572
  //
573
  // We keep a static cache mapping SimpleFontSpecs to java.awt.Fonts, so
574
  // that we reuse Fonts between styles and style contexts.
575
  //
576
 
577
  private static class SimpleFontSpec
578
  {
579
    String family;
580
    int style;
581
    int size;
582
    public SimpleFontSpec(String family,
583
                          int style,
584
                          int size)
585
    {
586
      this.family = family;
587
      this.style = style;
588
      this.size = size;
589
    }
590
    public boolean equals(Object obj)
591
    {
592
      return (obj != null)
593
        && (obj instanceof SimpleFontSpec)
594
        && (((SimpleFontSpec)obj).family.equals(this.family))
595
        && (((SimpleFontSpec)obj).style == this.style)
596
        && (((SimpleFontSpec)obj).size == this.size);
597
    }
598
    public int hashCode()
599
    {
600
      return family.hashCode() + style + size;
601
    }
602
  }
603
 
604
  public Font getFont(AttributeSet attr)
605
  {
606
    String family = StyleConstants.getFontFamily(attr);
607
    int style = Font.PLAIN;
608
    if (StyleConstants.isBold(attr))
609
      style += Font.BOLD;
610
    if (StyleConstants.isItalic(attr))
611
      style += Font.ITALIC;
612
    int size = StyleConstants.getFontSize(attr);
613
    return getFont(family, style, size);
614
  }
615
 
616
  public Font getFont(String family, int style, int size)
617
  {
618
    SimpleFontSpec spec = new SimpleFontSpec(family, style, size);
619
    if (sharedFonts.containsKey(spec))
620
      return (Font) sharedFonts.get(spec);
621
    else
622
      {
623
        Font tmp = new Font(family, style, size);
624
        sharedFonts.put(spec, tmp);
625
        return tmp;
626
      }
627
  }
628
 
629
  public FontMetrics getFontMetrics(Font f)
630
  {
631
    return Toolkit.getDefaultToolkit().getFontMetrics(f);
632
  }
633
 
634
  public Color getForeground(AttributeSet a)
635
  {
636
    return StyleConstants.getForeground(a);
637
  }
638
 
639
  public Color getBackground(AttributeSet a)
640
  {
641
    return StyleConstants.getBackground(a);
642
  }
643
 
644
  protected int getCompressionThreshold()
645
  {
646
    return compressionThreshold;
647
  }
648
 
649
  public static StyleContext getDefaultStyleContext()
650
  {
651
    if (defaultStyleContext == null)
652
      defaultStyleContext = new StyleContext();
653
    return defaultStyleContext;
654
  }
655
 
656
  public synchronized AttributeSet addAttribute(AttributeSet old, Object name,
657
                                                Object value)
658
  {
659
    AttributeSet ret;
660
    if (old.getAttributeCount() + 1 < getCompressionThreshold())
661
      {
662
        search.removeAttributes(search);
663
        search.addAttributes(old);
664
        search.addAttribute(name, value);
665
        reclaim(old);
666
        ret = searchImmutableSet();
667
      }
668
    else
669
      {
670
        MutableAttributeSet mas = getMutableAttributeSet(old);
671
        mas.addAttribute(name, value);
672
        ret = mas;
673
      }
674
    return ret;
675
  }
676
 
677
  public synchronized AttributeSet addAttributes(AttributeSet old,
678
                                                 AttributeSet attributes)
679
  {
680
    AttributeSet ret;
681
    if (old.getAttributeCount() + attributes.getAttributeCount()
682
        < getCompressionThreshold())
683
      {
684
        search.removeAttributes(search);
685
        search.addAttributes(old);
686
        search.addAttributes(attributes);
687
        reclaim(old);
688
        ret = searchImmutableSet();
689
      }
690
    else
691
      {
692
        MutableAttributeSet mas = getMutableAttributeSet(old);
693
        mas.addAttributes(attributes);
694
        ret = mas;
695
      }
696
    return ret;
697
  }
698
 
699
  public AttributeSet getEmptySet()
700
  {
701
    return SimpleAttributeSet.EMPTY;
702
  }
703
 
704
  public void reclaim(AttributeSet attributes)
705
  {
706
    cleanupPool();
707
  }
708
 
709
  public synchronized AttributeSet removeAttribute(AttributeSet old,
710
                                                   Object name)
711
  {
712
    AttributeSet ret;
713
    if (old.getAttributeCount() - 1 <= getCompressionThreshold())
714
      {
715
        search.removeAttributes(search);
716
        search.addAttributes(old);
717
        search.removeAttribute(name);
718
        reclaim(old);
719
        ret = searchImmutableSet();
720
      }
721
    else
722
      {
723
        MutableAttributeSet mas = getMutableAttributeSet(old);
724
        mas.removeAttribute(name);
725
        ret = mas;
726
      }
727
    return ret;
728
  }
729
 
730
  public synchronized AttributeSet removeAttributes(AttributeSet old,
731
                                                    AttributeSet attributes)
732
  {
733
    AttributeSet ret;
734
    if (old.getAttributeCount() <= getCompressionThreshold())
735
      {
736
        search.removeAttributes(search);
737
        search.addAttributes(old);
738
        search.removeAttributes(attributes);
739
        reclaim(old);
740
        ret = searchImmutableSet();
741
      }
742
    else
743
      {
744
        MutableAttributeSet mas = getMutableAttributeSet(old);
745
        mas.removeAttributes(attributes);
746
        ret = mas;
747
      }
748
    return ret;
749
  }
750
 
751
  public synchronized AttributeSet removeAttributes(AttributeSet old,
752
                                                    Enumeration<?> names)
753
  {
754
    AttributeSet ret;
755
    if (old.getAttributeCount() <= getCompressionThreshold())
756
      {
757
        search.removeAttributes(search);
758
        search.addAttributes(old);
759
        search.removeAttributes(names);
760
        reclaim(old);
761
        ret = searchImmutableSet();
762
      }
763
    else
764
      {
765
        MutableAttributeSet mas = getMutableAttributeSet(old);
766
        mas.removeAttributes(names);
767
        ret = mas;
768
      }
769
    return ret;
770
  }
771
 
772
  /**
773
   * Gets the object previously registered with registerStaticAttributeKey.
774
   *
775
   * @param key - the key that was registered.
776
   * @return the object previously registered with registerStaticAttributeKey.
777
   */
778
  public static Object getStaticAttribute(Object key)
779
  {
780
    if (key == null)
781
      return null;
782
    return readAttributeKeys.get(key);
783
  }
784
 
785
  /**
786
   * Returns the String that key will be registered with
787
   * registerStaticAttributeKey.
788
   *
789
   * @param key - the key that will be registered.
790
   * @return the string the key will be registered with.
791
   */
792
  public static Object getStaticAttributeKey(Object key)
793
  {
794
    return key.getClass().getName() + "." + key.toString();
795
  }
796
 
797
  /**
798
   * Reads a set of attributes from the given object input stream. This will
799
   * attempt to restore keys that were static objects by considering only the
800
   * keys that have were registered with registerStaticAttributeKey. The
801
   * attributes retrieved will be placed into the given set.
802
   *
803
   * @param in - the stream to read from
804
   * @param a - the set of attributes
805
   * @throws ClassNotFoundException - may be encountered when reading from
806
   *           stream
807
   * @throws IOException - any I/O error
808
   */
809
  public static void readAttributeSet(ObjectInputStream in,
810
                                      MutableAttributeSet a)
811
    throws ClassNotFoundException, IOException
812
  {
813
    int count = in.readInt();
814
    for (int i = 0; i < count; i++)
815
      {
816
        Object key = in.readObject();
817
        Object val = in.readObject();
818
        if (readAttributeKeys != null)
819
          {
820
            Object staticKey = readAttributeKeys.get(key);
821
            if (staticKey != null)
822
              key = staticKey;
823
            Object staticVal = readAttributeKeys.get(val);
824
            if (staticVal != null)
825
              val = staticVal;
826
          }
827
        a.addAttribute(key, val);
828
      }
829
  }
830
 
831
  /**
832
   * Serialize an attribute set in a way that is compatible with it
833
   * being read in again by {@link #readAttributeSet(ObjectInputStream, MutableAttributeSet)}.
834
   * In particular registered static keys are transformed properly.
835
   *
836
   * @param out - stream to write to
837
   * @param a - the attribute set
838
   * @throws IOException - any I/O error
839
   */
840
  public static void writeAttributeSet(ObjectOutputStream out, AttributeSet a)
841
    throws IOException
842
  {
843
    int count = a.getAttributeCount();
844
    out.writeInt(count);
845
    Enumeration e = a.getAttributeNames();
846
    while (e.hasMoreElements())
847
      {
848
        Object key = e.nextElement();
849
        // Write key.
850
        if (key instanceof Serializable)
851
          out.writeObject(key);
852
        else
853
          {
854
            Object io = writeAttributeKeys.get(key);
855
            if (io == null)
856
              throw new NotSerializableException(key.getClass().getName()
857
                                                 + ", key: " + key);
858
            out.writeObject(io);
859
          }
860
        // Write value.
861
        Object val = a.getAttribute(key);
862
        Object io = writeAttributeKeys.get(val);
863
        if (val instanceof Serializable)
864
          out.writeObject(io != null ? io : val);
865
        else
866
          {
867
            if (io == null)
868
              throw new NotSerializableException(val.getClass().getName());
869
            out.writeObject(io);
870
          }
871
      }
872
  }
873
 
874
  /**
875
   * Handles reading in the attributes.
876
   * @see #readAttributeSet(ObjectInputStream, MutableAttributeSet)
877
   *
878
   * @param in - the stream to read from
879
   * @param a - the set of attributes
880
   * @throws ClassNotFoundException - may be encountered when reading from stream
881
   * @throws IOException - any I/O error
882
   */
883
  public void readAttributes(ObjectInputStream in, MutableAttributeSet a)
884
    throws ClassNotFoundException, IOException
885
  {
886
    readAttributeSet(in, a);
887
  }
888
 
889
  /**
890
   * Handles writing of the given attributes.
891
   * @see #writeAttributeSet(ObjectOutputStream, AttributeSet)
892
   *
893
   * @param out - stream to write to
894
   * @param a - the attribute set
895
   * @throws IOException - any I/O error
896
   */
897
  public void writeAttributes(ObjectOutputStream out, AttributeSet a)
898
    throws IOException
899
  {
900
    writeAttributeSet(out, a);
901
  }
902
 
903
  /**
904
   * Registers an attribute key as a well-known keys. When an attribute with
905
   * such a key is written to a stream, a special syntax is used so that it
906
   * can be recognized when it is read back in. All attribute keys defined
907
   * in <code>StyleContext</code> are registered as static keys. If you define
908
   * additional attribute keys that you want to exist as nonreplicated objects,
909
   * then you should register them using this method.
910
   *
911
   * @param key the key to register as static attribute key
912
   */
913
  public static void registerStaticAttributeKey(Object key)
914
  {
915
    String io = key.getClass().getName() + "." + key.toString();
916
    if (writeAttributeKeys == null)
917
      writeAttributeKeys = new Hashtable();
918
    if (readAttributeKeys == null)
919
      readAttributeKeys = new Hashtable();
920
    writeAttributeKeys.put(key, io);
921
    readAttributeKeys.put(io, key);
922
  }
923
 
924
  /**
925
   * Returns a string representation of this StyleContext.
926
   *
927
   * @return a string representation of this StyleContext
928
   */
929
  public String toString()
930
  {
931
    cleanupPool();
932
    StringBuilder b = new StringBuilder();
933
    Iterator i = attributeSetPool.keySet().iterator();
934
    while (i.hasNext())
935
      {
936
        Object att = i.next();
937
        b.append(att);
938
        b.append('\n');
939
      }
940
    return b.toString();
941
  }
942
 
943
  /**
944
   * Searches the AttributeSet pool and returns a pooled instance if available,
945
   * or pool a new one.
946
   *
947
   * @return an immutable attribute set that equals the current search key
948
   */
949
  private AttributeSet searchImmutableSet()
950
  {
951
    SmallAttributeSet k = createSmallAttributeSet(search);
952
    WeakReference ref = (WeakReference) attributeSetPool.get(k);
953
    SmallAttributeSet a;
954
    if (ref == null || (a = (SmallAttributeSet) ref.get()) == null)
955
      {
956
        a = k;
957
        attributeSetPool.put(a, new WeakReference(a));
958
      }
959
    return a;
960
  }
961
 
962
  /**
963
   * Cleans up the attribute set pool from entries that are no longer
964
   * referenced.
965
   */
966
  private void cleanupPool()
967
  {
968
    // TODO: How else can we force cleaning up the WeakHashMap?
969
    attributeSetPool.size();
970
  }
971
 
972
  /**
973
   * Returns a MutableAttributeSet that holds a. If a itself is mutable,
974
   * this returns a itself, otherwise it creates a new SimpleAtttributeSet
975
   * via {@link #createLargeAttributeSet(AttributeSet)}.
976
   *
977
   * @param a the AttributeSet to create a mutable set for
978
   *
979
   * @return a mutable attribute set that corresponds to a
980
   */
981
  private MutableAttributeSet getMutableAttributeSet(AttributeSet a)
982
  {
983
    MutableAttributeSet mas;
984
    if (a instanceof MutableAttributeSet)
985
      mas = (MutableAttributeSet) a;
986
    else
987
      mas = createLargeAttributeSet(a);
988
    return mas;
989
  }
990
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.