1 package com.puppycrawl.tools.checkstyle; 20 21 import java.io.BufferedInputStream ; 22 import java.io.FileInputStream ; 23 import java.io.FileNotFoundException ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.net.MalformedURLException ; 27 import java.net.URL ; 28 import java.util.ArrayList ; 29 import java.util.HashMap ; 30 import java.util.Iterator ; 31 import java.util.List ; 32 import java.util.Map ; 33 import java.util.Stack ; 34 import javax.xml.parsers.ParserConfigurationException ; 35 36 import com.puppycrawl.tools.checkstyle.api.AbstractLoader; 37 import com.puppycrawl.tools.checkstyle.api.CheckstyleException; 38 import com.puppycrawl.tools.checkstyle.api.Configuration; 39 import com.puppycrawl.tools.checkstyle.api.SeverityLevel; 40 41 import org.xml.sax.Attributes ; 42 import org.xml.sax.InputSource ; 43 import org.xml.sax.SAXException ; 44 import org.xml.sax.SAXParseException ; 45 46 52 public final class ConfigurationLoader 53 { 54 55 private static final String DTD_PUBLIC_ID_1_0 = 56 "-//Puppy Crawl//DTD Check Configuration 1.0//EN"; 57 58 59 private static final String DTD_RESOURCE_NAME_1_0 = 60 "com/puppycrawl/tools/checkstyle/configuration_1_0.dtd"; 61 62 63 private static final String DTD_PUBLIC_ID_1_1 = 64 "-//Puppy Crawl//DTD Check Configuration 1.1//EN"; 65 66 67 private static final String DTD_RESOURCE_NAME_1_1 = 68 "com/puppycrawl/tools/checkstyle/configuration_1_1.dtd"; 69 70 71 private static final String DTD_PUBLIC_ID_1_2 = 72 "-//Puppy Crawl//DTD Check Configuration 1.2//EN"; 73 74 75 private static final String DTD_RESOURCE_NAME_1_2 = 76 "com/puppycrawl/tools/checkstyle/configuration_1_2.dtd"; 77 78 79 private static final int TWO_KB = 2048; 80 81 85 private final class InternalLoader 86 extends AbstractLoader 87 { 88 89 private static final String MODULE = "module"; 90 91 private static final String NAME = "name"; 92 93 private static final String PROPERTY = "property"; 94 95 private static final String VALUE = "value"; 96 97 private static final String DEFAULT = "default"; 98 99 private static final String SEVERITY = "severity"; 100 101 106 private InternalLoader() 107 throws SAXException , ParserConfigurationException 108 { 109 super(createIdToResourceNameMap()); 111 } 112 113 114 public void startElement(String aNamespaceURI, 115 String aLocalName, 116 String aQName, 117 Attributes aAtts) 118 throws SAXException 119 { 120 if (aQName.equals(MODULE)) { 122 final String name = aAtts.getValue(NAME); 124 final DefaultConfiguration conf = 125 new DefaultConfiguration(name); 126 127 if (mConfiguration == null) { 128 mConfiguration = conf; 129 } 130 131 if (!mConfigStack.isEmpty()) { 133 final DefaultConfiguration top = 134 (DefaultConfiguration) mConfigStack.peek(); 135 top.addChild(conf); 136 } 137 138 mConfigStack.push(conf); 139 } 140 else if (aQName.equals(PROPERTY)) { 141 final String name = aAtts.getValue(NAME); 143 final String value; 144 try { 145 value = replaceProperties(aAtts.getValue(VALUE), 146 mOverridePropsResolver, aAtts.getValue(DEFAULT)); 147 } 148 catch (final CheckstyleException ex) { 149 throw new SAXException (ex.getMessage()); 150 } 151 152 final DefaultConfiguration top = 154 (DefaultConfiguration) mConfigStack.peek(); 155 top.addAttribute(name, value); 156 } 157 } 158 159 160 public void endElement(String aNamespaceURI, 161 String aLocalName, 162 String aQName) 163 throws SAXException 164 { 165 if (aQName.equals(MODULE)) { 166 167 final Configuration recentModule = 168 (Configuration) mConfigStack.pop(); 169 170 SeverityLevel level = null; 173 try { 174 final String severity = recentModule.getAttribute(SEVERITY); 175 level = SeverityLevel.getInstance(severity); 176 } 177 catch (final CheckstyleException e) { 178 ; 180 } 181 182 final boolean omitModule = mOmitIgnoredModules 185 && SeverityLevel.IGNORE.equals(level); 186 187 if (omitModule && !mConfigStack.isEmpty()) { 188 final DefaultConfiguration parentModule = 189 (DefaultConfiguration) mConfigStack.peek(); 190 parentModule.removeChild(recentModule); 191 } 192 } 193 } 194 195 } 196 197 198 private InternalLoader mSaxHandler; 199 200 201 private final PropertyResolver mOverridePropsResolver; 202 203 private final Stack mConfigStack = new Stack (); 204 205 private Configuration mConfiguration; 206 207 208 private boolean mOmitIgnoredModules; 209 210 214 private static Map createIdToResourceNameMap() 215 { 216 final Map map = new HashMap (); 217 map.put(DTD_PUBLIC_ID_1_0, DTD_RESOURCE_NAME_1_0); 218 map.put(DTD_PUBLIC_ID_1_1, DTD_RESOURCE_NAME_1_1); 219 map.put(DTD_PUBLIC_ID_1_2, DTD_RESOURCE_NAME_1_2); 220 return map; 221 } 222 223 231 private ConfigurationLoader(final PropertyResolver aOverrideProps, 232 final boolean aOmitIgnoredModules) 233 throws ParserConfigurationException , SAXException 234 { 235 mSaxHandler = new InternalLoader(); 236 mOverridePropsResolver = aOverrideProps; 237 mOmitIgnoredModules = aOmitIgnoredModules; 238 } 239 240 249 private void parseInputStream(InputStream aStream) 250 throws IOException , SAXException 251 { 252 final InputStream configStream = 253 new BufferedInputStream (aStream, TWO_KB); 254 final InputSource inputSource = new InputSource (configStream); 255 mSaxHandler.parseInputSource(inputSource); 256 } 257 258 265 public static Configuration loadConfiguration(String aConfig, 266 PropertyResolver aOverridePropsResolver) throws CheckstyleException 267 { 268 return loadConfiguration(aConfig, aOverridePropsResolver, false); 269 } 270 271 281 public static Configuration loadConfiguration(String aConfig, 282 PropertyResolver aOverridePropsResolver, boolean aOmitIgnoredModules) 283 throws CheckstyleException 284 { 285 InputStream bufferedStream = null; 286 try { 287 InputStream configStream; 289 try { 290 final URL url = new URL (aConfig); 291 configStream = url.openStream(); 292 } 293 catch (final MalformedURLException ex) { 294 configStream = new FileInputStream (aConfig); 295 } 296 bufferedStream = new BufferedInputStream (configStream); 297 298 return loadConfiguration(bufferedStream, aOverridePropsResolver, 299 aOmitIgnoredModules); 300 } 301 catch (final FileNotFoundException e) { 302 throw new CheckstyleException("unable to find " + aConfig, e); 303 } 304 catch (final IOException e) { 305 throw new CheckstyleException("unable to read " + aConfig, e); 306 } 307 catch (final CheckstyleException e) { 308 throw new CheckstyleException("unable to read " + aConfig + " - " 310 + e.getMessage(), e); 311 } 312 finally { 313 if (bufferedStream != null) { 314 try { 315 bufferedStream.close(); 316 } 317 catch (final IOException e) { 318 ; 320 } 321 } 322 } 323 } 324 325 336 public static Configuration loadConfiguration(InputStream aConfigStream, 337 PropertyResolver aOverridePropsResolver, boolean aOmitIgnoredModules) 338 throws CheckstyleException 339 { 340 try { 341 final ConfigurationLoader loader = 342 new ConfigurationLoader(aOverridePropsResolver, 343 aOmitIgnoredModules); 344 loader.parseInputStream(aConfigStream); 345 return loader.getConfiguration(); 346 } 347 catch (final ParserConfigurationException e) { 348 throw new CheckstyleException( 349 "unable to parse configuration stream", e); 350 } 351 catch (final SAXParseException e) { 352 throw new CheckstyleException("unable to parse configuration stream" 353 + " - " + e.getMessage() + ":" + e.getLineNumber() 354 + ":" + e.getColumnNumber(), e); 355 } 356 catch (final SAXException e) { 357 throw new CheckstyleException("unable to parse configuration stream" 358 + " - " + e.getMessage(), e); 359 } 360 catch (final IOException e) { 361 throw new CheckstyleException("unable to read from stream", e); 362 } 363 } 364 365 369 private Configuration getConfiguration() 370 { 371 return mConfiguration; 372 } 373 374 397 static String replaceProperties( 399 String aValue, PropertyResolver aProps, String aDefaultValue) 400 throws CheckstyleException 401 { 402 if (aValue == null) { 403 return null; 404 } 405 406 final List fragments = new ArrayList (); 407 final List propertyRefs = new ArrayList (); 408 parsePropertyString(aValue, fragments, propertyRefs); 409 410 final StringBuffer sb = new StringBuffer (); 411 final Iterator i = fragments.iterator(); 412 final Iterator j = propertyRefs.iterator(); 413 while (i.hasNext()) { 414 String fragment = (String ) i.next(); 415 if (fragment == null) { 416 final String propertyName = (String ) j.next(); 417 fragment = aProps.resolve(propertyName); 418 if (fragment == null) { 419 if (aDefaultValue != null) { 420 return aDefaultValue; 421 } 422 throw new CheckstyleException( 423 "Property ${" + propertyName + "} has not been set"); 424 } 425 } 426 sb.append(fragment); 427 } 428 429 return sb.toString(); 430 } 431 432 451 private static void parsePropertyString(String aValue, 452 List aFragments, 453 List aPropertyRefs) 454 throws CheckstyleException 455 { 456 int prev = 0; 457 int pos; 458 while ((pos = aValue.indexOf("$", prev)) >= 0) { 460 461 if (pos > 0) { 466 aFragments.add(aValue.substring(prev, pos)); 467 } 468 if (pos == (aValue.length() - 1)) { 471 aFragments.add("$"); 472 prev = pos + 1; 473 } 474 else if (aValue.charAt(pos + 1) != '{') { 475 481 if (aValue.charAt(pos + 1) == '$') { 482 aFragments.add("$"); 484 prev = pos + 2; 485 } 486 else { 487 aFragments.add(aValue.substring(pos, pos + 2)); 489 prev = pos + 2; 490 } 491 492 } 493 else { 494 final int endName = aValue.indexOf('}', pos); 496 if (endName < 0) { 497 throw new CheckstyleException("Syntax error in property: " 498 + aValue); 499 } 500 final String propertyName = aValue.substring(pos + 2, endName); 501 aFragments.add(null); 502 aPropertyRefs.add(propertyName); 503 prev = endName + 1; 504 } 505 } 506 if (prev < aValue.length()) { 509 aFragments.add(aValue.substring(prev)); 510 } 511 } 512 } 513 | Popular Tags |