001    /*
002     * Copyright (c) 2007 Mozilla Foundation
003     *
004     * Permission is hereby granted, free of charge, to any person obtaining a 
005     * copy of this software and associated documentation files (the "Software"), 
006     * to deal in the Software without restriction, including without limitation 
007     * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
008     * and/or sell copies of the Software, and to permit persons to whom the 
009     * Software is furnished to do so, subject to the following conditions:
010     *
011     * The above copyright notice and this permission notice shall be included in 
012     * all copies or substantial portions of the Software.
013     *
014     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
015     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
016     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
017     * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
018     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
019     * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
020     * DEALINGS IN THE SOFTWARE.
021     */
022    
023    package nu.validator.messages;
024    
025    import nu.validator.messages.types.MessageType;
026    import nu.validator.source.SourceHandler;
027    import nu.validator.xml.AttributesImpl;
028    import nu.validator.xml.XhtmlSaxEmitter;
029    
030    import org.xml.sax.ContentHandler;
031    import org.xml.sax.SAXException;
032    
033    public class XmlMessageEmitter extends MessageEmitter {
034    
035        private final AttributesImpl attrs = new AttributesImpl();
036    
037        private final ContentHandler contentHandler;
038    
039        private final XmlSaxEmitter emitter;
040    
041        private final XhtmlMessageTextHandler messageTextHandler;
042    
043        private final XmlExtractHandler extractHandler;
044        
045        private String openMessage;
046        
047        /**
048         * @param contentHandler
049         */
050        public XmlMessageEmitter(final ContentHandler contentHandler) {
051            this.contentHandler = contentHandler;
052            this.emitter = new XmlSaxEmitter(contentHandler);
053            this.messageTextHandler = new XhtmlMessageTextHandler(new XhtmlSaxEmitter(contentHandler));
054            this.extractHandler = new XmlExtractHandler(emitter);
055        }
056    
057        @Override
058        public void endMessage() throws SAXException {
059            assert openMessage != null;
060            emitter.endElement(openMessage);
061            openMessage = null;
062        }
063    
064        @Override
065        public void startMessage(MessageType type, String systemId,
066                int oneBasedFirstLine, int oneBasedFirstColumn,
067                int oneBasedLastLine, int oneBasedLastColumn, boolean exact)
068                throws SAXException {
069            assert openMessage == null;
070            openMessage = type.getSuperType();
071            attrs.clear();
072            if (systemId != null) {
073                attrs.addAttribute("url", systemId);
074            }
075            if (oneBasedLastLine != -1) {
076                attrs.addAttribute("last-line", Integer.toString(oneBasedLastLine));
077                if (oneBasedFirstLine != oneBasedLastLine) {
078                    attrs.addAttribute("first-line", Integer.toString(oneBasedFirstLine));                
079                }
080                if (oneBasedLastColumn != -1) {
081                    attrs.addAttribute("last-column", Integer.toString(oneBasedLastColumn));                
082                    if (oneBasedFirstColumn != oneBasedLastColumn) {
083                        attrs.addAttribute("first-column", Integer.toString(oneBasedFirstColumn));                
084                    }        
085                }        
086            }
087            String subType = type.getSubType();
088            if (subType != null) {
089                attrs.addAttribute("type", subType);
090            }
091            emitter.startElement(openMessage, attrs);
092        }
093    
094        /**
095         * @see nu.validator.messages.MessageEmitter#endFullSource()
096         */
097        @Override
098        public void endFullSource() throws SAXException {
099        }
100    
101        /**
102         * @see nu.validator.messages.MessageEmitter#endMessages()
103         */
104        @Override
105        public void endMessages() throws SAXException {
106            emitter.endElement("messages");
107            contentHandler.endPrefixMapping("");
108            contentHandler.endPrefixMapping("h");
109            contentHandler.endDocument();
110        }
111    
112        /**
113         * @see nu.validator.messages.MessageEmitter#endSource()
114         */
115        @Override
116        public void endSource() throws SAXException {
117            emitter.endElement("extract");
118        }
119    
120        /**
121         * @see nu.validator.messages.MessageEmitter#endText()
122         */
123        @Override
124        public void endText() throws SAXException {
125            emitter.endElement("message");
126        }
127    
128        /**
129         * @see nu.validator.messages.MessageEmitter#startFullSource()
130         */
131        @Override
132        public SourceHandler startFullSource() throws SAXException {
133            return new XmlSourceHandler(emitter);
134        }
135    
136        /**
137         * @see nu.validator.messages.MessageEmitter#startMessages(java.lang.String)
138         */
139        @Override
140        public void startMessages(String documentUri, boolean willShowSource) throws SAXException {
141            contentHandler.startDocument();
142            contentHandler.startPrefixMapping("", XmlSaxEmitter.NAMESPACE);
143            contentHandler.startPrefixMapping("h", XhtmlSaxEmitter.XHTML_NS);
144            attrs.clear();
145            if (documentUri != null) {
146                attrs.addAttribute("url", documentUri);
147            }
148            emitter.startElement("messages", attrs);
149            openMessage = null;
150        }
151    
152        /**
153         * @see nu.validator.messages.MessageEmitter#startSource()
154         */
155        @Override
156        public SourceHandler startSource() throws SAXException {
157            emitter.startElement("extract");
158            return extractHandler;
159        }
160    
161        /**
162         * @see nu.validator.messages.MessageEmitter#startText()
163         */
164        @Override
165        public MessageTextHandler startText() throws SAXException {
166            emitter.startElement("message");
167            return messageTextHandler;
168        }
169    
170    }