001    package org.hackystat.sensorbase.db.postgres;
002    
003    import java.util.HashMap;
004    import java.util.Map;
005    
006    import org.xml.sax.Attributes;
007    import org.xml.sax.SAXException;
008    import org.xml.sax.helpers.DefaultHandler;
009    
010    /**
011     * The {@link DefaultHandler} implementation that parses the optional property
012     * key-value pairs. The getKeyValMap() method returns a mapping of property keys
013     * to values when an xml document is parsed.
014     * @author Austen Ito
015     * 
016     */
017    public class SensorPropertiesHandler extends DefaultHandler {
018      /** True if the element values should be read. */
019      private boolean readChars = false;
020      /** The current key that is parsed. */
021      private String currentKey = "";
022      /** True if the key is being read, false if not. */
023      private boolean readingKey = false;
024      /** The mapping of property keys to values. */
025      private final Map<String, String> keyValMap = new HashMap<String, String>();
026    
027      /**
028       * Determines if the current element is the "Key" tag or "Value" tag. If the
029       * element is either or those, the values of the elements are read.
030       * @param uri the uri of the element.
031       * @param localName the local name of the element.
032       * @param qName the tag name.
033       * @param attributes the element attributes.
034       * @throws SAXException thrown if the xml document can't be parsed.
035       */
036      @Override
037      public void startElement(String uri, String localName, String qName, Attributes attributes)
038          throws SAXException {
039        if ("Key".equals(qName)) {
040          this.readingKey = true;
041          this.readChars = true;
042        }
043        else if ("Value".equals(qName)) {
044          this.readingKey = false;
045          this.readChars = true;
046        }
047      }
048    
049      /**
050       * Reads the characters of the parsed string at the specified start and end
051       * positions.
052       * @param ch the parsed xml string.
053       * @param start the start index to read from the string.
054       * @param length the amount of characters to read from the string.
055       * @throws SAXException thrown if the xml document can't be parsed.
056       */
057      @Override
058      public void characters(char[] ch, int start, int length) throws SAXException {
059        if (this.readChars) {
060          StringBuffer valueBuffer = new StringBuffer();
061          for (int i = start; i < start + length; i++) {
062            valueBuffer.append(ch[i]);
063          }
064          if (this.readingKey) {
065            this.currentKey = valueBuffer.toString();
066          }
067          else {
068            this.keyValMap.put(this.currentKey, valueBuffer.toString());
069          }
070        }
071        this.readChars = false;
072      }
073    
074      /**
075       * Returns the populated property key-value mapping.
076       * @return the property mapping.
077       */
078      public Map<String, String> getKeyValMap() {
079        return this.keyValMap;
080      }
081    }