1 package net.sf.statsvn.input;
2
3 import javax.xml.parsers.ParserConfigurationException;
4
5 import org.xml.sax.Attributes;
6 import org.xml.sax.SAXException;
7 import org.xml.sax.SAXParseException;
8 import org.xml.sax.helpers.DefaultHandler;
9
10 /**
11 * This is the SAX parser for the repositories xml file. This xml file
12 * identifies the line counts xml files for all repositories for which
13 * SVN stats have been compiled.
14 *
15 * @author Gunter Mussbacher <gunterm@site.uottawa.ca>
16 *
17 * @version $Id: SvnXmlRepositoriesFileHandler.java 351 2008-03-28 18:46:26Z benoitx $
18 */
19 public class SvnXmlRepositoriesFileHandler extends DefaultHandler {
20
21 private static final String FATAL_ERROR_MESSAGE = "Invalid StatSvn repositories file.";
22
23 private static final String REPOSITORIES = "repositories";
24
25 private static final String REPOSITORY = "repository";
26
27 private static final String UUID = "uuid";
28
29 private static final String FILE = "file";
30
31 private String lastElement = "";
32
33 private final RepositoriesBuilder repositoriesBuilder;
34
35 /**
36 * Default constructor
37 *
38 * @param repositoriesBuilder
39 * the RepositoriesBuilder to which to send back the repository information.
40 */
41 public SvnXmlRepositoriesFileHandler(final RepositoriesBuilder repositoriesBuilder) {
42 this.repositoriesBuilder = repositoriesBuilder;
43 }
44
45 /**
46 * Makes sure the last element received is appropriate.
47 *
48 * @param last
49 * the expected last element.
50 * @throws SAXException
51 * unexpected event.
52 */
53 private void checkLastElement(final String last) throws SAXException {
54 if (!lastElement.equals(last)) {
55 fatalError(FATAL_ERROR_MESSAGE);
56 }
57 }
58
59 /**
60 * Handles the end of an xml element and redirects to the appropriate end* method.
61 *
62 * @throws SAXException
63 * unexpected event.
64 */
65 public void endElement(final String uri, final String localName, final String qName) throws SAXException {
66 super.endElement(uri, localName, qName);
67 String eName = localName;
68 if ("".equals(eName)) {
69 eName = qName;
70 }
71
72 if (eName.equals(REPOSITORIES)) {
73 endRepositories();
74 } else if (eName.equals(REPOSITORY)) {
75 endRepository();
76 } else {
77 fatalError(FATAL_ERROR_MESSAGE);
78 }
79 }
80
81 /**
82 * End of repositories element.
83 *
84 * @throws SAXException
85 * unexpected event.
86 */
87 private void endRepositories() throws SAXException {
88 checkLastElement(REPOSITORIES);
89 lastElement = "";
90 }
91
92 /**
93 * End of repository element.
94 *
95 * @throws SAXException
96 * unexpected event.
97 */
98 private void endRepository() throws SAXException {
99 checkLastElement(REPOSITORY);
100 lastElement = REPOSITORIES;
101 }
102
103 /**
104 * Throws a fatal error with the specified message.
105 *
106 * @param message
107 * the reason for the error
108 * @throws SAXException
109 * the error
110 */
111 private void fatalError(final String message) throws SAXException {
112 fatalError(new SAXParseException(message, null));
113 }
114
115 /**
116 * Handles the start of an xml element and redirects to the appropriate start* method.
117 *
118 * @throws SAXException
119 * unexpected event.
120 */
121 public void startElement(final String uri, final String localName, final String qName, final Attributes attributes) throws SAXException {
122 super.startElement(uri, localName, qName, attributes);
123
124 String eName = localName;
125 if ("".equals(eName)) {
126 eName = qName;
127 }
128
129 if (eName.equals(REPOSITORIES)) {
130 startRepositories();
131 } else if (eName.equals(REPOSITORY)) {
132 startRepository(attributes);
133 } else {
134 fatalError(FATAL_ERROR_MESSAGE);
135 }
136 }
137
138 /**
139 * Handles the start of the document. Initializes the repository builder.
140 *
141 * @throws SAXException
142 * unable to build the root.
143 */
144 private void startRepositories() throws SAXException {
145 checkLastElement("");
146 lastElement = REPOSITORIES;
147 try {
148 repositoriesBuilder.buildRoot();
149 } catch (final ParserConfigurationException e) {
150 fatalError(FATAL_ERROR_MESSAGE);
151 }
152 }
153
154 /**
155 * Handles start of a repository. Initializes repositories builder for use with repository.
156 *
157 * @param attributes
158 * element's xml attributes.
159 * @throws SAXException
160 * missing some data.
161 */
162 private void startRepository(final Attributes attributes) throws SAXException {
163 checkLastElement(REPOSITORIES);
164 lastElement = REPOSITORY;
165 if (attributes != null && attributes.getValue(UUID) != null && attributes.getValue(FILE) != null) {
166 final String uuid = attributes.getValue(UUID);
167 final String file = attributes.getValue(FILE);
168 repositoriesBuilder.buildRepository(uuid, file);
169 } else {
170 fatalError(FATAL_ERROR_MESSAGE);
171 }
172 }
173
174 }