2
* The Apache Software License, Version 1.1
5
* Copyright (c) 1999,2000 The Apache Software Foundation. All rights
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
12
* 1. Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in
17
* the documentation and/or other materials provided with the
20
* 3. The end-user documentation included with the redistribution,
21
* if any, must include the following acknowledgment:
22
* "This product includes software developed by the
23
* Apache Software Foundation (http://www.apache.org/)."
24
* Alternately, this acknowledgment may appear in the software itself,
25
* if and wherever such third-party acknowledgments normally appear.
27
* 4. The names "Xerces" and "Apache Software Foundation" must
28
* not be used to endorse or promote products derived from this
29
* software without prior written permission. For written
30
* permission, please contact apache@apache.org.
32
* 5. Products derived from this software may not be called "Apache",
33
* nor may "Apache" appear in their name, without prior written
34
* permission of the Apache Software Foundation.
36
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48
* ====================================================================
50
* This software consists of voluntary contributions made by many
51
* individuals on behalf of the Apache Software Foundation and was
52
* originally based on software copyright (c) 1999, International
53
* Business Machines, Inc., http://www.apache.org. For more
54
* information on the Apache Software Foundation, please see
55
* <http://www.apache.org/>.
57
package dom.traversal;
60
import java.awt.event.*;
61
import java.util.Hashtable;
62
import java.util.Enumeration;
64
import javax.swing.tree.*;
65
import javax.swing.event.*;
66
import org.apache.xerces.parsers.*;
68
import org.w3c.dom.traversal.*;
69
import org.xml.sax.ErrorHandler;
70
import org.xml.sax.SAXException;
71
import org.xml.sax.SAXParseException;
73
import ui.DOMTreeFull;
75
/** This class shows a DOM Document in a JTree, and presents controls
76
* which allow the user to create and view the progress of a NodeIterator
79
public class IteratorView
81
implements ActionListener {
84
TreeNode lastSelected;
86
JTextArea messageText;
87
JScrollPane messageScroll;
89
NodeIterator iterator;
90
NameNodeFilter nameNodeFilter;
100
JTextField nameFilter;
101
String whatArray[] = new String [] {
109
"PROCESSING_INSTRUCTION",
118
Hashtable treeNodeMap = new Hashtable();
122
public static void main (String args[]) {
124
if (args.length > 0) {
125
String filename = args[0];
127
IteratorView frame = new IteratorView(filename) ;
128
frame.addWindowListener(new java.awt.event.WindowAdapter() {
129
public void windowClosing(java.awt.event.WindowEvent e) {
133
frame.setSize(640, 480);
134
frame.setVisible(true);
135
} catch (Exception e) {
136
e.printStackTrace(System.err);
142
public IteratorView (String filename) {
143
super("IteratorView: "+filename);
145
parser = new DOMParser();
146
parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", true);
147
parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
148
Errors errors = new Errors();
149
parser.setErrorHandler(errors);
150
parser.parse(filename);
151
document = parser.getDocument();
153
if (!document.isSupported("Traversal", "2.0")) {
154
// This cannot happen with ou DOMParser...
155
throw new RuntimeException("This DOM Document does not support Traversal");
159
jtree = new DOMTreeFull((Node)document);
160
jtree.getSelectionModel().setSelectionMode
161
(TreeSelectionModel.SINGLE_TREE_SELECTION);
162
jtree.setRootVisible(false);
164
// Listen for when the selection changes, call nodeSelected(node)
165
jtree.addTreeSelectionListener(
166
new TreeSelectionListener() {
167
public void valueChanged(TreeSelectionEvent e) {
168
TreePath path = (TreePath)e.getPath();
169
TreeNode treeNode = (TreeNode)path.getLastPathComponent();
170
if(jtree.getSelectionModel().isPathSelected(path))
171
nodeSelected(treeNode);
183
JPanel iteratePanel = new JPanel();
184
iteratePanel.setBorder(BorderFactory.createCompoundBorder(
185
BorderFactory.createTitledBorder("Iterate"),
186
BorderFactory.createEmptyBorder(4, 4, 4, 4)
189
prevButton = new JButton("Previous");
190
iteratePanel.add(prevButton);
191
prevButton.addActionListener(this);
193
nextButton = new JButton("Next");
194
iteratePanel.add(nextButton);
195
nextButton.addActionListener(this);
198
JPanel domPanel = new JPanel();
199
domPanel.setLayout(new BorderLayout());
200
domPanel.setBorder(BorderFactory.createCompoundBorder(
201
BorderFactory.createTitledBorder("Selected Node"),
202
BorderFactory.createEmptyBorder(4, 4, 4, 4)
205
removeButton = new JButton("Remove Selected Node");
206
domPanel.add(removeButton, BorderLayout.NORTH);
207
removeButton.addActionListener(this);
209
addButton = new JButton("Add Text Node");
210
addText = new JTextField(10);
211
domPanel.add(addButton, BorderLayout.CENTER);
212
domPanel.add(addText, BorderLayout.SOUTH);
213
addButton.addActionListener(this);
216
JPanel settingsPanel = new JPanel();
217
settingsPanel.setLayout(new BorderLayout());
218
settingsPanel.setBorder(BorderFactory.createCompoundBorder(
219
BorderFactory.createTitledBorder("Iterator Settings"),
220
BorderFactory.createEmptyBorder(4, 4, 4, 4)
222
JPanel iteratorPanel = new JPanel();
223
newIterator = new JButton("createNodeIterator");
224
expandERs = new JCheckBox("expandEntityReferences");
225
iteratorPanel.add(newIterator);
226
expandERs.setSelected(true);
227
iteratorPanel.add(expandERs);
228
settingsPanel.add(iteratorPanel, BorderLayout.NORTH);
229
newIterator.addActionListener(this);
231
JPanel whatPanel = new JPanel();
232
whatPanel.setBorder(BorderFactory.createCompoundBorder(
233
BorderFactory.createTitledBorder("whatToShow"),
234
BorderFactory.createEmptyBorder(4, 4, 4, 4)
236
whatToShow = new JList(DOMTreeFull.whatArray);
237
JScrollPane whatScroll =
238
new JScrollPane(whatToShow) {
239
public Dimension getPreferredSize(){
240
return new Dimension(200, 75 );
244
whatPanel.add(whatScroll);
247
JPanel filterPanel = new JPanel();
248
filterPanel.setBorder(BorderFactory.createCompoundBorder(
249
BorderFactory.createTitledBorder("NodeNameFilter"),
250
BorderFactory.createEmptyBorder(4, 4, 4, 4)
252
filterPanel.setLayout(new BorderLayout());
253
match = new JCheckBox("match/ignore node name", true);
254
nameFilter = new JTextField(10);
255
filterPanel.add(match, BorderLayout.NORTH);
256
filterPanel.add(nameFilter, BorderLayout.SOUTH);
258
settingsPanel.add(whatPanel, BorderLayout.WEST);
259
settingsPanel.add(filterPanel, BorderLayout.EAST);
262
// Listen for when the selection changes, call nodeSelected(node)
263
whatToShow.addListSelectionListener(
264
new ListSelectionListener() {
265
public void valueChanged(ListSelectionEvent e) {
266
// do nothing on selection...
272
JPanel controlsPanel = new JPanel(new BorderLayout());
273
JPanel buttonsPanel = new JPanel(new BorderLayout());
274
buttonsPanel.add(iteratePanel, BorderLayout.NORTH);
275
buttonsPanel.add(domPanel, BorderLayout.SOUTH);
276
controlsPanel.add(buttonsPanel, BorderLayout.WEST);
277
controlsPanel.add(settingsPanel, BorderLayout.CENTER);
279
controlsPanel.setBorder(BorderFactory.createCompoundBorder(
280
BorderFactory.createTitledBorder("Controls"),
281
BorderFactory.createEmptyBorder(4, 4, 4, 4)
286
JPanel treePanel = new JPanel(new BorderLayout());
288
JScrollPane treeScroll = new JScrollPane(jtree) ;
289
treeScroll.setBorder(BorderFactory.createCompoundBorder(
290
BorderFactory.createTitledBorder("Tree View"),
291
BorderFactory.createEmptyBorder(4, 4, 4, 4)
294
// message text UI setup
295
messageText = new JTextArea(3,5);
297
JPanel messagePanel = new JPanel(new BorderLayout());
298
messageScroll = new JScrollPane(messageText);
299
messagePanel.add(messageScroll);
300
messagePanel.setBorder(BorderFactory.createCompoundBorder(
301
BorderFactory.createTitledBorder("Messages"),
302
BorderFactory.createEmptyBorder(4, 4, 4, 4)
305
JPanel mainPanel = new JPanel();
306
mainPanel.setLayout(new BorderLayout());
307
mainPanel.add(controlsPanel, BorderLayout.NORTH);
308
mainPanel.add(treeScroll, BorderLayout.CENTER);
309
mainPanel.add(messagePanel, BorderLayout.SOUTH);
310
getContentPane().add(mainPanel);
312
Hashtable errorNodes = errors.getErrorNodes();
313
Enumeration elements = errorNodes.elements();
314
while (elements.hasMoreElements()) {
315
//*** append errors to messageText
316
messageText.append( (String)elements.nextElement());
319
// This cast must work, because we have tested above
320
// with document.isSupported("Traversal")
321
iterator = ((DocumentTraversal)document).
325
new NameNodeFilter(),
328
} catch (Exception e) {
329
e.printStackTrace(System.err);
333
public void actionPerformed(ActionEvent e) {
335
if (e.getSource() == newIterator) {
336
Node node = document;
338
// whatToShow section
339
int [] indices = whatToShow.getSelectedIndices();
341
for (int i = 0; i < indices.length; i++) {
342
if (indices[i] == 0) {
346
mask = mask | 1<<indices[i]-1;
350
String nameText = nameFilter.getText();
351
boolean matched = match.isSelected();
352
if (nameNodeFilter==null) {
353
nameNodeFilter = new NameNodeFilter();
355
if (nameText.equals("")) {
356
setMessage("NodeNameFilter name is \"\". Assuming null.");
359
nameNodeFilter.setName(nameText);
360
nameNodeFilter.setMatch(matched);
362
if (iterator !=null) iterator.detach();
363
boolean expand = expandERs.isSelected();
364
iterator = ((DocumentTraversal)document).
370
setMessage("doc.createNodeIterator("+
372
", whatToShow="+mask+
374
", name="+nameText+")"
380
if (e.getSource() == addButton) {
382
String text = addText.getText();
384
if (text==null) return;
386
TreeNode treeNode = (TreeNode)jtree.getLastSelectedPathComponent();
387
if (treeNode == null) {
388
messageText.append("Must select a tree component to add a child to it.");
391
TreePath path = new TreePath(
392
((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
394
setMessage("Could not create a path.");
397
if(!jtree.getSelectionModel().isPathSelected(path))
399
Node node = jtree.getNode(treeNode);
400
Node textNode = document.createTextNode(text);
402
node.appendChild(textNode);
403
} catch (DOMException dome) {
404
setMessage("DOMException:"+dome.code+", "+dome);
407
((DOMTreeFull.Model)jtree.getModel()).insertNode(textNode, (MutableTreeNode)treeNode);
411
if (e.getSource() == nextButton) {
412
Node node = iterator.nextNode();
414
setMessage("iterator.nextNode() == null");
418
setMessage("iterator.nextNode() == "+node);
420
TreeNode treeNode = jtree.getTreeNode(node);
421
if (treeNode == null) {
422
setMessage("No JTree TreeNode for Node name:" + node.getNodeName());
426
TreePath path = new TreePath(
427
((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
428
jtree.requestFocus();
429
jtree.setSelectionPath(path);
430
jtree.scrollPathToVisible(path);
434
if (e.getSource() == prevButton) {
435
Node node = iterator.previousNode();
437
setMessage("iterator.previousNode() == null");
441
setMessage("iterator.previousNode() == "+node);
443
TreeNode treeNode = jtree.getTreeNode(node);
444
if (treeNode == null) {
445
setMessage("No JTree TreeNode for Node name:" + node.getNodeName());
449
TreePath path = new TreePath(
450
((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
451
jtree.requestFocus();
452
jtree.setSelectionPath(path);
453
jtree.scrollPathToVisible(path);
456
if (e.getSource() == removeButton) {
458
/** If the node is not selected don't remove. */
459
TreeNode treeNode = (TreeNode)jtree.getLastSelectedPathComponent();
460
if (treeNode == null) {
461
messageText.append("Must select a tree component to remove it.");
464
TreePath path = new TreePath(
465
((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
467
setMessage("Could not create a path.");
470
if(!jtree.getSelectionModel().isPathSelected(path))
472
Node node = jtree.getNode(treeNode);
473
if (node == null) return;
474
Node parent = node.getParentNode();
475
if (parent == null) return;
477
parent.removeChild(node);
479
((DefaultTreeModel)jtree.getModel()).removeNodeFromParent((MutableTreeNode)treeNode);
485
/** Helper function to set messages */
486
void setMessage(String string) {
487
messageText.selectAll();
489
messageText.append(string);
490
messageText.setCaretPosition(0);
493
/** called when our JTree's nodes are selected.
495
void nodeSelected(TreeNode treeNode) {
497
lastSelected = treeNode;
498
Node node = jtree.getNode(treeNode);
500
System.out.println("nodeSelected.node="+node);
501
if (node == null) return;
503
setMessage(DOMTreeFull.toString(node));
506
/** Utility function to expand the jtree */
508
for (int i = 0; i < jtree.getRowCount(); i++) {
513
class Errors implements ErrorHandler {
515
Hashtable errorNodes = new Hashtable();
517
public void warning(SAXParseException ex) {
518
store(ex, "[Warning]");
521
public void error(SAXParseException ex) {
522
store(ex, "[Error]");
525
public void fatalError(SAXParseException ex) throws SAXException {
526
store(ex, "[Fatal Error]");
529
public Hashtable getErrorNodes() {
533
public Object getError(Node node) {
534
return errorNodes.get(node);
537
public void clearErrors() {
541
void store(SAXParseException ex, String type) {
544
String errorString= type+" at line number, "+ex.getLineNumber()
545
+": "+ex.getMessage()+"\n";
546
Node currentNode = null;
548
currentNode = (Node)parser.getProperty("http://apache.org/xml/properties/dom-node");
549
} catch (SAXException se) {
550
System.err.println(se.getMessage());
553
if (currentNode == null) return;
555
// accumulate any multiple errors per node in the Hashtable.
556
String previous = (String) errorNodes.get(currentNode);
557
if (previous != null)
558
errorNodes.put(currentNode, previous +errorString);
560
errorNodes.put(currentNode, errorString);