Save This Page
Home » openjdk-7 » javax » naming » directory » [javadoc | source]
    1   /*
    2    * Copyright 1999-2004 Sun Microsystems, Inc.  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.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   
   27   package javax.naming.directory;
   28   
   29   import java.util.Hashtable;
   30   import java.util.Enumeration;
   31   
   32   import javax.naming.NamingException;
   33   import javax.naming.NamingEnumeration;
   34   
   35   /**
   36     * This class provides a basic implementation
   37     * of the Attributes interface.
   38     *<p>
   39     * BasicAttributes is either case-sensitive or case-insensitive (case-ignore).
   40     * This property is determined at the time the BasicAttributes constructor
   41     * is called.
   42     * In a case-insensitive BasicAttributes, the case of its attribute identifiers
   43     * is ignored when searching for an attribute, or adding attributes.
   44     * In a case-sensitive BasicAttributes, the case is significant.
   45     *<p>
   46     * When the BasicAttributes class needs to create an Attribute, it
   47     * uses BasicAttribute. There is no other dependency on BasicAttribute.
   48     *<p>
   49     * Note that updates to BasicAttributes (such as adding or removing an attribute)
   50     * does not affect the corresponding representation in the directory.
   51     * Updates to the directory can only be effected
   52     * using operations in the DirContext interface.
   53     *<p>
   54     * A BasicAttributes instance is not synchronized against concurrent
   55     * multithreaded access. Multiple threads trying to access and modify
   56     * a single BasicAttributes instance should lock the object.
   57     *
   58     * @author Rosanna Lee
   59     * @author Scott Seligman
   60     *
   61     * @see DirContext#getAttributes
   62     * @see DirContext#modifyAttributes
   63     * @see DirContext#bind
   64     * @see DirContext#rebind
   65     * @see DirContext#createSubcontext
   66     * @see DirContext#search
   67     * @since 1.3
   68     */
   69   
   70   public class BasicAttributes implements Attributes {
   71       /**
   72        * Indicates whether case of attribute ids is ignored.
   73        * @serial
   74        */
   75       private boolean ignoreCase = false;
   76   
   77       // The 'key' in attrs is stored in the 'right case'.
   78       // If ignoreCase is true, key is aways lowercase.
   79       // If ignoreCase is false, key is stored as supplied by put().
   80       // %%% Not declared "private" due to bug 4064984.
   81       transient Hashtable attrs = new Hashtable(11);
   82   
   83       /**
   84         * Constructs a new instance of Attributes.
   85         * The character case of attribute identifiers
   86         * is significant when subsequently retrieving or adding attributes.
   87         */
   88       public BasicAttributes() {
   89       }
   90   
   91       /**
   92         * Constructs a new instance of Attributes.
   93         * If <code>ignoreCase</code> is true, the character case of attribute
   94         * identifiers is ignored; otherwise the case is significant.
   95         * @param ignoreCase true means this attribute set will ignore
   96         *                   the case of its attribute identifiers
   97         *                   when retrieving or adding attributes;
   98         *                   false means case is respected.
   99         */
  100       public BasicAttributes(boolean ignoreCase) {
  101           this.ignoreCase = ignoreCase;
  102       }
  103   
  104       /**
  105         * Constructs a new instance of Attributes with one attribute.
  106         * The attribute specified by attrID and val are added to the newly
  107         * created attribute.
  108         * The character case of attribute identifiers
  109         * is significant when subsequently retrieving or adding attributes.
  110         * @param attrID   non-null The id of the attribute to add.
  111         * @param val The value of the attribute to add. If null, a null
  112         *        value is added to the attribute.
  113         */
  114       public BasicAttributes(String attrID, Object val) {
  115           this();
  116           this.put(new BasicAttribute(attrID, val));
  117       }
  118   
  119       /**
  120         * Constructs a new instance of Attributes with one attribute.
  121         * The attribute specified by attrID and val are added to the newly
  122         * created attribute.
  123         * If <code>ignoreCase</code> is true, the character case of attribute
  124         * identifiers is ignored; otherwise the case is significant.
  125         * @param attrID   non-null The id of the attribute to add.
  126         *           If this attribute set ignores the character
  127         *           case of its attribute ids, the case of attrID
  128         *           is ignored.
  129         * @param val The value of the attribute to add. If null, a null
  130         *        value is added to the attribute.
  131         * @param ignoreCase true means this attribute set will ignore
  132         *                   the case of its attribute identifiers
  133         *                   when retrieving or adding attributes;
  134         *                   false means case is respected.
  135         */
  136       public BasicAttributes(String attrID, Object val, boolean ignoreCase) {
  137           this(ignoreCase);
  138           this.put(new BasicAttribute(attrID, val));
  139       }
  140   
  141       public Object clone() {
  142           BasicAttributes attrset;
  143           try {
  144               attrset = (BasicAttributes)super.clone();
  145           } catch (CloneNotSupportedException e) {
  146               attrset = new BasicAttributes(ignoreCase);
  147           }
  148           attrset.attrs = (Hashtable)attrs.clone();
  149           return attrset;
  150       }
  151   
  152       public boolean isCaseIgnored() {
  153           return ignoreCase;
  154       }
  155   
  156       public int size() {
  157           return attrs.size();
  158       }
  159   
  160       public Attribute get(String attrID) {
  161           Attribute attr = (Attribute) attrs.get(
  162                   ignoreCase ? attrID.toLowerCase() : attrID);
  163           return (attr);
  164       }
  165   
  166       public NamingEnumeration<Attribute> getAll() {
  167           return new AttrEnumImpl();
  168       }
  169   
  170       public NamingEnumeration<String> getIDs() {
  171           return new IDEnumImpl();
  172       }
  173   
  174       public Attribute put(String attrID, Object val) {
  175           return this.put(new BasicAttribute(attrID, val));
  176       }
  177   
  178       public Attribute put(Attribute attr) {
  179           String id = attr.getID();
  180           if (ignoreCase) {
  181               id = id.toLowerCase();
  182           }
  183           return (Attribute)attrs.put(id, attr);
  184       }
  185   
  186       public Attribute remove(String attrID) {
  187           String id = (ignoreCase ? attrID.toLowerCase() : attrID);
  188           return (Attribute)attrs.remove(id);
  189       }
  190   
  191       /**
  192        * Generates the string representation of this attribute set.
  193        * The string consists of each attribute identifier and the contents
  194        * of each attribute. The contents of this string is useful
  195        * for debugging and is not meant to be interpreted programmatically.
  196        *
  197        * @return A non-null string listing the contents of this attribute set.
  198        */
  199       public String toString() {
  200           if (attrs.size() == 0) {
  201               return("No attributes");
  202           } else {
  203               return attrs.toString();
  204           }
  205       }
  206   
  207       /**
  208        * Determines whether this <tt>BasicAttributes</tt> is equal to another
  209        * <tt>Attributes</tt>
  210        * Two <tt>Attributes</tt> are equal if they are both instances of
  211        * <tt>Attributes</tt>,
  212        * treat the case of attribute IDs the same way, and contain the
  213        * same attributes. Each <tt>Attribute</tt> in this <tt>BasicAttributes</tt>
  214        * is checked for equality using <tt>Object.equals()</tt>, which may have
  215        * be overridden by implementations of <tt>Attribute</tt>).
  216        * If a subclass overrides <tt>equals()</tt>,
  217        * it should override <tt>hashCode()</tt>
  218        * as well so that two <tt>Attributes</tt> instances that are equal
  219        * have the same hash code.
  220        * @param obj the possibly null object to compare against.
  221        *
  222        * @return true If obj is equal to this BasicAttributes.
  223        * @see #hashCode
  224        */
  225       public boolean equals(Object obj) {
  226           if ((obj != null) && (obj instanceof Attributes)) {
  227               Attributes target = (Attributes)obj;
  228   
  229               // Check case first
  230               if (ignoreCase != target.isCaseIgnored()) {
  231                   return false;
  232               }
  233   
  234               if (size() == target.size()) {
  235                   Attribute their, mine;
  236                   try {
  237                       NamingEnumeration theirs = target.getAll();
  238                       while (theirs.hasMore()) {
  239                           their = (Attribute)theirs.next();
  240                           mine = get(their.getID());
  241                           if (!their.equals(mine)) {
  242                               return false;
  243                           }
  244                       }
  245                   } catch (NamingException e) {
  246                       return false;
  247                   }
  248                   return true;
  249               }
  250           }
  251           return false;
  252       }
  253   
  254       /**
  255        * Calculates the hash code of this BasicAttributes.
  256        *<p>
  257        * The hash code is computed by adding the hash code of
  258        * the attributes of this object. If this BasicAttributes
  259        * ignores case of its attribute IDs, one is added to the hash code.
  260        * If a subclass overrides <tt>hashCode()</tt>,
  261        * it should override <tt>equals()</tt>
  262        * as well so that two <tt>Attributes</tt> instances that are equal
  263        * have the same hash code.
  264        *
  265        * @return an int representing the hash code of this BasicAttributes instance.
  266        * @see #equals
  267        */
  268       public int hashCode() {
  269           int hash = (ignoreCase ? 1 : 0);
  270           try {
  271               NamingEnumeration all = getAll();
  272               while (all.hasMore()) {
  273                   hash += all.next().hashCode();
  274               }
  275           } catch (NamingException e) {}
  276           return hash;
  277       }
  278   
  279       /**
  280        * Overridden to avoid exposing implementation details.
  281        * @serialData Default field (ignoreCase flag -- a boolean), followed by
  282        * the number of attributes in the set
  283        * (an int), and then the individual Attribute objects.
  284        */
  285       private void writeObject(java.io.ObjectOutputStream s)
  286               throws java.io.IOException {
  287           s.defaultWriteObject(); // write out the ignoreCase flag
  288           s.writeInt(attrs.size());
  289           Enumeration attrEnum = attrs.elements();
  290           while (attrEnum.hasMoreElements()) {
  291               s.writeObject(attrEnum.nextElement());
  292           }
  293       }
  294   
  295       /**
  296        * Overridden to avoid exposing implementation details.
  297        */
  298       private void readObject(java.io.ObjectInputStream s)
  299               throws java.io.IOException, ClassNotFoundException {
  300           s.defaultReadObject();  // read in the ignoreCase flag
  301           int n = s.readInt();    // number of attributes
  302           attrs = (n >= 1)
  303               ? new Hashtable(n * 2)
  304               : new Hashtable(2); // can't have initial size of 0 (grrr...)
  305           while (--n >= 0) {
  306               put((Attribute)s.readObject());
  307           }
  308       }
  309   
  310   
  311   class AttrEnumImpl implements NamingEnumeration<Attribute> {
  312   
  313       Enumeration<Attribute> elements;
  314   
  315       public AttrEnumImpl() {
  316           this.elements = attrs.elements();
  317       }
  318   
  319       public boolean hasMoreElements() {
  320           return elements.hasMoreElements();
  321       }
  322   
  323       public Attribute nextElement() {
  324           return elements.nextElement();
  325       }
  326   
  327       public boolean hasMore() throws NamingException {
  328           return hasMoreElements();
  329       }
  330   
  331       public Attribute next() throws NamingException {
  332           return nextElement();
  333       }
  334   
  335       public void close() throws NamingException {
  336           elements = null;
  337       }
  338   }
  339   
  340   class IDEnumImpl implements NamingEnumeration<String> {
  341   
  342       Enumeration<Attribute> elements;
  343   
  344       public IDEnumImpl() {
  345           // Walking through the elements, rather than the keys, gives
  346           // us attribute IDs that have not been converted to lowercase.
  347           this.elements = attrs.elements();
  348       }
  349   
  350       public boolean hasMoreElements() {
  351           return elements.hasMoreElements();
  352       }
  353   
  354       public String nextElement() {
  355           Attribute attr = elements.nextElement();
  356           return attr.getID();
  357       }
  358   
  359       public boolean hasMore() throws NamingException {
  360           return hasMoreElements();
  361       }
  362   
  363       public String next() throws NamingException {
  364           return nextElement();
  365       }
  366   
  367       public void close() throws NamingException {
  368           elements = null;
  369       }
  370   }
  371   
  372       /**
  373        * Use serialVersionUID from JNDI 1.1.1 for interoperability.
  374        */
  375       private static final long serialVersionUID = 4980164073184639448L;
  376   }

Save This Page
Home » openjdk-7 » javax » naming » directory » [javadoc | source]