    001    /* ========================================================================
    002     * JCommon : a free general purpose class library for the Java(tm) platform
    003     * ========================================================================
    004     *
    005     * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
    006     *
    007     * Project Info:  http://www.jfree.org/jcommon/index.html
    008     *
    009     * This library is free software; you can redistribute it and/or modify it
    010     * under the terms of the GNU Lesser General Public License as published by
    011     * the Free Software Foundation; either version 2.1 of the License, or
    012     * (at your option) any later version.
    013     *
    014     * This library is distributed in the hope that it will be useful, but
    015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
    017     * License for more details.
    018     *
    019     * You should have received a copy of the GNU Lesser General Public
    020     * License along with this library; if not, write to the Free Software
    021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
    022     * USA.
    023     *
    024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
    025     * in the United States and other countries.]
    026     *
    027     * ------------------
    028     * AttributeList.java
    029     * ------------------
    030     * (C)opyright 2003-2005, by Thomas Morgner and Contributors.
    031     *
    032     * Original Author:  Thomas Morgner;
    033     * Contributor(s):   David Gilbert (for Object Refinery Limited);
    034     *
    035     * $Id: AttributeList.java,v 1.3 2005/10/18 13:35:06 mungady Exp $
    036     *
    037     * Changes
    038     * -------
    039     * 25-Sep-2003 : Initial version (TM);
    040     * 26-Nov-2003 : Javadoc updates (DG);
    041     *
    042     */
    043
    044    package org.jfree.xml.writer;
    045
    046    import java.util.Iterator;
    047    import java.util.List;
    048
    049    /**
    050     * The attribute list is used by a writer to specify the attributes
    051     * of an XML element in a certain order.
    052     *
    053     * @author Thomas Morgner
    054     */
    055    public class AttributeList {
    056
    057        /**
    058         * A name/value pair of the attribute list.
    059         */
    060        private static class AttributeEntry {
    061
    062            /** The name of the attribute entry. */
    063            private String name;
    064
    065            /** The value of the attribute entry. */
    066            private String value;
    067
    068            /**
    069             * Creates a new attribute entry for the given name and value.
    070             *
    071             * @param name  the attribute name (<code>null</code> not permitted).
    072             * @param value the attribute value (<code>null</code> not permitted).
    073             */
    074            public AttributeEntry(final String name, final String value) {
    075                if (name == null) {
    076                    throw new NullPointerException("Name must not be null. ["
    077                                                   + name + ", " + value + "]");
    078                }
    079                if (value == null) {
    080                    throw new NullPointerException("Value must not be null. ["
    081                                                   + name + ", " + value + "]");
    082                }
    083                this.name = name;
    084                this.value = value;
    085            }
    086
    087            /**
    088             * Returns the attribute name.
    089             *
    090             * @return the name.
    091             */
    092            public String getName() {
    093                return this.name;
    094            }
    095
    096            /**
    097             * Returns the value of this attribute entry.
    098             *
    099             * @return the value of the entry.
    100             */
    101            public String getValue() {
    102                return this.value;
    103            }
    104
    105            /**
    106             * Checks whether the given object is an attribute entry with the same name.
    107             *
    108             * @param o  the suspected other attribute entry.
    109             *
    110             * @return <code>true</code> if the given object is equal, <code>false</code> otherwise.
    111             */
    112            public boolean equals(final Object o) {
    113                if (this == o) {
    114                    return true;
    115                }
    116                if (!(o instanceof AttributeEntry)) {
    117                    return false;
    118                }
    119
    120                final AttributeEntry attributeEntry = (AttributeEntry) o;
    121                if (!this.name.equals(attributeEntry.name)) {
    122                    return false;
    123                }
    124                return true;
    125            }
    126
    127            /**
    128             * Computes an hashcode for this entry.
    129             *
    130             * @return the hashcode.
    131             */
    132            public int hashCode() {
    133                return this.name.hashCode();
    134            }
    135        }
    136
    137        /**
    138         * An iterator over the attribute names of this list.
    139         */
    140        private static class AttributeIterator implements Iterator {
    141
    142            /** The backend is an iterator over the attribute entries. */
    143            private Iterator backend;
    144
    145            /**
    146             * Creates a new attribute iterator using the given iterator as backend.
    147             *
    148             * @param backend  an iterator over the attribute entries (<code>null</code> not permitted).
    149             */
    150            public AttributeIterator(final Iterator backend) {
    151                if (backend == null) {
    152                    throw new NullPointerException();
    153                }
    154                this.backend = backend;
    155            }
    156
    157            /**
    158             * Returns <tt>true</tt> if the iteration has more elements. (In other
    159             * words, returns <tt>true</tt> if <tt>next</tt> would return an element
    160             * rather than throwing an exception.)
    161             *
    162             * @return <tt>true</tt> if the iterator has more elements.
    163             */
    164            public boolean hasNext() {
    165                return this.backend.hasNext();
    166            }
    167
    168            /**
    169             * Returns the next element in the iteration.
    170             *
    171             * @return the next element in the iteration.
    172             */
    173            public Object next() {
    174                final AttributeEntry entry = (AttributeEntry) this.backend.next();
    175                if (entry != null) {
    176                    return entry.getName();
    177                }
    178                return entry;
    179            }
    180
    181            /**
    182             *
    183             * Removes from the underlying collection the last element returned by the
    184             * iterator (optional operation).  This method can be called only once per
    185             * call to <tt>next</tt>.  The behavior of an iterator is unspecified if
    186             * the underlying collection is modified while the iteration is in
    187             * progress in any way other than by calling this method.
    188             */
    189            public void remove() {
    190                this.backend.remove();
    191            }
    192        }
    193
    194        /** The storage for all entries of this list. */
    195        private List entryList;
    196
    197        /**
    198         * Creates an empty attribute list with no default values.
    199         */
    200        public AttributeList() {
    201            this.entryList = new java.util.ArrayList();
    202        }
    203
    204        /**
    205         * Returns an iterator over all attribute names. The names are returned
    206         * in their oder of addition to the list. The iterator contains strings.
    207         *
    208         * @return the iterator over all attribute names.
    209         */
    210        public Iterator keys() {
    211            return new AttributeIterator(this.entryList.iterator());
    212        }
    213
    214        /**
    215         * Defines an attribute.
    216         *
    217         * @param name the name of the attribute to be defined
    218         * @param value the value of the attribute.
    219         */
    220        public synchronized void setAttribute(final String name, final String value) {
    221            final AttributeEntry entry = new AttributeEntry(name, value);
    222            final int pos = this.entryList.indexOf(entry);
    223            if (pos != -1) {
    224                this.entryList.remove(pos);
    225            }
    226            this.entryList.add(entry);
    227        }
    228
    229        /**
    230         * Returns the attribute value for the given attribute name or null,
    231         * if the attribute is not defined in this list.
    232         *
    233         * @param name the name of the attribute
    234         * @return the attribute value or null.
    235         */
    236        public synchronized String getAttribute(final String name) {
    237            return getAttribute(name, null);
    238        }
    239
    240        /**
    241         * Returns the attribute value for the given attribute name or the given
    242         * defaultvalue, if the attribute is not defined in this list.
    243         *
    244         * @param name the name of the attribute.
    245         * @param defaultValue  the default value.
    246         *
    247         * @return the attribute value or the defaultValue.
    248         */
    249        public synchronized String getAttribute(final String name, final String defaultValue) {
    250            for (int i = 0; i < this.entryList.size(); i++) {
    251                final AttributeEntry ae = (AttributeEntry) this.entryList.get(i);
    252                if (ae.getName().equals(name)) {
    253                    return ae.getValue();
    254                }
    255            }
    256            return defaultValue;
    257        }
    258
    259        /**
    260         * Removes the attribute with the given name from the list.
    261         *
    262         * @param name the name of the attribute which should be removed..
    263         */
    264        public synchronized void removeAttribute(final String name) {
    265            for (int i = 0; i < this.entryList.size(); i++) {
    266                final AttributeEntry ae = (AttributeEntry) this.entryList.get(i);
    267                if (ae.getName().equals(name)) {
    268                    this.entryList.remove(ae);
    269                    return;
    270                }
    271            }
    272        }
    273    }