View Javadoc
1 package net.sourceforge.pmd; 2 3 import net.sourceforge.pmd.util.ResourceLoader; 4 import org.xml.sax.Attributes; 5 import org.xml.sax.InputSource; 6 import org.xml.sax.SAXException; 7 import org.xml.sax.helpers.DefaultHandler; 8 9 import javax.xml.parsers.SAXParser; 10 import javax.xml.parsers.SAXParserFactory; 11 import java.io.InputStream; 12 import java.util.Enumeration; 13 import java.util.Iterator; 14 import java.util.Properties; 15 import java.util.Stack; 16 import java.util.StringTokenizer; 17 18 /*** 19 * Loads the PMD <b>project.xml</b> file and stores the contents in a Properties object. 20 * The property keys are the case-insensitive path starting below the root <project> down 21 * to the element. For example: 22 * <ul> 23 * <li>currentVersion</li> 24 * <li>organization/name</li> 25 * <li>versions/version/name</li> 26 * </ul> 27 * When an element has repeated values, e.g., developer names, one property is created and 28 * the values are separated by <b>&vs;</b>. The <i>vs</i> stands for <i>value separator</i>. 29 * For example: 30 * <ul> 31 * <li>Tom Copeland&vs;David Dixon-Peugh&vs;David Craine</li> 32 * <li>tom@infoether.com&vs;ddp@apache.org&vs;dave@infoether.com</li> 33 * </ul> 34 * When there is a collection of repeating values, an empty space will reserve the position 35 * of a missing value. This is so that the collection can be parsed on position. 36 * 37 * @author Donald A. Leckie 38 * @since September 10, 2002 39 * @version $Revision: 1.12 $, $Date: 2003/04/08 16:02:10 $ 40 */ 41 public class ProjectFile { 42 43 private static Properties PROPERTIES; 44 private static Exception PARSE_EXCEPTION; 45 private static final String VALUE_SEPARATOR = "&vs;"; 46 47 /*** 48 ***************************************************************************** 49 * 50 * @param key 51 * 52 * @return 53 */ 54 public static final String getProperty(String key) { 55 key = (key == null) ? "" : key.trim().toLowerCase(); 56 57 if (PROPERTIES == null) { 58 (new ProjectFile()).loadProperties(); 59 } 60 61 String value = PROPERTIES.getProperty(key); 62 63 return (value == null) ? "" : value; 64 } 65 66 /*** 67 ***************************************************************************** 68 * 69 * @return 70 */ 71 public static final Enumeration getPropertyKeys() { 72 return PROPERTIES.propertyNames(); 73 } 74 75 /*** 76 ***************************************************************************** 77 * 78 * @return 79 */ 80 public static final int getPropertyCount() { 81 int count = 0; 82 Enumeration keys = PROPERTIES.propertyNames(); 83 84 while (keys.hasMoreElements()) { 85 keys.nextElement(); 86 count++; 87 } 88 89 return count; 90 } 91 92 /*** 93 ***************************************************************************** 94 * 95 * @return 96 */ 97 public static final String[] toArray(String propertyValue) { 98 String[] values = new String[0]; 99 100 if (propertyValue != null) { 101 StringTokenizer parser; 102 int valueCount; 103 int index; 104 105 parser = new StringTokenizer(propertyValue, VALUE_SEPARATOR); 106 valueCount = parser.countTokens(); 107 values = new String[valueCount]; 108 index = 0; 109 110 while (parser.hasMoreTokens()) { 111 values[index] = parser.nextToken(); 112 index++; 113 } 114 } 115 116 return values; 117 } 118 119 /*** 120 ***************************************************************************** 121 * 122 * @return 123 */ 124 public static final Exception getException() { 125 return PARSE_EXCEPTION; 126 } 127 128 /*** 129 ***************************************************************************** 130 * 131 */ 132 private void loadProperties() { 133 InputStream inputStream; 134 InputSource inputSource; 135 136 PROPERTIES = new Properties(); 137 138 try { 139 inputStream = ResourceLoader.loadResourceAsStream("project.xml"); 140 inputSource = new InputSource(inputStream); 141 MainContentHandler mainContentHandler; 142 SAXParserFactory factory = SAXParserFactory.newInstance(); 143 factory.setFeature("http://xml.org/sax/features/namespace-prefixes", true); 144 factory.setFeature("http://xml.org/sax/features/namespaces", false); 145 146 SAXParser parser = factory.newSAXParser(); 147 148 mainContentHandler = new MainContentHandler(); 149 150 parser.parse(inputSource, mainContentHandler); 151 } catch (Exception exception) { 152 PARSE_EXCEPTION = exception; 153 } 154 } 155 156 /*** 157 ***************************************************************************** 158 ***************************************************************************** 159 ***************************************************************************** 160 */ 161 private class MainContentHandler extends DefaultHandler { 162 163 private StringBuffer m_buffer = new StringBuffer(100); 164 private Stack m_nameStack = new Stack(); 165 private final String PROJECT = "project"; 166 167 /*** 168 ************************************************************************* 169 */ 170 private MainContentHandler() { 171 super(); 172 } 173 174 /*** 175 ************************************************************************* 176 * 177 * @param namespace 178 * @param localName 179 * @param qualifiedName 180 * @param attributes 181 * 182 * @throws SAXException 183 */ 184 public void startElement(String namespace, String localName, String qualifiedName, Attributes attributes) throws SAXException { 185 if (qualifiedName.equalsIgnoreCase(PROJECT) == false) { 186 m_nameStack.push(qualifiedName); 187 } 188 } 189 190 /*** 191 ************************************************************************* 192 * 193 * @param chars 194 * @param beginIndex 195 * @param length 196 * 197 * @throws PMDException 198 */ 199 public void characters(char[] chars, int beginIndex, int length) { 200 m_buffer.append(chars, beginIndex, length); 201 } 202 203 /*** 204 ************************************************************************* 205 * 206 * @param namespace 207 * @param localName 208 * @param qualifiedName 209 * 210 * @throws SAXException 211 */ 212 public void endElement(String namespace, String localName, String qualifiedName) throws SAXException { 213 String value = m_buffer.toString().replace('\n', ' ').trim(); 214 String key = buildKey(); 215 String existingValue = PROPERTIES.getProperty(key); 216 217 if (existingValue != null) { 218 value = existingValue + VALUE_SEPARATOR + value; 219 } 220 221 PROPERTIES.setProperty(key, value); 222 m_buffer.setLength(0); 223 m_nameStack.pop(); 224 } 225 226 /*** 227 ************************************************************************* 228 * 229 * @return 230 */ 231 private String buildKey() { 232 StringBuffer name = new StringBuffer(100); 233 Iterator iterator = m_nameStack.iterator(); 234 235 while (iterator.hasNext()) { 236 name.append(iterator.next()); 237 name.append('/'); 238 } 239 240 if (name.length() > 0) { 241 name.setLength(name.length() - 1); 242 } 243 244 return name.toString().toLowerCase(); 245 } 246 } 247 }

This page was automatically generated by Maven