001/*
002 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
003 * 
004 * This software is open source. 
005 * See the bottom of this file for the licence.
006 * 
007 * $Id: DefaultElement.java,v 1.46 2002/02/01 13:04:32 jstrachan Exp $
008 */
009
010package org.dom4j.tree;
011
012import java.io.IOException;
013import java.io.StringWriter;
014import java.io.PrintWriter;
015import java.util.ArrayList;
016import java.util.Collections;
017import java.util.HashMap;
018import java.util.Iterator;
019import java.util.List;
020import java.util.Map;
021import java.util.StringTokenizer;
022
023import org.dom4j.Attribute;
024import org.dom4j.Branch;
025import org.dom4j.CDATA;
026import org.dom4j.CharacterData;
027import org.dom4j.Comment;
028import org.dom4j.Document;
029import org.dom4j.DocumentFactory;
030import org.dom4j.Element;
031import org.dom4j.Entity;
032import org.dom4j.IllegalAddException;
033import org.dom4j.Node;
034import org.dom4j.Namespace;
035import org.dom4j.QName;
036import org.dom4j.ProcessingInstruction;
037import org.dom4j.Text;
038
039/** <p><code>DefaultElement</code> is the default DOM4J default implementation
040  * of an XML element.</p>
041  *
042  * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
043  * @version $Revision: 1.46 $
044  */
045public class DefaultElement extends AbstractElement {
046    
047    /** The <code>DocumentFactory</code> instance used by default */
048    private static transient final DocumentFactory DOCUMENT_FACTORY = DocumentFactory.getInstance();
049
050    
051    /** The <code>QName</code> for this element */
052    private QName qname;
053    
054    /** Stores the parent branch of this node which is either a Document 
055      * if this element is the root element in a document, or another Element 
056      * if it is a child of the root document, or null if it has not been added
057      * to a document yet. 
058       */
059    private Branch parentBranch;
060
061    /** Stores null for no content, a Node for a single content node
062      * or a List for multiple content nodes. 
063      * The List will be lazily constructed when required. */
064    private Object content;
065    
066    /** Lazily constructes list of attributes */
067    private Object attributes;
068
069
070    
071    public DefaultElement(String name) { 
072        this.qname = DOCUMENT_FACTORY.createQName(name);
073    }
074
075    public DefaultElement(QName qname) { 
076        this.qname = qname;
077    }
078
079    public DefaultElement(QName qname, int attributeCount) { 
080        this.qname = qname;
081        if ( attributeCount > 1 ) {
082            this.attributes = new ArrayList( attributeCount );
083        }
084    }
085
086    public DefaultElement(String name, Namespace namespace) { 
087        this.qname = DOCUMENT_FACTORY.createQName(name, namespace);
088    }
089
090    public Element getParent() {
091        return ( parentBranch instanceof Element ) 
092            ? (Element) parentBranch : null;
093    }
094
095    public void setParent(Element parent) {
096        if ( parentBranch instanceof Element || parent != null ) {
097            parentBranch = parent;
098        }
099    }
100
101    public Document getDocument() {
102        if ( parentBranch instanceof Document ) {
103            return (Document) parentBranch;
104        }
105        else if ( parentBranch instanceof Element ) {
106            Element parent = (Element) parentBranch;
107            return parent.getDocument();
108        }
109        return null;
110    }
111    
112    public void setDocument(Document document) {
113        if ( parentBranch instanceof Document || document != null ) {
114            parentBranch = document;
115        }
116    }
117    
118    public boolean supportsParent() {
119        return true;
120    }
121
122    public QName getQName() {
123        return qname;
124    }
125
126    public void setQName(QName qname) {
127        this.qname = qname;
128    }
129    
130    public String getText() {
131        if ( content instanceof List ) {
132            return super.getText();
133        }
134        else {
135            if ( content != null ) {
136                return getContentAsText( content );
137            }
138            else {
139                return "";
140            }
141        }
142    }
143    
144    public String getStringValue() {
145        if ( content instanceof List ) {
146            List list = (List) content;
147            int size = list.size();
148            if ( size > 0 ) {
149                if ( size == 1 ) {
150                    // optimised to avoid StringBuffer creation
151                    return getContentAsStringValue( list.get(0) );
152                }
153                else {
154                    StringBuffer buffer = new StringBuffer();
155                    for ( int i = 0; i < size; i++ ) {
156                        Object node = list.get(i);
157                        String string = getContentAsStringValue( node ); 
158                        if ( string.length() > 0 ) {
159                            if ( USE_STRINGVALUE_SEPARATOR ) {
160                                if ( buffer.length() > 0 ) {
161                                    buffer.append( ' ' );
162                                }
163                            }
164                            buffer.append( string );
165                        }
166                    }
167                    return buffer.toString();
168                }
169            }
170        }
171        else {
172            if ( content != null ) {
173                return getContentAsStringValue( content );
174            }
175        }
176        return "";
177    }
178    
179    public Object clone() {
180        DefaultElement answer = (DefaultElement) super.clone();
181        if ( answer != this ) {
182            answer.content = null;
183            answer.attributes = null;
184            answer.appendAttributes(this);
185            answer.appendContent(this);
186        }
187        return answer;
188    }
189    
190    
191    public Namespace getNamespaceForPrefix(String prefix) {
192        if ( prefix == null ) {
193            prefix = "";
194        }
195        if ( prefix.equals( getNamespacePrefix() ) ) {
196            return getNamespace();
197        }
198        else {
199            if ( content instanceof List ) {
200                List list = (List) content;
201                int size = list.size();
202                for ( int i = 0; i < size; i++ ) {
203                    Object object = list.get(i);
204                    if ( object instanceof Namespace ) {
205                        Namespace namespace = (Namespace) object;
206                        if ( prefix.equals( namespace.getPrefix() ) ) {
207                            return namespace;
208                        }
209                    }
210                }
211            }
212            else 
213            if ( content instanceof Namespace ) {
214                Namespace namespace = (Namespace) content;
215                if ( prefix.equals( namespace.getPrefix() ) ) {
216                    return namespace;
217                }
218            }
219        }
220        Element parent = getParent();
221        if ( parent != null ) {
222            Namespace answer = parent.getNamespaceForPrefix(prefix);
223            if ( answer != null ) {
224                return answer;
225            }               
226        }
227        if ( prefix == null || prefix.length() <= 0 ) {
228            return Namespace.NO_NAMESPACE;
229        }
230        return null;
231    }
232   
233    public Namespace getNamespaceForURI(String uri) {
234        if ( uri == null || uri.length() <= 0 ) {
235            return Namespace.NO_NAMESPACE;
236        }
237        else if ( uri.equals( getNamespaceURI() ) ) {
238            return getNamespace();
239        }
240        else {
241            if ( content instanceof List ) {
242                List list = (List) content;
243                int size = list.size();
244                for ( int i = 0; i < size; i++ ) {
245                    Object object = list.get(i);
246                    if ( object instanceof Namespace ) {
247                        Namespace namespace = (Namespace) object;
248                        if ( uri.equals( namespace.getURI() ) ) {
249                            return namespace;
250                        }
251                    }
252                }
253            }
254            else 
255            if ( content instanceof Namespace ) {
256                Namespace namespace = (Namespace) content;
257                if ( uri.equals( namespace.getURI() ) ) {
258                    return namespace;
259                }
260            }
261            Element parent = getParent();
262            if ( parent != null ) {
263                return parent.getNamespaceForURI(uri);
264            }
265            return null;
266        }
267    }
268    
269    public List declaredNamespaces() {
270        BackedList answer = createResultList();
271        if ( getNamespaceURI().length() > 0 ) {
272            answer.addLocal( getNamespace() );
273        }
274        if ( content instanceof List ) {
275            List list = (List) content;
276            int size = list.size();
277            for ( int i = 0; i < size; i++ ) {
278                Object object = list.get(i);
279                if ( object instanceof Namespace ) {
280                    answer.addLocal( object );
281                }
282            }
283        }
284        else {
285            if ( content instanceof Namespace ) {
286                answer.addLocal( content );
287            }
288        }
289        return answer;
290    }
291    
292    public List additionalNamespaces() {
293        if ( content instanceof List ) {
294            List list = (List) content;
295            int size = list.size();
296            BackedList answer = createResultList();
297            for ( int i = 0; i < size; i++ ) {
298                Object object = list.get(i);
299                if ( object instanceof Namespace ) {
300                    Namespace namespace = (Namespace) object;
301                    answer.addLocal( namespace );
302                }
303            }
304            return answer;
305        }
306        else {
307            if ( content instanceof Namespace ) {
308                Namespace namespace = (Namespace) content;
309                return createSingleResultList( namespace );
310            }
311            else {
312                return createEmptyList();
313            }
314        }
315    }
316    
317    public List additionalNamespaces(String defaultNamespaceURI) {
318        if ( content instanceof List ) {
319            List list = (List) content;
320            BackedList answer = createResultList();
321            int size = list.size();
322            for ( int i = 0; i < size; i++ ) {
323                Object object = list.get(i);
324                if ( object instanceof Namespace ) {
325                    Namespace namespace = (Namespace) object;
326                    if ( ! defaultNamespaceURI.equals( namespace.getURI() ) ) {
327                        answer.addLocal( namespace );
328                    }
329                }
330            }
331            return answer;
332        }
333        else {
334            if ( content instanceof Namespace ) {
335                Namespace namespace = (Namespace) content;
336                if ( ! defaultNamespaceURI.equals( namespace.getURI() ) ) {
337                    return createSingleResultList( namespace );
338                }
339            }
340        }
341        return createEmptyList();
342    }
343    
344    
345    // Processing instruction API
346    
347    public List processingInstructions() {
348        if ( content instanceof List ) {
349            List list = (List) content;
350            BackedList answer = createResultList();
351            int size = list.size();
352            for ( int i = 0; i < size; i++ ) {
353                Object object = list.get(i);
354                if ( object instanceof ProcessingInstruction ) {
355                    answer.addLocal( object );
356                }
357            }
358            return answer;
359        }
360        else {
361            if ( content instanceof ProcessingInstruction ) {
362                return createSingleResultList( content );
363            }
364            return createEmptyList();
365        }
366    }
367    
368    public List processingInstructions(String target) {
369        if ( content instanceof List ) {
370            List list = (List) content;
371            BackedList answer = createResultList();
372            int size = list.size();
373            for ( int i = 0; i < size; i++ ) {
374                Object object = list.get(i);
375                if ( object instanceof ProcessingInstruction ) {
376                    ProcessingInstruction pi = (ProcessingInstruction) object;
377                    if ( target.equals( pi.getName() ) ) {                  
378                        answer.addLocal( pi );
379                    }
380                }
381            }
382            return answer;
383        }
384        else {
385            if ( content instanceof ProcessingInstruction ) {
386                ProcessingInstruction pi = (ProcessingInstruction) content;
387                if ( target.equals( pi.getName() ) ) {                  
388                    return createSingleResultList( pi );
389                }
390            }
391            return createEmptyList();
392        }
393    }
394    
395    public ProcessingInstruction processingInstruction(String target) {
396        if ( content instanceof List ) {
397            List list = (List) content;
398            int size = list.size();
399            for ( int i = 0; i < size; i++ ) {
400                Object object = list.get(i);
401                if ( object instanceof ProcessingInstruction ) {
402                    ProcessingInstruction pi = (ProcessingInstruction) object;
403                    if ( target.equals( pi.getName() ) ) {                  
404                        return pi;
405                    }
406                }
407            }
408        }
409        else {
410            if ( content instanceof ProcessingInstruction ) {
411                ProcessingInstruction pi = (ProcessingInstruction) content;
412                if ( target.equals( pi.getName() ) ) {                  
413                    return pi;
414                }
415            }
416        }
417        return null;
418    }
419    
420    public boolean removeProcessingInstruction(String target) {
421        if ( content instanceof List ) {
422            List list = (List) content;
423            for ( Iterator iter = list.iterator(); iter.hasNext(); ) {
424                Object object = iter.next();
425                if ( object instanceof ProcessingInstruction ) {
426                    ProcessingInstruction pi = (ProcessingInstruction) object;
427                    if ( target.equals( pi.getName() ) ) {                  
428                        iter.remove();
429                        return true;
430                    }
431                }
432            }
433        }
434        else {
435            if ( content instanceof ProcessingInstruction ) {
436                ProcessingInstruction pi = (ProcessingInstruction) content;
437                if ( target.equals( pi.getName() ) ) {                  
438                    content = null;
439                    return true;
440                }
441            }
442        }
443        return false;
444    }
445    
446    public Element element(String name) {
447        if ( content instanceof List ) {
448            List list = (List) content;
449            int size = list.size();
450            for ( int i = 0; i < size; i++ ) {
451                Object object = list.get(i);
452                if ( object instanceof Element ) {
453                    Element element = (Element) object;
454                    if ( name.equals( element.getName() ) ) {
455                        return element;
456                    }
457                }
458            }
459        }
460        else {
461            if ( content instanceof Element ) {
462                Element element = (Element) content;
463                if ( name.equals( element.getName() ) ) {
464                    return element;
465                }
466            }
467        }
468        return null;
469    }
470    
471    public Element element(QName qName) {
472        if ( content instanceof List ) {
473            List list = (List) content;
474            int size = list.size();
475            for ( int i = 0; i < size; i++ ) {
476                Object object = list.get(i);
477                if ( object instanceof Element ) {
478                    Element element = (Element) object;
479                    if ( qName.equals( element.getQName() ) ) {
480                        return element;
481                    }
482                }
483            }
484        }
485        else {
486            if ( content instanceof Element ) {
487                Element element = (Element) content;
488                if ( qName.equals( element.getQName() ) ) {
489                    return element;
490                }
491            }
492        }
493        return null;
494    }
495
496    public Element element(String name, Namespace namespace) {
497        return element( getDocumentFactory().createQName( name, namespace ) );
498    }
499    
500    
501    
502    public List elements() {
503        if ( content instanceof List ) {
504            List list = (List) content;
505            BackedList answer = createResultList();
506            int size = list.size();
507            for ( int i = 0; i < size; i++ ) {
508                Object object = list.get(i);
509                if ( object instanceof Element ) {
510                    answer.addLocal( object );
511                }
512            }
513            return answer;
514        }
515        else {
516            if ( content instanceof Element ) {
517                Element element = (Element) content;
518                return createSingleResultList( element );
519            }
520            return createEmptyList();
521        }
522    }
523    
524    public List elements(String name) {
525        if ( content instanceof List ) {
526            List list = (List) content;
527            BackedList answer = createResultList();
528            int size = list.size();
529            for ( int i = 0; i < size; i++ ) {
530                Object object = list.get(i);
531                if ( object instanceof Element ) {
532                    Element element = (Element) object;
533                    if ( name.equals( element.getName() ) ) {
534                        answer.addLocal( element );
535                    }
536                }
537            }
538            return answer;
539        }
540        else {
541            if ( content instanceof Element ) {
542                Element element = (Element) content;
543                if ( name.equals( element.getName() ) ) {
544                    return createSingleResultList( element );
545                }
546            }
547            return createEmptyList();
548        }
549    }
550    
551    public List elements(QName qName) {
552        if ( content instanceof List ) {
553            List list = (List) content;
554            BackedList answer = createResultList();
555            int size = list.size();
556            for ( int i = 0; i < size; i++ ) {
557                Object object = list.get(i);
558                if ( object instanceof Element ) {
559                    Element element = (Element) object;
560                    if ( qName.equals( element.getQName() ) ) {
561                        answer.addLocal( element );
562                    }
563                }
564            }
565            return answer;
566        }
567        else {
568            if ( content instanceof Element ) {
569                Element element = (Element) content;
570                if ( qName.equals( element.getQName() ) ) {
571                    return createSingleResultList( element );
572                }
573            }
574            return createEmptyList();
575        }
576    }
577    
578    public List elements(String name, Namespace namespace) {
579        return elements( getDocumentFactory().createQName(name, namespace ) );
580    }
581    
582    public Iterator elementIterator() {
583        if ( content instanceof List ) {
584            List list = (List) content;
585            return new ElementIterator(list.iterator());
586        }
587        else {
588            if ( content instanceof Element ) {
589                Element element = (Element) content;
590                return createSingleIterator( element );
591            }
592            return EMPTY_ITERATOR;
593        }
594    }
595        
596    public Iterator elementIterator(String name) {
597        if ( content instanceof List ) {
598            List list = (List) content;
599            return new ElementNameIterator(list.iterator(), name);
600        }
601        else {
602            if ( content instanceof Element ) {
603                Element element = (Element) content;
604                if ( name.equals( element.getName() ) ) {
605                    return createSingleIterator( element );
606                }
607            }
608            return EMPTY_ITERATOR;
609        }
610    }
611    
612    public Iterator elementIterator(QName qName) {
613        if ( content instanceof List ) {
614            List list = (List) content;
615            return new ElementQNameIterator(list.iterator(), qName);
616        }
617        else {
618            if ( content instanceof Element ) {
619                Element element = (Element) content;
620                if ( qName.equals( element.getQName() ) ) {
621                    return createSingleIterator( element );
622                }
623            }
624            return EMPTY_ITERATOR;
625        }
626    }
627    
628    public Iterator elementIterator(String name, Namespace namespace) {
629        return elementIterator( getDocumentFactory().createQName( name, namespace ) );
630    }
631    
632    public void setContent(List content) {
633        if ( content instanceof ContentListFacade ) {
634            content = ((ContentListFacade) content).getBackingList();
635        }
636        if ( content == null ) {
637            this.content = null;
638        }
639        else {
640            int size = content.size();
641            List newContent = createContentList( size );
642            for ( int i = 0; i < size; i++ ) {
643                Object object = content.get(i);
644                if ( object instanceof Node ) {
645                    Node node = (Node) object;
646                    Element parent = node.getParent();
647                    if ( parent != null && parent != this ) {
648                        node = (Node) node.clone();
649                    }
650                    newContent.add( node );
651                    childAdded( node );
652                }
653                else if ( object != null ) {
654                    String text = object.toString();
655                    Node node = getDocumentFactory().createText( text );
656                    newContent.add( node );
657                    childAdded( node );
658                }
659            }
660            contentRemoved();
661            this.content = newContent;
662        }
663    }
664    
665    public void clearContent() {
666        if ( content != null ) {
667            contentRemoved();
668        }
669        content = null;
670    }
671    
672    
673    public Node node(int index) {
674        if ( index >= 0 ) {
675            Object node = content;
676            if ( content instanceof List ) {
677                List list = (List) content;
678                if ( index >= list.size() ) {
679                    return null;
680                }
681                node = list.get(index);
682            }
683            if (node != null) {
684                if (node instanceof Node) {
685                    return (Node) node;
686                }
687                else {
688                    return new DefaultText(node.toString());
689                }
690            }
691        }
692        return null;
693    }
694    
695    public int indexOf(Node node) {
696        if ( content instanceof List ) {
697            List list = (List) content;
698            return list.indexOf( node );
699        }
700        else {
701            return ( content != null && content.equals( node ) ) 
702                ? 0 : -1;
703        }
704    }
705    
706    public int nodeCount() {
707        if ( content instanceof List ) {
708            List list = (List) content;
709            return list.size();
710        }
711        else {
712            return ( content != null ) ? 1 : 0;
713        }
714    }
715    
716    public Iterator nodeIterator() {
717        if ( content instanceof List ) {
718            List list = (List) content;
719            return list.iterator();
720        }
721        else {
722            if ( content != null ) {
723                return createSingleIterator( content );
724            }
725            else {
726                return EMPTY_ITERATOR;
727            }
728        }
729    }
730
731    public List attributes() {
732        return new ContentListFacade(this, attributeList());
733    }
734    
735    public void setAttributes(List attributes) {
736        this.attributes = attributes;
737        if ( attributes instanceof ContentListFacade ) {
738            this.attributes = ((ContentListFacade) attributes).getBackingList();
739        }
740    }
741    
742    public Iterator attributeIterator() {
743        if ( attributes instanceof List ) {
744            List list = (List) attributes;
745            return list.iterator();
746        }
747        else if ( attributes != null ) {
748            return createSingleIterator( attributes );
749        } 
750        else {
751            return EMPTY_ITERATOR;
752        }
753    }
754    
755    public Attribute attribute(int index) {
756        if ( attributes instanceof List ) {
757            List list = (List) attributes;
758            return (Attribute) list.get(index);
759        }
760        else if ( attributes != null && index == 0 ) {
761            return (Attribute) attributes;
762        }
763        else {
764            return null;
765        }
766    }
767            
768    public int attributeCount() {
769        if ( attributes instanceof List ) {
770            List list = (List) attributes;
771            return list.size();
772        }
773        else {
774            return ( attributes != null ) ? 1 : 0;
775        }
776    }
777    
778    public Attribute attribute(String name) {
779        if ( attributes instanceof List ) {
780            List list = (List) attributes;
781            int size = list.size();
782            for ( int i = 0; i < size; i++ ) {
783                Attribute attribute = (Attribute) list.get(i);
784                if ( name.equals( attribute.getName() ) ) {
785                    return attribute;
786                }
787            }
788        }
789        else if ( attributes != null ) {
790            Attribute attribute = (Attribute) attributes;
791            if ( name.equals( attribute.getName() ) ) {
792                return attribute;
793            }
794        }
795        return null;
796    }
797
798    public Attribute attribute(QName qName) {
799        if ( attributes instanceof List ) {
800            List list = (List) attributes;
801            int size = list.size();
802            for ( int i = 0; i < size; i++ ) {
803                Attribute attribute = (Attribute) list.get(i);
804                if ( qName.equals( attribute.getQName() ) ) {
805                    return attribute;
806                }
807            }
808        }
809        else if ( attributes != null ) {
810            Attribute attribute = (Attribute) attributes;
811            if ( qName.equals( attribute.getQName() ) ) {
812                return attribute;
813            }
814        }
815        return null;
816    }
817
818    public Attribute attribute(String name, Namespace namespace) {
819        return attribute( getDocumentFactory().createQName( name, namespace ) );
820    }
821
822    public void add(Attribute attribute) {
823        if (attribute.getParent() != null) {
824            String message = 
825                "The Attribute already has an existing parent \"" 
826                + attribute.getParent().getQualifiedName() + "\"";
827            
828            throw new IllegalAddException( this, attribute, message );
829        }
830        
831        if ( attributes == null ) {
832            attributes = attribute;
833        }
834        else {
835            attributeList().add(attribute);
836        }
837        
838        childAdded(attribute);
839    }
840    
841
842    
843    public boolean remove(Attribute attribute) {
844        boolean answer = false;
845        
846        if ( attributes instanceof List ) {
847            List list = (List) attributes;            
848            answer = list.remove(attribute);
849            if ( ! answer ) {
850                // we may have a copy of the attribute
851                Attribute copy = attribute( attribute.getQName() );
852                if ( copy != null ) {
853                    list.remove( copy );
854                    answer = true;
855                }
856            }
857        }
858        else if ( attributes != null ) {
859            if ( attribute.equals( attributes ) ) {
860                attributes = null;
861                answer = true;
862            }
863            else {
864                // we may have a copy of the attribute
865                Attribute other = (Attribute) attributes;
866                if ( attribute.getQName().equals( other.getQName() ) ) {
867                    attributes = null;
868                    answer = true;
869                }
870            }
871        }
872        
873        if ( answer ) {
874            childRemoved(attribute);
875        }
876        return answer;
877    }
878
879    
880    
881    // Implementation methods
882    //-------------------------------------------------------------------------    
883    
884    protected void addNewNode(Node node) {
885        if (content == null) {
886            content = node;
887        }
888        else {
889            if (content instanceof List) {
890                List list = (List) content;
891                list.add( node );
892            }
893            else {
894                List list = createContentList();
895                list.add( content );
896                list.add( node );
897                content = list;
898            }
899        }
900        childAdded(node);
901    }
902
903    protected boolean removeNode(Node node) {
904        boolean answer = false;
905        if (content != null) {
906            if ( content == node ) {
907                content = null;
908                answer = true;
909            }
910            else if ( content instanceof List ) {
911                List list = (List) content;
912                answer = list.remove(node);
913            }
914        }
915        if (answer) {
916            childRemoved(node);
917        }
918        return answer;
919    }
920
921    
922    protected List contentList() {
923        if ( content instanceof List ) {
924            return (List) content;
925        }
926        else {
927            List list = createContentList();
928            if ( content != null ) {
929                list.add( content );
930            }
931            content = list;
932            return list;
933        }
934    }
935
936    protected List attributeList() {
937        if ( attributes instanceof List ) {
938            return (List) attributes;
939        }
940        else if ( attributes != null ) {
941            List list = createAttributeList();
942            list.add( attributes );
943            attributes = list;
944            return list;
945        }
946        else {
947            List list = createAttributeList();
948            attributes = list;
949            return list;
950        }
951    }
952    
953    protected List attributeList(int size) {
954        if ( attributes instanceof List ) {
955            return (List) attributes;
956        }
957        else if ( attributes != null ) {
958            List list = createAttributeList(size);
959            list.add( attributes );
960            attributes = list;
961            return list;
962        }
963        else {
964            List list = createAttributeList(size);
965            attributes = list;
966            return list;
967        }
968    }
969    
970    protected void setAttributeList(List attributes) {
971        this.attributes = attributes;
972    }    
973    
974    protected DocumentFactory getDocumentFactory() {
975        DocumentFactory factory = qname.getDocumentFactory();
976        return ( factory != null ) ? factory : DOCUMENT_FACTORY;
977    }
978    
979}
980
981
982
983
984/*
985 * Redistribution and use of this software and associated documentation
986 * ("Software"), with or without modification, are permitted provided
987 * that the following conditions are met:
988 *
989 * 1. Redistributions of source code must retain copyright
990 *    statements and notices.  Redistributions must also contain a
991 *    copy of this document.
992 *
993 * 2. Redistributions in binary form must reproduce the
994 *    above copyright notice, this list of conditions and the
995 *    following disclaimer in the documentation and/or other
996 *    materials provided with the distribution.
997 *
998 * 3. The name "DOM4J" must not be used to endorse or promote
999 *    products derived from this Software without prior written
1000 *    permission of MetaStuff, Ltd.  For written permission,
1001 *    please contact dom4j-info@metastuff.com.
1002 *
1003 * 4. Products derived from this Software may not be called "DOM4J"
1004 *    nor may "DOM4J" appear in their names without prior written
1005 *    permission of MetaStuff, Ltd. DOM4J is a registered
1006 *    trademark of MetaStuff, Ltd.
1007 *
1008 * 5. Due credit should be given to the DOM4J Project
1009 *    (http://dom4j.org/).
1010 *
1011 * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
1012 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
1013 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
1014 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
1015 * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
1016 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1017 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1018 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1019 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1020 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1021 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1022 * OF THE POSSIBILITY OF SUCH DAMAGE.
1023 *
1024 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
1025 *
1026 * $Id: DefaultElement.java,v 1.46 2002/02/01 13:04:32 jstrachan Exp $
1027 */