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.json.JsonHandler;
026    import nu.validator.messages.types.MessageType;
027    import nu.validator.source.SourceHandler;
028    
029    import org.xml.sax.ContentHandler;
030    import org.xml.sax.SAXException;
031    
032    public class JsonMessageEmitter extends MessageEmitter {
033    
034        private final JsonHandler handler;
035        
036        private final String callback;
037        
038        private final JsonExtractHandler extractHandler;
039    
040        private final JsonMessageTextHandler messageTextHandler;
041        
042        private boolean arrayOpen;
043        
044        /**
045         * @param handler
046         */
047        public JsonMessageEmitter(final JsonHandler handler, final String callback) {
048            this.handler = handler;
049            this.callback = callback;
050            this.extractHandler = new JsonExtractHandler(handler);
051            this.messageTextHandler = new JsonMessageTextHandler(handler);
052        }
053    
054        @Override
055        public void endMessage() throws SAXException {
056            handler.endObject();
057        }
058    
059        @Override
060        public void startMessage(MessageType type, String systemId,
061                int oneBasedFirstLine, int oneBasedFirstColumn,
062                int oneBasedLastLine, int oneBasedLastColumn, boolean exact)
063                throws SAXException {
064            assert arrayOpen;
065            handler.startObject();
066            handler.key("type");
067            handler.string(type.getSuperType());
068            if (systemId != null) {
069                handler.key("url");
070                handler.string(systemId);
071            }
072            if (oneBasedLastLine != -1) {
073                handler.key("lastLine");
074                handler.number(oneBasedLastLine);
075                if (oneBasedFirstLine != oneBasedLastLine) {
076                    handler.key("firstLine");
077                    handler.number(oneBasedFirstLine);                
078                }
079                if (oneBasedLastColumn != -1) {
080                    handler.key("lastColumn");
081                    handler.number(oneBasedLastColumn);                                
082                    if (oneBasedFirstColumn != oneBasedLastColumn) {
083                        handler.key("firstColumn");
084                        handler.number(oneBasedFirstColumn);                
085                    }        
086                }        
087            }
088            String subType = type.getSubType();
089            if (subType != null) {
090                handler.key("subType");
091                handler.string(subType);
092            }
093        }
094    
095        /**
096         * @see nu.validator.messages.MessageEmitter#endFullSource()
097         */
098        @Override
099        public void endFullSource() throws SAXException {
100        }
101    
102        /**
103         * @see nu.validator.messages.MessageEmitter#endMessages()
104         */
105        @Override
106        public void endMessages() throws SAXException {
107            maybeCloseArray();
108            handler.endObject();
109            handler.endDocument();
110        }
111    
112        /**
113         * @throws SAXException
114         */
115        private void maybeCloseArray() throws SAXException {
116            if (arrayOpen) {
117                handler.endArray();
118                arrayOpen = false;
119            }
120        }
121    
122        /**
123         * @see nu.validator.messages.MessageEmitter#endSource()
124         */
125        @Override
126        public void endSource() throws SAXException {
127            handler.key("hiliteStart");
128            handler.number(extractHandler.getHiliteStart());
129            handler.key("hiliteLength");
130            handler.number(extractHandler.getHiliteLength());
131        }
132    
133        /**
134         * @see nu.validator.messages.MessageEmitter#endText()
135         */
136        @Override
137        public void endText() throws SAXException {
138            handler.endString();
139        }
140    
141        /**
142         * @see nu.validator.messages.MessageEmitter#startFullSource()
143         */
144        @Override
145        public SourceHandler startFullSource() throws SAXException {
146            maybeCloseArray();
147            handler.key("source");
148            return new JsonSourceHandler(handler);
149        }
150    
151        /**
152         * @see nu.validator.messages.MessageEmitter#startMessages(java.lang.String)
153         */
154        @Override
155        public void startMessages(String documentUri, boolean willShowSource) throws SAXException {
156            handler.startDocument(callback);
157            handler.startObject();
158            if (documentUri != null) {
159                handler.key("url");
160                handler.string(documentUri);
161            }
162            handler.key("messages");
163            handler.startArray();
164            arrayOpen = true;
165        }
166    
167        /**
168         * @see nu.validator.messages.MessageEmitter#startSource()
169         */
170        @Override
171        public SourceHandler startSource() throws SAXException {
172            handler.key("extract");
173            return extractHandler;
174        }
175    
176        /**
177         * @see nu.validator.messages.MessageEmitter#startText()
178         */
179        @Override
180        public MessageTextHandler startText() throws SAXException {
181            handler.key("message");
182            handler.startString();
183            return messageTextHandler;
184        }
185    
186    }