1 /***
2 * Copyright 2003-2004 Fabrizio Giustina.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.apache.maven.xhtml;
17
18 import java.io.File;
19 import java.io.IOException;
20
21 import org.apache.tools.ant.Project;
22 import org.dom4j.Element;
23 import org.dom4j.io.XMLWriter;
24 import org.dom4j.tree.DefaultElement;
25 import org.xml.sax.EntityResolver;
26 import org.xml.sax.ErrorHandler;
27 import org.xml.sax.InputSource;
28 import org.xml.sax.SAXException;
29 import org.xml.sax.SAXParseException;
30
31 /***
32 * ValidatorHandler.
33 * @author fgiust
34 * @version $Revision: 1.4 $ ($Author: fgiust $)
35 */
36 class ValidatorHandler implements ErrorHandler, EntityResolver
37 {
38
39 /***
40 * number of errors found in the current file.
41 */
42 private int errorsFound;
43
44 /***
45 * out.
46 */
47 private XMLWriter out;
48
49 /***
50 * real EntityResolver for DTDs
51 */
52 private EntityResolver chainedEntityResolver;
53
54 /***
55 * @return Returns the chainedEntityResolver.
56 */
57 public EntityResolver getChainedEntityResolver()
58 {
59 return this.chainedEntityResolver;
60 }
61
62 /***
63 * @param chainedEntityResolver The chainedEntityResolver to set.
64 */
65 public void setChainedEntityResolver(EntityResolver chainedEntityResolver)
66 {
67 this.chainedEntityResolver = chainedEntityResolver;
68 }
69
70 /***
71 * set XMLWriter for output.
72 * @param writer XMLWriter
73 */
74 public void setOut(XMLWriter writer)
75 {
76 this.out = writer;
77 }
78
79 /***
80 * init the validation handler: set up current file and reset errors number.
81 * @param file File currently validated
82 */
83 public void init(File file)
84 {
85 this.errorsFound = 0;
86 }
87
88 /***
89 * how many errors happened during last parsing?
90 * @return int number of errors
91 */
92 public int getErrors()
93 {
94 return this.errorsFound;
95 }
96
97 /***
98 * an error occurred: increment errors count and log exception message.
99 * @param exception SAXParseException
100 */
101 public void error(SAXParseException exception)
102 {
103 this.errorsFound++;
104 doLog(exception, Project.MSG_ERR);
105 }
106
107 /***
108 * a fatal error occurred: redirect to error().
109 * @param exception SAXParseException
110 */
111 public final void fatalError(SAXParseException exception)
112 {
113 error(exception);
114 }
115
116 /***
117 * a warning occurred: redirect to error().
118 * @param exception SAXParseException
119 */
120 public final void warning(SAXParseException exception)
121 {
122 error(exception);
123 }
124
125 /***
126 * log event to output.
127 * @param e SAXParseException
128 * @param logLevel int
129 */
130 private void doLog(SAXParseException e, int logLevel)
131 {
132 Element error = new DefaultElement("error");
133 error.addAttribute("line", "" + e.getLineNumber());
134 error.addAttribute("col", "" + e.getColumnNumber());
135 error.addAttribute("position", e.getLineNumber() + ":" + e.getColumnNumber());
136 error.addAttribute("level", "" + logLevel);
137
138 String message = e.getMessage();
139
140 int endCdata;
141 while (message != null && (endCdata = message.indexOf("]]>")) > -1)
142 {
143 message = message.substring(0, endCdata) + "] ] >" + message.substring(endCdata + 3, message.length());
144 }
145
146 error.addCDATA(message);
147 writeToLog(error);
148 }
149
150 /***
151 * this method is not used to resolve entities, but to log dtd in files.
152 * @param publicId public ID in dtd
153 * @param systemId system ID in dtd
154 * @return always null
155 * @throws SAXException generated by chained EntityResolver
156 * @throws IOException generated by chained EntityResolver
157 */
158 public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException
159 {
160
161 if (systemId.indexOf(".dtd") != -1)
162 {
163
164 String name = publicId;
165
166 if (name != null)
167 {
168 int start = name.indexOf("-//W3C//DTD ");
169 int end = name.lastIndexOf("//EN");
170
171 if (start != -1 && end > (start + 12))
172 {
173
174 name = name.substring(start + 12, end);
175 }
176
177 }
178
179
180 Element dtd = new DefaultElement("dtd");
181 dtd.addAttribute("publicId", publicId);
182 dtd.addAttribute("systemId", systemId);
183 dtd.addAttribute("display", name);
184 writeToLog(dtd);
185 }
186
187 return chainedEntityResolver.resolveEntity(publicId, systemId);
188 }
189
190 /***
191 * write an element to the xml log file.
192 * @param element Element to write
193 */
194 private void writeToLog(Element element)
195 {
196 try
197 {
198 this.out.write(element);
199 }
200 catch (IOException e)
201 {
202
203 }
204 }
205 }