001    /* AccessibleRelationSet.java -- the combined relations of an accessible object
002       Copyright (C) 2002, 2005 Free Software Foundation
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    package javax.accessibility;
039    
040    import java.util.Locale;
041    import java.util.Vector;
042    
043    /**
044     * Describes all relations of an accessible object. For example, an object
045     * by labeled by one object and control another.
046     *
047     * @author Eric Blake (ebb9@email.byu.edu)
048     * @see AccessibleRelation
049     * @since 1.2
050     * @status updated to 1.4
051     */
052    public class AccessibleRelationSet
053    {
054      /**
055       * The list of relations, should be instances of AccessibleRelation. Don't
056       * set this to null.
057       *
058       * @see #add(AccessibleRelation)
059       * @see #addAll(AccessibleRelation[])
060       * @see #remove(AccessibleRelation)
061       * @see #contains(String)
062       * @see #get(String)
063       * @see #size()
064       * @see #toArray()
065       * @see #clear()
066       */
067      protected Vector<AccessibleRelation> relations
068        = new Vector<AccessibleRelation>();
069    
070      /**
071       * Create an empty relation set.
072       */
073      public AccessibleRelationSet()
074      {
075      }
076    
077      /**
078       * Create a relation set initialized with the given relations, duplicates are
079       * ignored.
080       *
081       * @param relations the relations to insert
082       * @throws NullPointerException if relations is null
083       */
084      public AccessibleRelationSet(AccessibleRelation[] relations)
085      {
086        addAll(relations);
087      }
088    
089      /**
090       * Add a new relation to the current set. If the relation is already in
091       * the set, the targets are merged with the existing relation, possibly
092       * resulting in an object being in the target list more than once. Do not
093       * add a relation with a null key, as it will cause problems later.
094       *
095       * @param relation the relation to add
096       * @return true if the set was modified, which is always the case
097       * @throws NullPointerException if relation is null
098       */
099      public boolean add(AccessibleRelation relation)
100      {
101        AccessibleRelation old = get(relation.key);
102        if (old == null)
103          return relations.add(relation);
104        if (old.targets.length == 0)
105          old.targets = relation.targets;
106        else if (relation.targets.length != 0)
107          {
108            Object[] t = new Object[old.targets.length + relation.targets.length];
109            System.arraycopy(old.targets, 0, t, 0, old.targets.length);
110            System.arraycopy(relation.targets, 0, t, old.targets.length,
111                             relation.targets.length);
112            old.targets = t;
113          }
114        return true;
115      }
116    
117      /**
118       * Add all of the relations to the current set. Duplicates are ignored.
119       *
120       * @param array the array of relations to add
121       * @throws NullPointerException if array is null or has null entries
122       */
123      public void addAll(AccessibleRelation[] array)
124      {
125        int i = array.length;
126        while (--i >= 0)
127          add(array[i]);
128      }
129    
130      /**
131       * Remove a relation from the set. If a relation was removed, return true.
132       * Note that this uses AccessibleRelation.equals, which defaults to ==, so a
133       * relation with the same key may still exist in the set afterwords.
134       *
135       * @param relation the state to remove
136       * @return true if the set changed
137       */
138      public boolean remove(AccessibleRelation relation)
139      {
140        return relations.remove(relation);
141      }
142    
143      /**
144       * Clear all relations in the set.
145       */
146      public void clear()
147      {
148        relations.clear();
149      }
150    
151      /**
152       * Return the number of relations in the set.
153       *
154       * @return the set size
155       */
156      public int size()
157      {
158        return relations.size();
159      }
160    
161      /**
162       * Check if the relation key is in the set.
163       *
164       * @param key the relation to locate
165       * @return true if it is in the set
166       */
167      public boolean contains(String key)
168      {
169        int i = relations.size();
170        while (--i >= 0)
171          if (((AccessibleRelation) relations.get(i)).key.equals(key))
172            return true;
173        return false;
174      }
175    
176      /**
177       * Get the relation that matches the key.
178       *
179       * @param key the relation to locate
180       * @return the relation in the set, or null
181       */
182      public AccessibleRelation get(String key)
183      {
184        int i = relations.size();
185        while (--i >= 0)
186          {
187            AccessibleRelation r = (AccessibleRelation) relations.get(i);
188            if (r.key.equals(key))
189              return r;
190          }
191        return null;
192      }
193    
194      /**
195       * Return the relation set as an array.
196       *
197       * @return an array of the current relations
198       */
199      public AccessibleRelation[] toArray()
200      {
201        AccessibleRelation[] result = new AccessibleRelation[relations.size()];
202        relations.toArray(result);
203        return result;
204      }
205    
206      /**
207       * Return a localized, comma-separated string representing all relations
208       * in the set. This is in arbitrary order.
209       *
210       * @return the string representation
211       * @see AccessibleBundle#toDisplayString(String, Locale)
212       */
213      public String toString()
214      {
215        int i = relations.size();
216        if (i == 0)
217          return "";
218        // Pre-allocate an average of 10 chars per state.
219        StringBuffer b = new StringBuffer(i * 10);
220        while (--i >= 0)
221          b.append(relations.get(i)).append(',');
222        return b.substring(0, b.length() - 1);
223      }
224    } // class AccessibleRelationSet