001    /*
002    // $Id: //open/util/resgen/src/org/eigenbase/xom/GenericDef.java#3 $
003    // Package org.eigenbase.xom is an XML Object Mapper.
004    // Copyright (C) 2005-2005 The Eigenbase Project
005    // Copyright (C) 2005-2005 Disruptive Tech
006    // Copyright (C) 2005-2005 LucidEra, Inc.
007    // Portions Copyright (C) 2001-2005 Kana Software, Inc. and others.
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 the
011    // Free Software Foundation; either version 2 of the License, or (at your
012    // option) any later version approved by The Eigenbase Project.
013    //
014    // This library is distributed in the hope that it will be useful, 
015    // but WITHOUT ANY WARRANTY; without even the implied warranty of
016    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017    // GNU Lesser General Public License for more details.
018    // 
019    // You should have received a copy of the GNU Lesser General Public License
020    // along with this library; if not, write to the Free Software
021    // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
022    //
023    // jhyde, 3 October, 2001
024    */
025    
026    package org.eigenbase.xom;
027    import java.io.PrintWriter;
028    import java.util.Hashtable;
029    import java.util.Vector;
030    
031    /**
032     * A <code>GenericDef</code> is a {@link ElementDef} whose attributes and
033     * children are stored in collections, not generated members.  It is convenient
034     * for building XML documents, but is not strongly typed.
035     *
036     * @author jhyde
037     * @since 3 October, 2001
038     * @version $Id: //open/util/resgen/src/org/eigenbase/xom/GenericDef.java#3 $
039     **/
040    public class GenericDef extends ElementDef {
041        private String tagName;
042        private Vector children;
043        private OrderedStringMap attributes;
044    
045        public GenericDef(String tagName)
046        {
047            this.tagName = tagName;
048            this.children = new Vector();
049            this.attributes = new OrderedStringMap();
050        }
051    
052        // implement ElementDef
053        public void display(PrintWriter out, int indent)
054        {
055            out.println(getName());
056            for (int i = 0, count = attributes.size(); i < count; i++) {
057                String key = attributes.keyAt(i);
058                Object value = attributes.valueAt(i);
059                displayAttribute(out, key, value.toString(), indent + 1);
060            }
061            for (int i = 0, count = children.size(); i < count; i++) {
062                ElementDef child = (ElementDef) children.elementAt(i);
063                displayElement(out, "?", child, indent + 1);
064            }
065        }
066    
067        // implement NodeDef
068        public void displayXML(XMLOutput out, int indent)
069        {
070            out.beginBeginTag(tagName);
071            for (int i = 0, count = attributes.size(); i < count; i++) {
072                String key = attributes.keyAt(i);
073                Object value = attributes.valueAt(i);
074                out.attribute(key, value.toString());
075            }
076            out.endBeginTag(tagName);
077            for (int i = 0, count = children.size(); i < count; i++) {
078                NodeDef child = (NodeDef) children.elementAt(i);
079                child.displayXML(out, indent + 1);
080            }
081            out.endTag(tagName);
082        }
083    
084        // override ElementDef
085        public int getType()
086        {
087            return DOMWrapper.ELEMENT;
088        }
089    
090        /**
091         * Returns the tag name of this element, or null for TEXT elements.
092         */
093        public String getName()
094        {
095            return tagName;
096        }
097    
098        public void addChild(NodeDef element)
099        {
100            children.addElement(element);
101        }
102    
103        public NodeDef[] getChildren()
104        {
105            NodeDef[] a = new NodeDef[children.size()];
106            children.copyInto(a);
107            return a;
108        }
109    
110        public void setAttribute(String key, Object value)
111        {
112            attributes.put(key, value);
113        }
114    
115        public Object getAttribute(String key)
116        {
117            return attributes.get(key);
118        }
119    
120        private static class OrderedStringMap
121        {
122            Vector v;
123            Hashtable h;
124    
125            OrderedStringMap()
126            {
127                v = new Vector();
128                h = new Hashtable();
129            }
130            int size()
131            {
132                return v.size();
133            }
134            Object get(String key)
135            {
136                return h.get(key);
137            }
138            void put(String key, Object value)
139            {
140                if (h.put(key, value) == null) {
141                    // attribute does not have a value; append to vector
142                    v.addElement(new StringMapEntry(key,value));
143                } else {
144                    // attribute already has a value; replace it
145                    for (int i = 0, count = v.size(); i < count; i++) {
146                        StringMapEntry entry = (StringMapEntry) v.elementAt(i);
147                        if (entry.key.equals(key)) {
148                            entry.value = value;
149                            return;
150                        }
151                    }
152                    throw new Error(
153                        "key " + key + " not found in OrderedStringMap");
154                }
155            }
156            String keyAt(int i)
157            {
158                return ((StringMapEntry) v.elementAt(i)).key;
159            }
160            Object valueAt(int i)
161            {
162                return ((StringMapEntry) v.elementAt(i)).value;
163            }
164        };
165    
166        private static class StringMapEntry
167        {
168            String key;
169            Object value;
170            StringMapEntry(String key, Object value)
171            {
172                this.key = key;
173                this.value = value;
174            }
175        }
176    }
177    
178    
179    // End GenericDef.java