1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package com.puppycrawl.tools.checkstyle;
20
21 import com.puppycrawl.tools.checkstyle.api.Utils;
22
23 import com.google.common.collect.Sets;
24 import com.puppycrawl.tools.checkstyle.api.AbstractLoader;
25 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
26 import com.puppycrawl.tools.checkstyle.api.FastStack;
27 import java.io.BufferedInputStream;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.net.URL;
31 import java.util.Enumeration;
32 import java.util.Set;
33 import javax.xml.parsers.ParserConfigurationException;
34 import org.xml.sax.Attributes;
35 import org.xml.sax.InputSource;
36 import org.xml.sax.SAXException;
37
38
39
40
41
42
43 public final class PackageNamesLoader
44 extends AbstractLoader
45 {
46
47 private static final String DTD_PUBLIC_ID =
48 "-//Puppy Crawl//DTD Package Names 1.0//EN";
49
50
51 private static final String DTD_RESOURCE_NAME =
52 "com/puppycrawl/tools/checkstyle/packages_1_0.dtd";
53
54
55
56
57 private static final String CHECKSTYLE_PACKAGES =
58 "checkstyle_packages.xml";
59
60
61 private final FastStack<String> packageStack = FastStack.newInstance();
62
63
64 private final Set<String> packageNames = Sets.newLinkedHashSet();
65
66
67
68
69
70
71 private PackageNamesLoader()
72 throws ParserConfigurationException, SAXException
73 {
74 super(DTD_PUBLIC_ID, DTD_RESOURCE_NAME);
75 }
76
77
78
79
80
81
82 private Set<String> getPackageNames()
83 {
84 return packageNames;
85 }
86
87 @Override
88 public void startElement(String namespaceURI,
89 String localName,
90 String qName,
91 Attributes atts)
92 throws SAXException
93 {
94 if ("package".equals(qName)) {
95
96 final String name = atts.getValue("name");
97 if (name == null) {
98 throw new SAXException("missing package name");
99 }
100 packageStack.push(name);
101 }
102 }
103
104
105
106
107
108 private String getPackageName()
109 {
110 final StringBuffer buf = new StringBuffer();
111 for (String subPackage : packageStack) {
112 buf.append(subPackage);
113 if (!subPackage.endsWith(".")) {
114 buf.append(".");
115 }
116 }
117 return buf.toString();
118 }
119
120 @Override
121 public void endElement(String namespaceURI,
122 String localName,
123 String qName)
124 {
125 if ("package".equals(qName)) {
126
127 packageNames.add(getPackageName());
128 packageStack.pop();
129 }
130 }
131
132
133
134
135
136
137
138
139
140
141 public static Set<String> getPackageNames(ClassLoader classLoader)
142 throws CheckstyleException
143 {
144
145 Enumeration<URL> packageFiles = null;
146 try {
147 packageFiles = classLoader.getResources(CHECKSTYLE_PACKAGES);
148 }
149 catch (IOException e) {
150 throw new CheckstyleException(
151 "unable to get package file resources", e);
152 }
153
154
155
156 final PackageNamesLoader namesLoader = newPackageNamesLoader();
157
158 while ((null != packageFiles) && packageFiles.hasMoreElements()) {
159 final URL packageFile = packageFiles.nextElement();
160 InputStream stream = null;
161
162 try {
163 stream = new BufferedInputStream(packageFile.openStream());
164 final InputSource source = new InputSource(stream);
165 loadPackageNamesSource(source, "default package names",
166 namesLoader);
167 }
168 catch (IOException e) {
169 throw new CheckstyleException(
170 "unable to open " + packageFile, e);
171 }
172 finally {
173 Utils.closeQuietly(stream);
174 }
175 }
176 return namesLoader.getPackageNames();
177 }
178
179
180
181
182
183
184 private static PackageNamesLoader newPackageNamesLoader()
185 throws CheckstyleException
186 {
187 try {
188 return new PackageNamesLoader();
189 }
190 catch (final ParserConfigurationException e) {
191 throw new CheckstyleException(
192 "unable to create PackageNamesLoader ", e);
193 }
194 catch (final SAXException e) {
195 throw new CheckstyleException(
196 "unable to create PackageNamesLoader - "
197 + e.getMessage(), e);
198 }
199 }
200
201
202
203
204
205
206
207
208 private static void loadPackageNamesSource(
209 InputSource source, String sourceName,
210 PackageNamesLoader nameLoader)
211 throws CheckstyleException
212 {
213 try {
214 nameLoader.parseInputSource(source);
215 }
216 catch (final SAXException e) {
217 throw new CheckstyleException("unable to parse "
218 + sourceName + " - " + e.getMessage(), e);
219 }
220 catch (final IOException e) {
221 throw new CheckstyleException("unable to read " + sourceName, e);
222 }
223 }
224 }