2
* Licensed to the Apache Software Foundation (ASF) under one or more
3
* contributor license agreements. See the NOTICE file distributed with
4
* this work for additional information regarding copyright ownership.
5
* The ASF licenses this file to You under the Apache License, Version 2.0
6
* (the "License"); you may not use this file except in compliance with
7
* the License. You may obtain a copy of the License at
9
* http://www.apache.org/licenses/LICENSE-2.0
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
17
package dom.traversal;
19
import java.awt.BorderLayout;
20
import java.awt.Dimension;
21
import java.awt.event.ActionEvent;
22
import java.awt.event.ActionListener;
23
import java.util.Enumeration;
24
import java.util.Hashtable;
26
import javax.swing.BorderFactory;
27
import javax.swing.JButton;
28
import javax.swing.JCheckBox;
29
import javax.swing.JFrame;
30
import javax.swing.JList;
31
import javax.swing.JPanel;
32
import javax.swing.JScrollPane;
33
import javax.swing.JTextArea;
34
import javax.swing.JTextField;
35
import javax.swing.event.ListSelectionEvent;
36
import javax.swing.event.ListSelectionListener;
37
import javax.swing.event.TreeSelectionEvent;
38
import javax.swing.event.TreeSelectionListener;
39
import javax.swing.tree.DefaultTreeModel;
40
import javax.swing.tree.MutableTreeNode;
41
import javax.swing.tree.TreeNode;
42
import javax.swing.tree.TreePath;
43
import javax.swing.tree.TreeSelectionModel;
45
import org.apache.xerces.parsers.DOMParser;
46
import org.w3c.dom.DOMException;
47
import org.w3c.dom.Document;
48
import org.w3c.dom.Node;
49
import org.w3c.dom.traversal.DocumentTraversal;
50
import org.w3c.dom.traversal.NodeFilter;
51
import org.w3c.dom.traversal.NodeIterator;
52
import org.xml.sax.ErrorHandler;
53
import org.xml.sax.SAXException;
54
import org.xml.sax.SAXParseException;
56
import ui.DOMTreeFull;
58
/** This class shows a DOM Document in a JTree, and presents controls
59
* which allow the user to create and view the progress of a NodeIterator
62
public class IteratorView
64
implements ActionListener {
66
private static final long serialVersionUID = 3256726186452662580L;
69
TreeNode lastSelected;
71
JTextArea messageText;
72
JScrollPane messageScroll;
74
NodeIterator iterator;
75
NameNodeFilter nameNodeFilter;
85
JTextField nameFilter;
86
String whatArray[] = new String [] {
94
"PROCESSING_INSTRUCTION",
103
Hashtable treeNodeMap = new Hashtable();
107
public static void main (String args[]) {
109
if (args.length > 0) {
110
String filename = args[0];
112
IteratorView frame = new IteratorView(filename) ;
113
frame.addWindowListener(new java.awt.event.WindowAdapter() {
114
public void windowClosing(java.awt.event.WindowEvent e) {
118
frame.setSize(640, 480);
119
frame.setVisible(true);
120
} catch (Exception e) {
121
e.printStackTrace(System.err);
127
public IteratorView (String filename) {
128
super("IteratorView: "+filename);
130
parser = new DOMParser();
131
parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", true);
132
parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
133
Errors errors = new Errors();
134
parser.setErrorHandler(errors);
135
parser.parse(filename);
136
document = parser.getDocument();
138
if (!document.isSupported("Traversal", "2.0")) {
139
// This cannot happen with ou DOMParser...
140
throw new RuntimeException("This DOM Document does not support Traversal");
144
jtree = new DOMTreeFull((Node)document);
145
jtree.getSelectionModel().setSelectionMode
146
(TreeSelectionModel.SINGLE_TREE_SELECTION);
147
jtree.setRootVisible(false);
149
// Listen for when the selection changes, call nodeSelected(node)
150
jtree.addTreeSelectionListener(
151
new TreeSelectionListener() {
152
public void valueChanged(TreeSelectionEvent e) {
153
TreePath path = (TreePath)e.getPath();
154
TreeNode treeNode = (TreeNode)path.getLastPathComponent();
155
if(jtree.getSelectionModel().isPathSelected(path))
156
nodeSelected(treeNode);
168
JPanel iteratePanel = new JPanel();
169
iteratePanel.setBorder(BorderFactory.createCompoundBorder(
170
BorderFactory.createTitledBorder("Iterate"),
171
BorderFactory.createEmptyBorder(4, 4, 4, 4)
174
prevButton = new JButton("Previous");
175
iteratePanel.add(prevButton);
176
prevButton.addActionListener(this);
178
nextButton = new JButton("Next");
179
iteratePanel.add(nextButton);
180
nextButton.addActionListener(this);
183
JPanel domPanel = new JPanel();
184
domPanel.setLayout(new BorderLayout());
185
domPanel.setBorder(BorderFactory.createCompoundBorder(
186
BorderFactory.createTitledBorder("Selected Node"),
187
BorderFactory.createEmptyBorder(4, 4, 4, 4)
190
removeButton = new JButton("Remove Selected Node");
191
domPanel.add(removeButton, BorderLayout.NORTH);
192
removeButton.addActionListener(this);
194
addButton = new JButton("Add Text Node");
195
addText = new JTextField(10);
196
domPanel.add(addButton, BorderLayout.CENTER);
197
domPanel.add(addText, BorderLayout.SOUTH);
198
addButton.addActionListener(this);
201
JPanel settingsPanel = new JPanel();
202
settingsPanel.setLayout(new BorderLayout());
203
settingsPanel.setBorder(BorderFactory.createCompoundBorder(
204
BorderFactory.createTitledBorder("Iterator Settings"),
205
BorderFactory.createEmptyBorder(4, 4, 4, 4)
207
JPanel iteratorPanel = new JPanel();
208
newIterator = new JButton("createNodeIterator");
209
expandERs = new JCheckBox("expandEntityReferences");
210
iteratorPanel.add(newIterator);
211
expandERs.setSelected(true);
212
iteratorPanel.add(expandERs);
213
settingsPanel.add(iteratorPanel, BorderLayout.NORTH);
214
newIterator.addActionListener(this);
216
JPanel whatPanel = new JPanel();
217
whatPanel.setBorder(BorderFactory.createCompoundBorder(
218
BorderFactory.createTitledBorder("whatToShow"),
219
BorderFactory.createEmptyBorder(4, 4, 4, 4)
221
whatToShow = new JList(DOMTreeFull.whatArray);
222
JScrollPane whatScroll =
223
new JScrollPane(whatToShow) {
224
private static final long serialVersionUID = 3546357344813724213L;
225
public Dimension getPreferredSize(){
226
return new Dimension(200, 75 );
230
whatPanel.add(whatScroll);
233
JPanel filterPanel = new JPanel();
234
filterPanel.setBorder(BorderFactory.createCompoundBorder(
235
BorderFactory.createTitledBorder("NodeNameFilter"),
236
BorderFactory.createEmptyBorder(4, 4, 4, 4)
238
filterPanel.setLayout(new BorderLayout());
239
match = new JCheckBox("match/ignore node name", true);
240
nameFilter = new JTextField(10);
241
filterPanel.add(match, BorderLayout.NORTH);
242
filterPanel.add(nameFilter, BorderLayout.SOUTH);
244
settingsPanel.add(whatPanel, BorderLayout.WEST);
245
settingsPanel.add(filterPanel, BorderLayout.EAST);
248
// Listen for when the selection changes, call nodeSelected(node)
249
whatToShow.addListSelectionListener(
250
new ListSelectionListener() {
251
public void valueChanged(ListSelectionEvent e) {
252
// do nothing on selection...
258
JPanel controlsPanel = new JPanel(new BorderLayout());
259
JPanel buttonsPanel = new JPanel(new BorderLayout());
260
buttonsPanel.add(iteratePanel, BorderLayout.NORTH);
261
buttonsPanel.add(domPanel, BorderLayout.SOUTH);
262
controlsPanel.add(buttonsPanel, BorderLayout.WEST);
263
controlsPanel.add(settingsPanel, BorderLayout.CENTER);
265
controlsPanel.setBorder(BorderFactory.createCompoundBorder(
266
BorderFactory.createTitledBorder("Controls"),
267
BorderFactory.createEmptyBorder(4, 4, 4, 4)
272
JPanel treePanel = new JPanel(new BorderLayout());
274
JScrollPane treeScroll = new JScrollPane(jtree) ;
275
treeScroll.setBorder(BorderFactory.createCompoundBorder(
276
BorderFactory.createTitledBorder("Tree View"),
277
BorderFactory.createEmptyBorder(4, 4, 4, 4)
280
// message text UI setup
281
messageText = new JTextArea(3,5);
283
JPanel messagePanel = new JPanel(new BorderLayout());
284
messageScroll = new JScrollPane(messageText);
285
messagePanel.add(messageScroll);
286
messagePanel.setBorder(BorderFactory.createCompoundBorder(
287
BorderFactory.createTitledBorder("Messages"),
288
BorderFactory.createEmptyBorder(4, 4, 4, 4)
291
JPanel mainPanel = new JPanel();
292
mainPanel.setLayout(new BorderLayout());
293
mainPanel.add(controlsPanel, BorderLayout.NORTH);
294
mainPanel.add(treeScroll, BorderLayout.CENTER);
295
mainPanel.add(messagePanel, BorderLayout.SOUTH);
296
getContentPane().add(mainPanel);
298
Hashtable errorNodes = errors.getErrorNodes();
299
Enumeration elements = errorNodes.elements();
300
while (elements.hasMoreElements()) {
301
//*** append errors to messageText
302
messageText.append( (String)elements.nextElement());
305
// This cast must work, because we have tested above
306
// with document.isSupported("Traversal")
307
iterator = ((DocumentTraversal)document).
311
new NameNodeFilter(),
314
} catch (Exception e) {
315
e.printStackTrace(System.err);
319
public void actionPerformed(ActionEvent e) {
321
if (e.getSource() == newIterator) {
322
Node node = document;
324
// whatToShow section
325
int [] indices = whatToShow.getSelectedIndices();
327
for (int i = 0; i < indices.length; i++) {
328
if (indices[i] == 0) {
332
mask = mask | 1<<indices[i]-1;
336
String nameText = nameFilter.getText();
337
boolean matched = match.isSelected();
338
if (nameNodeFilter==null) {
339
nameNodeFilter = new NameNodeFilter();
341
if (nameText.equals("")) {
342
setMessage("NodeNameFilter name is \"\". Assuming null.");
345
nameNodeFilter.setName(nameText);
346
nameNodeFilter.setMatch(matched);
348
if (iterator !=null) iterator.detach();
349
boolean expand = expandERs.isSelected();
350
iterator = ((DocumentTraversal)document).
356
setMessage("doc.createNodeIterator("+
358
", whatToShow="+mask+
360
", name="+nameText+")"
366
if (e.getSource() == addButton) {
368
String text = addText.getText();
370
if (text==null) return;
372
TreeNode treeNode = (TreeNode)jtree.getLastSelectedPathComponent();
373
if (treeNode == null) {
374
messageText.append("Must select a tree component to add a child to it.");
377
TreePath path = new TreePath(
378
((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
380
setMessage("Could not create a path.");
383
if(!jtree.getSelectionModel().isPathSelected(path))
385
Node node = jtree.getNode(treeNode);
386
Node textNode = document.createTextNode(text);
388
node.appendChild(textNode);
389
} catch (DOMException dome) {
390
setMessage("DOMException:"+dome.code+", "+dome);
393
((DOMTreeFull.Model)jtree.getModel()).insertNode(textNode, (MutableTreeNode)treeNode);
397
if (e.getSource() == nextButton) {
398
Node node = iterator.nextNode();
400
setMessage("iterator.nextNode() == null");
404
setMessage("iterator.nextNode() == "+node);
406
TreeNode treeNode = jtree.getTreeNode(node);
407
if (treeNode == null) {
408
setMessage("No JTree TreeNode for Node name:" + node.getNodeName());
412
TreePath path = new TreePath(
413
((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
414
jtree.requestFocus();
415
jtree.setSelectionPath(path);
416
jtree.scrollPathToVisible(path);
420
if (e.getSource() == prevButton) {
421
Node node = iterator.previousNode();
423
setMessage("iterator.previousNode() == null");
427
setMessage("iterator.previousNode() == "+node);
429
TreeNode treeNode = jtree.getTreeNode(node);
430
if (treeNode == null) {
431
setMessage("No JTree TreeNode for Node name:" + node.getNodeName());
435
TreePath path = new TreePath(
436
((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
437
jtree.requestFocus();
438
jtree.setSelectionPath(path);
439
jtree.scrollPathToVisible(path);
442
if (e.getSource() == removeButton) {
444
/** If the node is not selected don't remove. */
445
TreeNode treeNode = (TreeNode)jtree.getLastSelectedPathComponent();
446
if (treeNode == null) {
447
messageText.append("Must select a tree component to remove it.");
450
TreePath path = new TreePath(
451
((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
453
setMessage("Could not create a path.");
456
if(!jtree.getSelectionModel().isPathSelected(path))
458
Node node = jtree.getNode(treeNode);
459
if (node == null) return;
460
Node parent = node.getParentNode();
461
if (parent == null) return;
463
parent.removeChild(node);
465
((DefaultTreeModel)jtree.getModel()).removeNodeFromParent((MutableTreeNode)treeNode);
471
/** Helper function to set messages */
472
void setMessage(String string) {
473
messageText.selectAll();
475
messageText.append(string);
476
messageText.setCaretPosition(0);
479
/** called when our JTree's nodes are selected.
481
void nodeSelected(TreeNode treeNode) {
483
lastSelected = treeNode;
484
Node node = jtree.getNode(treeNode);
486
System.out.println("nodeSelected.node="+node);
487
if (node == null) return;
489
setMessage(DOMTreeFull.toString(node));
492
/** Utility function to expand the jtree */
494
for (int i = 0; i < jtree.getRowCount(); i++) {
499
class Errors implements ErrorHandler {
501
Hashtable errorNodes = new Hashtable();
503
public void warning(SAXParseException ex) {
504
store(ex, "[Warning]");
507
public void error(SAXParseException ex) {
508
store(ex, "[Error]");
511
public void fatalError(SAXParseException ex) throws SAXException {
512
store(ex, "[Fatal Error]");
515
public Hashtable getErrorNodes() {
519
public Object getError(Node node) {
520
return errorNodes.get(node);
523
public void clearErrors() {
527
void store(SAXParseException ex, String type) {
530
String errorString= type+" at line number, "+ex.getLineNumber()
531
+": "+ex.getMessage()+"\n";
532
Node currentNode = null;
534
currentNode = (Node)parser.getProperty("http://apache.org/xml/properties/dom-node");
535
} catch (SAXException se) {
536
System.err.println(se.getMessage());
539
if (currentNode == null) return;
541
// accumulate any multiple errors per node in the Hashtable.
542
String previous = (String) errorNodes.get(currentNode);
543
if (previous != null)
544
errorNodes.put(currentNode, previous +errorString);
546
errorNodes.put(currentNode, errorString);