Frames No Frames

  %method %block %branch %line
net.jaekl.qd.xml.ParseResult
89%(8/9)
81%(38/47)
74%(25/34)
91%(60/66)

hit count method name method modifiers method signature
1 <clinit> [static] void <clinit>()
45 <init> [public] void <init>(java.lang.String,java.lang.String[],java.lang.Object[][])
195 characters [public] void characters(char[],int,int)
20 collectParsedChildren [protected] net.jaekl.qd.xml.ParseResult[] collectParsedChildren(java.lang.Class)
216 endElement [public] boolean endElement(java.lang.String,java.lang.String,java.lang.String)
1 getTagName [public] java.lang.String getTagName()
0 haveSeenMyTag [public] boolean haveSeenMyTag()
255 startElement [public] net.jaekl.qd.xml.ParseResult startElement(java.lang.String,java.lang.String,java.lang.String,org.xml.sax.Attributes)
31 validate [public] void validate()

 1  
 // Copyright (C) 2004, 2014 Christian Jaekl
 2  
 
 3  
 // Abstract class representing the result of parsing an XML Element.
 4  
 // A class derived from this one will know how to parse a subtree inside an XML file, and 
 5  
 // will contain the result of that parse within itself when the parse has completed.
 6  
 //
 7  
 // Note that this code will need to be augmented and fixed if XML namespace support is desired.
 8  
 
 9  
 package net.jaekl.qd.xml;
 10  
 
 11  
 import java.util.ArrayList;
 12  
 import java.util.HashMap;
 13  
 import java.util.HashSet;
 14  
 import java.util.Iterator;
 15  
 import java.util.Stack;
 16  
 
 17  
 import org.xml.sax.Attributes;
 18  
 
 19  Block: 1/1 
 public abstract class ParseResult
 20  
 {
 21  
 	Stack<String> m_current;									// Name of the element that we're currently inside
 22  
 	StringBuilder m_chars;										// character content of m_current.peek()
 23  
 	ArrayList<ParseResult> m_childParsers;						// Set of all child parsers
 24  
 	boolean m_haveSeenMyTag;									// Have I encountered my own (root) tag yet?
 25  
 
 26  
 	String m_tagName;											// Name of the (root) element tag that I'm parsing
 27  
 	HashSet<String> m_internal;									// Tags that we will store as members of this class instance
 28  
 	HashMap<String,Class<? extends ParseResult>> m_external;	// Tags that we will store as child ParseResult-derived objects
 29  
 
 30  
 	@SuppressWarnings("unchecked")
 31  
 	public ParseResult(String tagName, String[] internalMemberTags, Object[][] externalParserTags)
 32  Block: 1/1 
 	{
 33  
 		m_current = new Stack<String>();
 34  
 		m_chars = new StringBuilder();
 35  
 		m_childParsers = new ArrayList<ParseResult>();
 36  
 		m_haveSeenMyTag = false;
 37  
 		
 38  
 		m_tagName = tagName;
 39  
 		m_internal = new HashSet<String>();
 40  
 		m_external = new HashMap<String, Class<? extends ParseResult>>();
 41  
 
 42  
 		for (String internalTag : internalMemberTags) {
 43  Block: 1/1 Branch: 1/1 
 			m_internal.add(internalTag);
 44  
 		}
 45  
 
 46  Block: 1/1 Branch: 1/1 
 		for (int idx = 0; idx < externalParserTags.length; ++idx) {
 47  Block: 1/1 Branch: 1/1 
 			String externalTag = (String)externalParserTags[idx][0];
 48  
 			Class<? extends ParseResult>  parserClass = (Class<? extends ParseResult>)externalParserTags[idx][1];
 49  
 			m_external.put(externalTag, parserClass);
 50  
 		}
 51  Block: 1/1 Branch: 1/1 
 	}
 52  
 
 53  
 	public abstract void endContents(String uri, String localName, String qName, String chars) throws XmlParseException;
 54  
 	public abstract void endExternal(String uri, String localName, String qName) throws XmlParseException;
 55  
 	
 56  Block: 1/1 
 	public String getTagName() { return m_tagName; }
 57  Block: 0/1 
 	public boolean haveSeenMyTag() { return m_haveSeenMyTag; }
 58  
 
 59  
 	public void characters(char[] ch, int start, int length) throws XmlParseException
 60  
 	{
 61  Block: 1/1 
 		m_chars.append(ch, start, length);
 62  
 	}
 63  
 	
 64  
 	protected ParseResult[] collectParsedChildren(Class<? extends ParseResult> cls) {
 65  Block: 1/1 
 		ArrayList<ParseResult> collection = new ArrayList<ParseResult>();
 66  
 		Iterator<ParseResult> iter = m_childParsers.iterator();
 67  Block: 1/1 
 		while (iter.hasNext()) {
 68  Block: 1/1 Branch: 1/1 
 			ParseResult pr = iter.next();
 69  
 			if (pr.getClass().isAssignableFrom(cls)) {
 70  Block: 1/1 Branch: 1/1 
 				collection.add(pr);
 71  
 				iter.remove();
 72  
 			}
 73  Block: 1/1 Branch: 0/1 
 		}
 74  
 		
 75  Block: 1/1 Branch: 1/1 
 		ParseResult[] result = new ParseResult[collection.size()];
 76  
 		return collection.toArray(result);
 77  
 	}
 78  
 
 79  
 	// returns true if this ParseResult's context has ended with this endElement() call
 80  
 	public boolean endElement(String uri, String localName, String qName) throws XmlParseException
 81  
 	{
 82  Block: 1/1 
 		assert (null != localName);
 83  
 		
 84  Block: 1/1 Branch: 1/2 
 		boolean isInternal = m_internal.contains(localName);
 85  
 
 86  
 		if (! m_haveSeenMyTag) {
 87  
 			// We're in some unrecognised prologue.  Ignore it and move on.
 88  Block: 1/1 Branch: 1/1 
 			return false;
 89  
 		}
 90  
 		
 91  Block: 1/1 Branch: 1/1 
 		if (m_tagName.equals(localName)) {
 92  Block: 1/1 Branch: 1/1 
 			validate();
 93  
 			return true;
 94  
 		}
 95  
 		
 96  Block: 1/1 Branch: 1/1 
 		if (!isInternal) {
 97  
 			// Unrecognized tag.  Ignore it.
 98  Block: 1/1 Branch: 1/1 
 			return false;
 99  
 		}
 100  
 		
 101  Block: 1/1 Branch: 1/1 
 		String tag = m_current.pop();
 102  
 		if ( ! tag.equals(localName) ) {
 103  Block: 0/1 Branch: 0/1 
 			throw new MismatchedTagsException(tag, localName);
 104  
 		}
 105  
 		
 106  Block: 1/1 Branch: 1/1 
 		String chars = m_chars.toString();
 107  
 		endContents(uri, localName, qName, chars);
 108  
 		
 109  
 		return false;
 110  
 	}
 111  
 	
 112  
 	// returns either itself, or a new ParseResult-derived object, whichever should handle parsing the inside of this element
 113  
 	public ParseResult startElement(String uri, String localName, String qName, Attributes attributes) 
 114  
 			throws XmlParseException
 115  
 	{
 116  Block: 1/1 
 		assert (null != localName);
 117  
 
 118  Block: 1/1 Branch: 1/2 
 		m_chars.setLength(0);
 119  
 		
 120  
 		if (! m_haveSeenMyTag) {
 121  
 			// Have we opened our own (root) tag yet?
 122  
 			
 123  Block: 1/1 Branch: 1/1 
 			if (m_tagName.equals(localName)) {
 124  Block: 1/1 Branch: 1/1 
 				m_haveSeenMyTag = true;
 125  
 				return this;
 126  
 			}
 127  
 			else {
 128  
 				// One of two things has happened here.
 129  
 				// Either (a) we've got some sort of wrapper here, and have not yet reach our own tag, 
 130  
 				//     or (b) we're parsing XML that doesn't match expectations.
 131  
 				// In either case, we're going to ignore this tag, and scan forward looking for our own root.
 132  Block: 1/1 Branch: 1/1 
 				return this;
 133  
 			}
 134  
 		}
 135  
 
 136  Block: 1/1 Branch: 1/1 
 		if (m_internal.contains(localName)) {
 137  Block: 1/1 Branch: 1/1 
 			m_current.push(localName);
 138  
 			return this;
 139  
 		}
 140  
 
 141  Block: 1/1 Branch: 1/1 
 		Class<? extends ParseResult> parserClass = m_external.get(localName);
 142  
 		if (null != parserClass) {
 143  
 			try {
 144  Block: 1/1 Branch: 1/1 
 				ParseResult childParser = (ParseResult) parserClass.newInstance();
 145  
 				m_childParsers.add(childParser);
 146  
 				return childParser.startElement(uri, localName, qName, attributes);
 147  
 			}
 148  Block: 0/1 
 			catch (IllegalAccessException iae) {
 149  
 				throw new XmlParseException(iae);
 150  
 			}
 151  Block: 0/1 
 			catch (InstantiationException ie) {
 152  
 				throw new XmlParseException(ie);
 153  
 			}
 154  
 		}
 155  
 		
 156  
 		// Not a recognized tag.  Ignore it, rather than complaining. 
 157  Block: 1/1 Branch: 1/1 
 		return this;
 158  
 	}
 159  
 	
 160  
 	public void validate() throws XmlParseException
 161  
 	{
 162  
 		// Default implementation is a no-op.
 163  
 		// Override if you want to validate on endElement()
 164  Block: 1/1 
 	}
 165  
 }
 166  
 

Report generated 11/12/14 11:31 PM