001    /** 
002     * 
003     * Copyright 2004 Protique Ltd
004     * 
005     * Licensed under the Apache License, Version 2.0 (the "License"); 
006     * you may not use this file except in compliance with the License. 
007     * You may obtain a copy of the License at 
008     * 
009     * http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS, 
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
014     * See the License for the specific language governing permissions and 
015     * limitations under the License. 
016     * 
017     **/
018    package org.codehaus.activesoap.handler.stax;
019    
020    import javax.xml.namespace.QName;
021    import javax.xml.stream.XMLStreamException;
022    import javax.xml.stream.XMLStreamWriter;
023    import javax.xml.stream.XMLStreamReader;
024    import javax.xml.stream.XMLStreamConstants;
025    import java.util.Iterator;
026    import java.util.List;
027    import java.util.Map;
028    
029    /**
030     * @version $Revision: 1.4 $
031     */
032    public class StaxHelper {
033        /**
034         * Writes the given attributes to the stream
035         */
036        public static void writeAttributes(Map map, XMLStreamWriter out) throws XMLStreamException {
037            for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
038                Map.Entry entry = (Map.Entry) iter.next();
039                Object key = entry.getKey();
040                String value = (String) entry.getValue();
041                if (key instanceof String) {
042                    out.writeAttribute((String) key, value);
043                }
044                else if (key instanceof QName) {
045                    QName name = (QName) key;
046                    out.writeAttribute(name.getPrefix(), name.getNamespaceURI(), name.getLocalPart(), value);
047                }
048            }
049        }
050    
051        /**
052         * Writes the given element to the StAX stream if it is not null
053         */
054        public static void writeElement(QName qname, ElementContent element, AnyElementMarshaler marshaler, XMLStreamWriter out) throws XMLStreamException {
055            writeElement(qname, element, marshaler, out, false);
056    
057        }
058    
059        public static void writeElement(QName qname, ElementContent element, AnyElementMarshaler marshaler, XMLStreamWriter out, boolean repairingMode) throws XMLStreamException {
060            if (element != null) {
061                writeStartElement(qname, out, repairingMode);
062                element.writeContent(marshaler, out);
063                out.writeEndElement();
064            }
065        }
066    
067        public static void writeElementNoNamespace(QName qname, ElementContent element, AnyElementMarshaler marshaler, XMLStreamWriter out) throws XMLStreamException {
068            if (element != null) {
069                writeStartElementNoNamespace(qname, out);
070                element.writeContent(marshaler, out);
071                out.writeEndElement();
072            }
073        }
074    
075        public static void writeElementNoNamespace(QName qname, Object object, AnyElementMarshaler marshaler, XMLStreamWriter out) throws XMLStreamException {
076            if (object != null) {
077                writeStartElementNoNamespace(qname, out);
078                marshaler.writeElement(object, out);
079                out.writeEndElement();
080            }
081        }
082    
083        public static void writeElement(QName qname, Object object, AnyElementMarshaler marshaler, XMLStreamWriter out) throws XMLStreamException {
084            writeElement(qname, object, marshaler, out, false);
085    
086        }
087        public static void writeElement(QName qname, Object object, AnyElementMarshaler marshaler, XMLStreamWriter out, boolean repairingMode) throws XMLStreamException {
088            if (object != null) {
089                writeStartElement(qname, out, repairingMode);
090                marshaler.writeElement(object, out);
091                out.writeEndElement();
092            }
093        }
094    
095        public static void writeStartElementNoNamespace(QName qname, XMLStreamWriter out) throws XMLStreamException {
096            String prefix = qname.getPrefix();
097            String uri = qname.getNamespaceURI();
098            out.writeStartElement(prefix, qname.getLocalPart(), uri);
099        }
100    
101        public static void writeStartElement(QName qname, XMLStreamWriter out, boolean repairingMode) throws XMLStreamException {
102            String prefix = qname.getPrefix();
103            String uri = qname.getNamespaceURI();
104    
105            // before you ask - yes it really is this complicated to output QNames to StAX
106            // handling both repair namespace modes :)
107    
108            boolean hasPrefix = prefix != null && prefix.length() > 0;
109            boolean hasURI = uri != null && uri.length() > 0;
110    
111            if (hasPrefix) {
112                out.setPrefix(prefix, uri);
113            }
114            else if (hasURI) {
115                out.setDefaultNamespace(uri);
116            }
117            out.writeStartElement(prefix, qname.getLocalPart(), uri);
118    
119            if (hasURI && !repairingMode) {
120                if (hasPrefix) {
121                    out.writeNamespace(prefix, uri);
122                }
123                else {
124                    out.writeDefaultNamespace(uri);
125                }
126            }
127        }
128    
129    
130        /**
131         * Writes the list of any objects to the stream. The list can be null to avoid firing lazy-construction logic
132         */
133        public static void writeAnyContent(List list, AnyElementMarshaler marshaller, XMLStreamWriter out) throws XMLStreamException {
134            if (list != null) {
135                for (Iterator iter = list.iterator(); iter.hasNext();) {
136                    Object value = iter.next();
137                    marshaller.writeElement(value, out);
138                }
139            }
140        }
141    
142        /**
143         * Reads the content of the current element as a String, ignoring any embedded elements
144         */
145        public static String readTextContent(XMLStreamReader in) throws XMLStreamException {
146            StringBuffer buffer = new StringBuffer();
147    
148            boolean complete = false;
149            int elements = 0;
150            int code = in.getEventType();
151            while (!complete) {
152                switch (code) {
153                    case XMLStreamConstants.CHARACTERS:
154                        if (elements == 1) {
155                            buffer.append(in.getText());
156                        }
157                        break;
158    
159                    case XMLStreamConstants.START_ELEMENT:
160                        elements++;
161                        break;
162    
163                    case XMLStreamConstants.END_ELEMENT:
164                        if (--elements <= 0) {
165                            complete = true;
166                        }
167                        break;
168    
169                    case XMLStreamConstants.END_DOCUMENT:
170                        complete = true;
171                        break;
172                }
173                if (complete) {
174                    break;
175                }
176                if (!in.hasNext()) {
177                    complete = true;
178                }
179                else {
180                    code = in.next();
181                }
182            }
183            return buffer.toString();
184        }
185    
186    }