1 /*
   2  * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.accessibility;
  27 
  28 import java.util.Vector;
  29 import java.util.Locale;
  30 import java.util.MissingResourceException;
  31 import java.util.ResourceBundle;
  32 
  33 /**
  34  * Class AccessibleRelationSet determines a component's relation set.  The
  35  * relation set of a component is a set of AccessibleRelation objects that
  36  * describe the component's relationships with other components.
  37  *
  38  * @see AccessibleRelation
  39  *
  40  * @author      Lynn Monsanto
  41  * @since 1.3
  42  */
  43 public class AccessibleRelationSet {
  44 
  45     /**
  46      * Each entry in the Vector represents an AccessibleRelation.
  47      * @see #add
  48      * @see #addAll
  49      * @see #remove
  50      * @see #contains
  51      * @see #get
  52      * @see #size
  53      * @see #toArray
  54      * @see #clear
  55      */
  56     protected Vector<AccessibleRelation> relations = null;
  57 
  58     /**
  59      * Creates a new empty relation set.
  60      */
  61     public AccessibleRelationSet() {
  62         relations = null;
  63     }
  64 
  65     /**
  66      * Creates a new relation with the initial set of relations contained in
  67      * the array of relations passed in.  Duplicate entries are ignored.
  68      *
  69      * @param relations an array of AccessibleRelation describing the
  70      * relation set.
  71      */
  72     public AccessibleRelationSet(AccessibleRelation[] relations) {
  73         if (relations.length != 0) {
  74             this.relations = new Vector(relations.length);
  75             for (int i = 0; i < relations.length; i++) {
  76                 add(relations[i]);
  77             }
  78         }
  79     }
  80 
  81     /**
  82      * Adds a new relation to the current relation set.  If the relation
  83      * is already in the relation set, the target(s) of the specified
  84      * relation is merged with the target(s) of the existing relation.
  85      * Otherwise,  the new relation is added to the relation set.
  86      *
  87      * @param relation the relation to add to the relation set
  88      * @return true if relation is added to the relation set; false if the
  89      * relation set is unchanged
  90      */
  91     public boolean add(AccessibleRelation relation) {
  92         if (relations == null) {
  93             relations = new Vector();
  94         }
  95 
  96         // Merge the relation targets if the key exists
  97         AccessibleRelation existingRelation = get(relation.getKey());
  98         if (existingRelation == null) {
  99             relations.addElement(relation);
 100             return true;
 101         } else {
 102             Object [] existingTarget = existingRelation.getTarget();
 103             Object [] newTarget = relation.getTarget();
 104             int mergedLength = existingTarget.length + newTarget.length;
 105             Object [] mergedTarget = new Object[mergedLength];
 106             for (int i = 0; i < existingTarget.length; i++) {
 107                 mergedTarget[i] = existingTarget[i];
 108             }
 109             for (int i = existingTarget.length, j = 0;
 110                  i < mergedLength;
 111                  i++, j++) {
 112                 mergedTarget[i] = newTarget[j];
 113             }
 114             existingRelation.setTarget(mergedTarget);
 115         }
 116         return true;
 117     }
 118 
 119     /**
 120      * Adds all of the relations to the existing relation set.  Duplicate
 121      * entries are ignored.
 122      *
 123      * @param relations  AccessibleRelation array describing the relation set.
 124      */
 125     public void addAll(AccessibleRelation[] relations) {
 126         if (relations.length != 0) {
 127             if (this.relations == null) {
 128                 this.relations = new Vector(relations.length);
 129             }
 130             for (int i = 0; i < relations.length; i++) {
 131                 add(relations[i]);
 132             }
 133         }
 134     }
 135 
 136     /**
 137      * Removes a relation from the current relation set.  If the relation
 138      * is not in the set, the relation set will be unchanged and the
 139      * return value will be false.  If the relation is in the relation
 140      * set, it will be removed from the set and the return value will be
 141      * true.
 142      *
 143      * @param relation the relation to remove from the relation set
 144      * @return true if the relation is in the relation set; false if the
 145      * relation set is unchanged
 146      */
 147     public boolean remove(AccessibleRelation relation) {
 148         if (relations == null) {
 149             return false;
 150         } else {
 151             return relations.removeElement(relation);
 152         }
 153     }
 154 
 155     /**
 156      * Removes all the relations from the current relation set.
 157      */
 158     public void clear() {
 159         if (relations != null) {
 160             relations.removeAllElements();
 161         }
 162     }
 163 
 164     /**
 165      * Returns the number of relations in the relation set.
 166      * @return the number of relations in the relation set
 167      */
 168     public int size() {
 169         if (relations == null) {
 170             return 0;
 171         } else {
 172             return relations.size();
 173         }
 174     }
 175 
 176     /**
 177      * Returns whether the relation set contains a relation
 178      * that matches the specified key.
 179      * @param key the AccessibleRelation key
 180      * @return true if the relation is in the relation set; otherwise false
 181      */
 182     public boolean contains(String key) {
 183         return get(key) != null;
 184     }
 185 
 186     /**
 187      * Returns the relation that matches the specified key.
 188      * @param key the AccessibleRelation key
 189      * @return the relation, if one exists, that matches the specified key.
 190      * Otherwise, null is returned.
 191      */
 192     public AccessibleRelation get(String key) {
 193         if (relations == null) {
 194             return null;
 195         } else {
 196             int len = relations.size();
 197             for (int i = 0; i < len; i++) {
 198                 AccessibleRelation relation =
 199                     (AccessibleRelation)relations.elementAt(i);
 200                 if (relation != null && relation.getKey().equals(key)) {
 201                     return relation;
 202                 }
 203             }
 204             return null;
 205         }
 206     }
 207 
 208     /**
 209      * Returns the current relation set as an array of AccessibleRelation
 210      * @return AccessibleRelation array contacting the current relation.
 211      */
 212     public AccessibleRelation[] toArray() {
 213         if (relations == null) {
 214             return new AccessibleRelation[0];
 215         } else {
 216             AccessibleRelation[] relationArray
 217                 = new AccessibleRelation[relations.size()];
 218             for (int i = 0; i < relationArray.length; i++) {
 219                 relationArray[i] = (AccessibleRelation) relations.elementAt(i);
 220             }
 221             return relationArray;
 222         }
 223     }
 224 
 225     /**
 226      * Creates a localized String representing all the relations in the set
 227      * using the default locale.
 228      *
 229      * @return comma separated localized String
 230      * @see AccessibleBundle#toDisplayString
 231      */
 232     public String toString() {
 233         String ret = "";
 234         if ((relations != null) && (relations.size() > 0)) {
 235             ret = ((AccessibleRelation) (relations.elementAt(0))).toDisplayString();
 236             for (int i = 1; i < relations.size(); i++) {
 237                 ret = ret + ","
 238                         + ((AccessibleRelation) (relations.elementAt(i))).
 239                                               toDisplayString();
 240             }
 241         }
 242         return ret;
 243     }
 244 }