001: package csdl.jblanket.app.tree;
002:
003: import java.util.ArrayList;
004: import java.util.HashMap;
005: import java.util.Iterator;
006: import java.util.List;
007: import java.util.Map;
008: import java.util.StringTokenizer;
009:
010: import javax.swing.tree.DefaultMutableTreeNode;
011: import javax.swing.tree.DefaultTreeModel;
012: import javax.swing.tree.TreePath;
013:
014: import org.xml.sax.Attributes;
015: import org.xml.sax.ContentHandler;
016: import org.xml.sax.Locator;
017: import org.xml.sax.SAXException;
018:
019: /**
020: * Handles the content of an XML file as it is encountered by the SAX parser for the exclude
021: * individual methods application.
022: * <p>
023: * NOTE: Method descriptions taken from org.xml.sax.ContentHandler.
024: *
025: * @author Joy M. Agustin
026: * @version $Id: NodeContentHandler.java,v 1.1 2004/11/07 00:32:40 timshadel Exp $
027: */
028: public class NodeContentHandler implements ContentHandler {
029:
030: /** Locates any content handler event in the XML source document */
031: private Locator locator;
032: /** Container for names spaces */
033: private Map namespaceMappings;
034:
035: /** Reference to the tree that will be displayed */
036: private DefaultTreeModel tree;
037: /** List of the DefaultMutableTreeNodes making up the current path */
038: private List pathList;
039: /** Category of methods being processed */
040: private String methodCategory;
041:
042: /** Name of the current method element being processed */
043: private String methodName;
044: /** List of parameters of the current method element being processed */
045: private List parameters;
046:
047: /**
048: * Constructs a new NodeContentHandler object.
049: *
050: * @param tree reference to the tree that will be built from the contents of an XML file.
051: * @param methodCategory the category of methods being processed.
052: */
053: public NodeContentHandler(DefaultTreeModel tree,
054: String methodCategory) {
055: super ();
056:
057: this .namespaceMappings = new HashMap();
058: this .tree = tree;
059:
060: this .pathList = new ArrayList();
061: this .methodCategory = methodCategory;
062:
063: this .parameters = new ArrayList();
064: }
065:
066: /**
067: * Processes notification of character data -- not implemented.
068: *
069: * @param chars the characters making up the data within the element.
070: * @param start the starting index of characters.
071: * @param length the number of characters in <code>chars</code>.
072: * @throws SAXException if any SAX error occurs.
073: */
074: public void characters(char[] chars, int start, int length)
075: throws SAXException {
076: }
077:
078: /**
079: * Processes notification of the end of a document -- not implemented.
080: *
081: * @throws SAXException if any SAX error occurs.
082: */
083: public void endDocument() throws SAXException {
084: }
085:
086: /**
087: * Processes notification of the end of an element.
088: *
089: * @param namespaceURI namespace URI of current element in context wrt document's complete set of
090: * namespaces.
091: * @param localName local, unprefixed name of current element.
092: * @param qName unmodified, unchanged name of current element.
093: * @throws SAXException if any SAX error occurs.
094: */
095: public void endElement(String namespaceURI, String localName,
096: String qName) throws SAXException {
097: // when leaving the 'Method' element, add method to tree if doesn't already exist
098: if (localName.equals("Method")) {
099:
100: MethodNode methodNode = new MethodNode(this .methodName,
101: this .parameters);
102: DefaultMutableTreeNode method = new DefaultMutableTreeNode(
103: methodNode);
104: // reset parameter list for next 'Method' element
105: this .parameters = new ArrayList();
106:
107: // search if current method already exists in the tree
108: TreePath path = new TreePath(this .pathList
109: .toArray(new Object[] {}));
110: DefaultMutableTreeNode parent = (DefaultMutableTreeNode) path
111: .getLastPathComponent();
112: DefaultMutableTreeNode sibling = null;
113:
114: if (this .tree.getChildCount(parent) == 0) {
115:
116: this .tree.insertNodeInto(method, parent, parent
117: .getChildCount());
118: sibling = method;
119: } else {
120:
121: int methodIndex = 0;
122: for ( /* empty */; methodIndex < this .tree
123: .getChildCount(parent); methodIndex++) {
124: sibling = (DefaultMutableTreeNode) this .tree
125: .getChild(parent, methodIndex);
126: // TODO entries into the tree are not sorted.
127: if (((MethodNode) sibling.getUserObject())
128: .toString().compareTo(
129: ((MethodNode) method
130: .getUserObject())
131: .toString()) == 0) {
132:
133: break;
134: }
135: }
136: if (!((MethodNode) sibling.getUserObject()).toString()
137: .equals(
138: ((MethodNode) method.getUserObject())
139: .toString())) {
140:
141: this .tree.insertNodeInto(method, parent,
142: methodIndex);
143: sibling = method;
144: }
145: }
146:
147: // modify the font characteristics as needed
148: if ("total.testedFile".equals(this .methodCategory)) {
149: ((MethodNode) sibling.getUserObject()).setTested();
150: } else if ("total.untestedFile".equals(this .methodCategory)) {
151: ((MethodNode) sibling.getUserObject()).setUntested();
152: } else if ("oneLineFile".equals(this .methodCategory)) {
153: ((MethodNode) sibling.getUserObject())
154: .setOneLineMethod();
155: } else if ("constructorFile".equals(this .methodCategory)) {
156: ((MethodNode) sibling.getUserObject()).setConstructor();
157: } else if ("excludedIndividualFile"
158: .equals(this .methodCategory)) {
159: ((MethodNode) sibling.getUserObject())
160: .setIndividualExclude();
161: }
162: }
163: }
164:
165: /**
166: * Processes end of the scope of a prefix-URI mapping.
167: *
168: * @param prefix the prefix that was being mapped.
169: * @throws SAXException if any SAX error occurs.
170: */
171: public void endPrefixMapping(String prefix) throws SAXException {
172:
173: for (Iterator i = this .namespaceMappings.keySet().iterator(); i
174: .hasNext();) {
175: String uri = (String) i.next();
176: String this Prefix = (String) this .namespaceMappings
177: .get(uri);
178:
179: if (prefix.equals(this Prefix)) {
180:
181: this .namespaceMappings.remove(uri);
182: break;
183: }
184: }
185: }
186:
187: /**
188: * Processes notification of ignorable whitespace in element content -- not implemented.
189: *
190: * @param chars the characters making up the data within the element.
191: * @param start the starting index of characters.
192: * @param length the number of characters in <code>chars</code>.
193:
194: * @throws SAXException if any SAX error occurs.
195: */
196: public void ignorableWhitespace(char[] chars, int start, int length)
197: throws SAXException {
198: }
199:
200: /**
201: * Processes notification of a processing instruction -- not implemented.
202: *
203: * @param target the processing instruction target.
204: * @param data the processing instruction data, or null if none was supplied.
205: * @throws SAXException if any SAX error occurs.
206: */
207: public void processingInstruction(String target, String data)
208: throws SAXException {
209: }
210:
211: /**
212: * Processes an object for locating the origin of SAX document events.
213: *
214: * @param locator an object that can return the location of any SAX document event.
215: */
216: public void setDocumentLocator(Locator locator) {
217: this .locator = locator;
218: }
219:
220: /**
221: * Processes notification of a skipped entity -- not implemented.
222: *
223: * @param name the name of the skipped entry.
224: * @throws SAXException if any SAX error occurs.
225: */
226: public void skippedEntity(String name) throws SAXException {
227: }
228:
229: /**
230: * Processes notification of the beginning of a document - not implememented.
231: *
232: * @throws SAXException if any SAX error occurs.
233: */
234: public void startDocument() throws SAXException {
235: }
236:
237: /**
238: * Processes notification of the beginning of an element.
239: *
240: * @param namespaceURI namespace URI of current element in context wrt document's complete set of
241: * namespaces.
242: * @param localName local, unprefixed name of current element.
243: * @param qName unmodified, unchanged name of current element.
244: * @param atts reference to all of the attributes within current element.
245: * @throws SAXException if any SAX error occurs.
246: */
247: public void startElement(String namespaceURI, String localName,
248: String qName, Attributes atts) throws SAXException {
249:
250: if (localName.equals("Method")) {
251:
252: this .methodName = atts.getValue("method");
253: processClassAttribute(atts.getValue("class"));
254: } else if (localName.equals("Parameter")) {
255:
256: this .parameters.add(atts.getValue("type").trim());
257: }
258: }
259:
260: /**
261: * Processes begin of the scope of a prefix-URI Namespace mapping.
262: *
263: * @param prefix the namespace prefix being declared.
264: * @param uri the namespace URI the prefix is mapped to.
265: * @throws SAXException if any SAX error occurs.
266: */
267: public void startPrefixMapping(String prefix, String uri)
268: throws SAXException {
269: this .namespaceMappings.put(uri, prefix);
270: }
271:
272: /**
273: * Processes the fully qualified name of a class into a tree.
274: *
275: * @param className the fully qualified class name.
276: */
277: private void processClassAttribute(String className) {
278: // begin building list of nodes in current path
279: this .pathList.add((DefaultMutableTreeNode) this .tree.getRoot());
280:
281: DefaultMutableTreeNode child;
282: DefaultMutableTreeNode parent = (DefaultMutableTreeNode) this .tree
283: .getRoot();
284: DefaultMutableTreeNode sibling = null;
285:
286: // find equivalent node, or create node as the last child
287: StringTokenizer tokens = new StringTokenizer(className, ".");
288: while (tokens.hasMoreTokens()) {
289:
290: String token = tokens.nextToken();
291: child = new DefaultMutableTreeNode(new Node(token));
292:
293: if (this .tree.getChildCount(parent) == 0) {
294:
295: this .tree.insertNodeInto(child, parent, parent
296: .getChildCount());
297: sibling = child;
298: } else {
299:
300: int childIndex = 0;
301: for ( /* empty */; childIndex < this .tree
302: .getChildCount(parent); childIndex++) {
303: sibling = (DefaultMutableTreeNode) this .tree
304: .getChild(parent, childIndex);
305: // TODO creation does not sort
306: if (((Node) sibling.getUserObject()).toString()
307: .compareTo(
308: ((Node) child.getUserObject())
309: .toString()) == 0) {
310:
311: break;
312: }
313: }
314: if (!((Node) sibling.getUserObject()).toString()
315: .equals(
316: ((Node) child.getUserObject())
317: .toString())) {
318:
319: this.tree.insertNodeInto(child, parent, childIndex);
320: sibling = child;
321: }
322: }
323:
324: this.pathList.add(sibling);
325: parent = sibling;
326: }
327: }
328: }
|