Save This Page
Home » Xerces-J-src.2.9.1 » dom » traversal » [javadoc | source]
    1   /*
    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
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   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.
   16    */
   17   package dom.traversal;
   18   
   19   import java.awt.BorderLayout;
   20   import java.awt.Dimension;
   21   import java.awt.Font;
   22   import java.awt.event.ActionEvent;
   23   import java.awt.event.ActionListener;
   24   import java.util.Enumeration;
   25   import java.util.Hashtable;
   26   
   27   import javax.swing.BorderFactory;
   28   import javax.swing.JButton;
   29   import javax.swing.JCheckBox;
   30   import javax.swing.JFrame;
   31   import javax.swing.JList;
   32   import javax.swing.JPanel;
   33   import javax.swing.JScrollPane;
   34   import javax.swing.JTextArea;
   35   import javax.swing.JTextField;
   36   import javax.swing.event.ListSelectionEvent;
   37   import javax.swing.event.ListSelectionListener;
   38   import javax.swing.event.TreeSelectionEvent;
   39   import javax.swing.event.TreeSelectionListener;
   40   import javax.swing.tree.DefaultTreeModel;
   41   import javax.swing.tree.MutableTreeNode;
   42   import javax.swing.tree.TreeNode;
   43   import javax.swing.tree.TreePath;
   44   import javax.swing.tree.TreeSelectionModel;
   45   
   46   import org.apache.xerces.parsers.DOMParser;
   47   import org.w3c.dom.DOMException;
   48   import org.w3c.dom.Document;
   49   import org.w3c.dom.Node;
   50   import org.w3c.dom.traversal.DocumentTraversal;
   51   import org.w3c.dom.traversal.NodeFilter;
   52   import org.w3c.dom.traversal.TreeWalker;
   53   import org.xml.sax.ErrorHandler;
   54   import org.xml.sax.SAXException;
   55   import org.xml.sax.SAXParseException;
   56   
   57   import ui.DOMTreeFull;
   58   
   59   /** This class shows a DOM Document in a JTree, and presents controls
   60    *  which allow the user to create and view the progress of a TreeWalker
   61    *  in the DOM tree.
   62    */
   63   public class TreeWalkerView 
   64       extends JFrame 
   65       implements ActionListener {
   66   
   67       private static final long serialVersionUID = 3257566187583189559L;
   68       
   69       Document document;
   70       TreeNode lastSelected;
   71       DOMParser parser;
   72       JTextArea messageText;
   73       JScrollPane messageScroll;
   74       DOMTreeFull jtree;
   75       TreeWalker treeWalker;
   76       NameNodeFilter nameNodeFilter;
   77       
   78       JButton nextButton;
   79       JButton prevButton;
   80       JButton removeButton;
   81       JButton addButton;
   82       JTextField addText;
   83       JButton newIterator;
   84       JList whatToShow;
   85       JCheckBox match;
   86       JTextField nameFilter;
   87      
   88       // treeWalker specific buttons    
   89       JButton parentButton;
   90       JButton nextSiblingButton;
   91       JButton previousSiblingButton;
   92       JButton firstChildButton;
   93       JButton lastChildButton;
   94       JButton currentButton;
   95       
   96       String whatArray[] = new String [] { 
   97               "ALL",
   98               "ELEMENT",
   99               "ATTRIBUTE",
  100               "TEXT",
  101               "CDATA_SECTION",
  102               "ENTITY_REFERENCE",
  103               "ENTITY",
  104               "PROCESSING_INSTRUCTION", 
  105               "COMMENT", 
  106               "DOCUMENT", 
  107               "DOCUMENT_TYPE",
  108               "DOCUMENT_FRAGMENT",
  109               "NOTATION" 
  110               };
  111       JCheckBox expandERs;
  112       
  113       
  114       /** main */
  115       public static void main (String args[]) {
  116   
  117           if (args.length > 0) {
  118               String filename = args[0];
  119               try {
  120                   TreeWalkerView frame = new TreeWalkerView(filename) ;
  121                   frame.addWindowListener(new java.awt.event.WindowAdapter() {
  122                    public void windowClosing(java.awt.event.WindowEvent e) {
  123                        System.exit(0);
  124                    }
  125                   });
  126                   frame.setSize(640, 700);
  127                   frame.setVisible(true);
  128                   } catch (Exception e) {
  129                       e.printStackTrace(System.err);
  130                   }
  131           }
  132       }
  133       
  134       Hashtable treeNodeMap = new Hashtable();
  135   
  136       /** Constructor */
  137       public TreeWalkerView (String filename) {
  138           super("TreeWalkerView: "+filename);
  139           try {
  140               parser = new DOMParser();
  141               parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", true);
  142               parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
  143               Errors errors = new Errors();
  144               parser.setErrorHandler(errors);
  145               parser.parse(filename);
  146               document = parser.getDocument();
  147               
  148               if (!document.isSupported("Traversal", "2.0")) {
  149                   // This cannot happen with the DOMParser...
  150                   throw new RuntimeException("This DOM Document does not support Traversal");
  151               
  152               }
  153   
  154               // jtree  UI setup
  155               jtree = new DOMTreeFull((Node)document);
  156               jtree.getSelectionModel().setSelectionMode
  157                   (TreeSelectionModel.SINGLE_TREE_SELECTION);
  158   
  159               // Listen for when the selection changes, call nodeSelected(node)
  160               jtree.addTreeSelectionListener(
  161                   new TreeSelectionListener() {
  162                       public void valueChanged(TreeSelectionEvent e) {
  163                           TreePath path = (TreePath)e.getPath(); 
  164                           TreeNode treeNode = (TreeNode)path.getLastPathComponent();
  165                           if(jtree.getSelectionModel().isPathSelected(path))
  166                                   nodeSelected(treeNode);
  167                       }
  168                   }
  169               );
  170               
  171               //            
  172               // controls
  173               //
  174               
  175               BorderLayout borderLayout = new BorderLayout();
  176               
  177               //iterate panel
  178               JPanel iteratePanel = new JPanel();
  179               iteratePanel.setBorder(BorderFactory.createCompoundBorder(
  180                   BorderFactory.createTitledBorder("Document Order Traversal"),
  181                   BorderFactory.createEmptyBorder(4, 4, 4, 4)
  182                   ));
  183               
  184               prevButton = new JButton("Previous");
  185               iteratePanel.add(prevButton);
  186               prevButton.addActionListener(this);
  187               
  188               nextButton = new JButton("Next");
  189               iteratePanel.add(nextButton);
  190               nextButton.addActionListener(this);
  191           
  192               //walkerPanel
  193               JPanel walkerPanel = new JPanel();
  194               walkerPanel.setLayout(new BorderLayout());
  195               walkerPanel.setBorder(BorderFactory.createCompoundBorder(
  196                   BorderFactory.createTitledBorder("Walk"),
  197                   BorderFactory.createEmptyBorder(4, 4, 4, 4)
  198                   ));
  199               
  200               parentButton = new JButton("Parent");
  201               walkerPanel.add(parentButton, BorderLayout.NORTH);
  202               parentButton.addActionListener(this);
  203              
  204               
  205               JPanel childPanel = new JPanel();
  206               firstChildButton = new JButton("First Child");
  207               childPanel.add(firstChildButton);
  208               firstChildButton.addActionListener(this);
  209      
  210               lastChildButton = new JButton("Last Child");
  211               childPanel.add(lastChildButton);
  212               lastChildButton.addActionListener(this);
  213               walkerPanel.add(childPanel, BorderLayout.SOUTH);
  214               
  215               nextSiblingButton = new JButton("Next Sibling");
  216               walkerPanel.add(nextSiblingButton, BorderLayout.EAST);
  217               nextSiblingButton.addActionListener(this);
  218               
  219               previousSiblingButton = new JButton("Previous Sibling");
  220               walkerPanel.add(previousSiblingButton, BorderLayout.WEST);
  221               previousSiblingButton.addActionListener(this);
  222               
  223               //DOM tree panel
  224               JPanel domPanel = new JPanel();
  225               domPanel.setLayout(new BorderLayout());
  226               domPanel.setBorder(BorderFactory.createCompoundBorder(
  227                   BorderFactory.createTitledBorder("Selected Node"),
  228                   BorderFactory.createEmptyBorder(4, 4, 4, 4)
  229                   ));
  230               
  231               JPanel buttonPanel = new JPanel();
  232               currentButton = new JButton("Current");
  233               buttonPanel.add(currentButton);
  234               currentButton.addActionListener(this);
  235      
  236               removeButton = new JButton("Remove");
  237               buttonPanel.add(removeButton);
  238               removeButton.addActionListener(this);
  239               
  240               addButton = new JButton("Append Text");
  241               addText = new JTextField(10);
  242               buttonPanel.add(addButton);
  243               domPanel.add(buttonPanel, BorderLayout.NORTH);
  244               domPanel.add(addText, BorderLayout.CENTER);
  245               addButton.addActionListener(this);
  246            
  247               // treeWalker settings
  248               JPanel settingsPanel = new JPanel();
  249               settingsPanel.setLayout(new BorderLayout());
  250               settingsPanel.setBorder(BorderFactory.createCompoundBorder(
  251                   BorderFactory.createTitledBorder("Filter Settings"),
  252                   BorderFactory.createEmptyBorder(4, 4, 4, 4)
  253                   ));
  254               JPanel treeWalkerPanel = new JPanel();
  255               treeWalkerPanel.setLayout(new BorderLayout());
  256               
  257               newIterator = new JButton("createTreeWalker");
  258               treeWalkerPanel.add(newIterator, BorderLayout.NORTH);
  259               expandERs = new JCheckBox("expandEntityReferences");
  260               expandERs.setSelected(true);
  261               treeWalkerPanel.add(expandERs, BorderLayout.SOUTH);
  262               settingsPanel.add(treeWalkerPanel, BorderLayout.NORTH);
  263               newIterator.addActionListener(this);
  264       
  265               JPanel whatPanel = new JPanel();
  266               whatPanel.setBorder(BorderFactory.createCompoundBorder(
  267                   BorderFactory.createTitledBorder("whatToShow"),
  268                   BorderFactory.createEmptyBorder(0, 0, 0, 0)
  269                   ));
  270               whatToShow = new JList(whatArray);
  271               JScrollPane whatScroll = 
  272               new JScrollPane(whatToShow) {
  273                       private static final long serialVersionUID = 3545240236637305138L;
  274                       public Dimension getPreferredSize(){
  275                           return new Dimension(200, 65 );
  276                       }
  277                   };
  278               
  279               whatPanel.add(whatScroll);
  280               
  281               
  282               JPanel filterPanel = new JPanel();
  283               filterPanel.setBorder(BorderFactory.createCompoundBorder(
  284                   BorderFactory.createTitledBorder("NodeNameFilter"),
  285                   BorderFactory.createEmptyBorder(4, 4, 4, 4)
  286                   ));
  287               filterPanel.setLayout(new BorderLayout());
  288               match = new JCheckBox("match/ignore node name", true);
  289               nameFilter = new JTextField(10);
  290               filterPanel.add(match, BorderLayout.NORTH);
  291               filterPanel.add(nameFilter, BorderLayout.SOUTH);
  292               
  293               settingsPanel.add(treeWalkerPanel, BorderLayout.NORTH);
  294               settingsPanel.add(whatPanel, BorderLayout.CENTER);
  295               settingsPanel.add(filterPanel, BorderLayout.SOUTH);
  296               
  297   
  298               // Listen for when the selection changes, call nodeSelected(node)
  299               whatToShow.addListSelectionListener(
  300                   new ListSelectionListener() {
  301                       public void valueChanged(ListSelectionEvent e) {
  302                           // do nothing on selection...
  303                       }
  304                   }
  305               );
  306               
  307               
  308               JPanel controlsPanel = new JPanel(new BorderLayout());
  309               controlsPanel.setFont(new Font("Dialog", Font.PLAIN, 8));
  310               JPanel buttonsPanel = new JPanel(new BorderLayout());
  311               buttonsPanel.add(iteratePanel, BorderLayout.NORTH);
  312               buttonsPanel.add(walkerPanel, BorderLayout.CENTER);
  313               buttonsPanel.add(domPanel, BorderLayout.SOUTH);
  314               controlsPanel.add(buttonsPanel, BorderLayout.NORTH);
  315               controlsPanel.add(settingsPanel, BorderLayout.CENTER);
  316               
  317               controlsPanel.setBorder(BorderFactory.createCompoundBorder(
  318                   BorderFactory.createTitledBorder("Controls"),
  319                   BorderFactory.createEmptyBorder(4, 4, 4, 4)
  320                   ));
  321                   
  322                   
  323               // tree panel    
  324               JPanel treePanel = new JPanel(new BorderLayout());
  325                   
  326               JScrollPane treeScroll = new JScrollPane(jtree) ;
  327               treeScroll.setBorder(BorderFactory.createCompoundBorder(
  328                   BorderFactory.createTitledBorder("Tree View"),
  329                   BorderFactory.createEmptyBorder(4, 4, 4, 4)
  330                   ));
  331   
  332               // message text UI setup
  333               messageText = new JTextArea(3,5);
  334   
  335               JPanel messagePanel = new JPanel(new BorderLayout());
  336               messageScroll = new JScrollPane(messageText);
  337               messagePanel.add(messageScroll);
  338               messagePanel.setBorder(BorderFactory.createCompoundBorder(
  339                   BorderFactory.createTitledBorder("Messages"),
  340                   BorderFactory.createEmptyBorder(4, 4, 4, 4)
  341                   ));
  342               
  343               JPanel mainPanel = new JPanel();
  344               mainPanel.setLayout(new BorderLayout());
  345               mainPanel.add(controlsPanel, BorderLayout.EAST);
  346               mainPanel.add(treeScroll, BorderLayout.CENTER);
  347               mainPanel.add(messagePanel, BorderLayout.SOUTH);
  348               getContentPane().add(mainPanel);
  349               
  350               Hashtable errorNodes = errors.getErrorNodes();
  351               Enumeration elements = errorNodes.elements();
  352               while (elements.hasMoreElements()) {
  353                   //*** append errors to messageText
  354                   messageText.append( (String)elements.nextElement());
  355               }    
  356               
  357               boolean expand = expandERs.isSelected();
  358               treeWalker = ((DocumentTraversal)document).
  359                   createTreeWalker(
  360                       document, 
  361                       NodeFilter.SHOW_ALL, 
  362                       new NameNodeFilter(),
  363                       expand);
  364               
  365           } catch (Exception e) {
  366               e.printStackTrace(System.err);
  367           }
  368       }
  369                  
  370       public void actionPerformed(ActionEvent e) {
  371           
  372           if (e.getSource() == newIterator) {
  373               
  374               TreeNode treeNode = (TreeNode)jtree.getLastSelectedPathComponent();
  375               if (treeNode == null) {
  376                   messageText.append("Must select a tree component.");
  377                   return;
  378               }
  379               
  380               Node node = jtree.getNode(treeNode);
  381               if (node == null) {
  382                   setMessage("No current Node in TreeNode: "+node);
  383               }
  384               
  385               // whatToShow section
  386               int  [] indices = whatToShow.getSelectedIndices();
  387               int mask = 0x0;
  388               for (int i = 0; i < indices.length; i++) {
  389                   if (indices[i] == 0) {
  390                       mask = 0xFFFF;
  391                       break;
  392                   } else {
  393                       mask = mask | 1<<indices[i]-1;
  394                   }
  395               }
  396               
  397               // filter section
  398               String nameText = nameFilter.getText();
  399               boolean matched = match.isSelected();
  400               if (nameNodeFilter==null) {
  401                   nameNodeFilter = new NameNodeFilter();
  402               }
  403               if (nameText.equals("")) {
  404                   setMessage("NodeNameFilter name is \"\". Assuming null.");
  405                   nameText = null;
  406               }
  407               nameNodeFilter.setName(nameText);
  408               nameNodeFilter.setMatch(matched);
  409               
  410               // expand Entity References?
  411               boolean expand = expandERs.isSelected();
  412               
  413               treeWalker = ((DocumentTraversal)document).
  414                   createTreeWalker(
  415                       node, 
  416                       mask, 
  417                       nameNodeFilter,
  418                       expand);
  419               setMessage("createTreeWalker:"+ 
  420                           " root="+node+
  421                           ", whatToShow="+mask+
  422                           ", match="+matched+
  423                           ", name="+nameText
  424                           );
  425               return;
  426               
  427           } 
  428           
  429           if (e.getSource() == currentButton) {
  430               
  431               TreeNode treeNode = (TreeNode)jtree.getLastSelectedPathComponent();
  432               if (treeNode == null) {
  433                   messageText.append("Must select a tree component.");
  434                   return;
  435               }
  436               
  437               Node node = jtree.getNode(treeNode);
  438               if (node == null) {
  439                   setMessage("No current Node in TreeNode: "+node);
  440               }
  441               treeWalker.setCurrentNode(node);
  442               return;
  443               
  444           }
  445           if (e.getSource() == addButton) {
  446               
  447               String text = addText.getText();
  448               
  449               if (text==null) return;
  450               
  451               TreeNode treeNode = (TreeNode)jtree.getLastSelectedPathComponent();
  452               if (treeNode == null) {
  453                   messageText.append("Must select a tree component to add a child to it.");
  454                   return;
  455               }
  456               TreePath path = new TreePath(
  457                       ((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
  458               if (path == null) {
  459                   setMessage("Could not create a path.");
  460                   return;
  461               }
  462               if(!jtree.getSelectionModel().isPathSelected(path))
  463                   return;
  464               Node node = jtree.getNode(treeNode);
  465               Node textNode = document.createTextNode(text);
  466               try {
  467                   node.appendChild(textNode);
  468               } catch (DOMException dome) {
  469                   setMessage("DOMException:"+dome.code+", "+dome);
  470                   return;
  471               }
  472               ((DOMTreeFull.Model)jtree.getModel()).insertNode(textNode, (MutableTreeNode)treeNode);
  473               
  474               return;
  475           }
  476           
  477           if (e.getSource() == removeButton) {
  478   
  479               /** If the node is not selected don't remove. */
  480               TreeNode treeNode = (TreeNode)jtree.getLastSelectedPathComponent();
  481               if (treeNode == null) {
  482                   messageText.append("Must select a tree component to remove it.");
  483                   return;
  484               }
  485               TreePath path = new TreePath(
  486                       ((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
  487               if (path == null) {
  488                   setMessage("Could not create a path.");
  489                   return;
  490               }
  491               if(!jtree.getSelectionModel().isPathSelected(path))
  492                   return;
  493               Node node = jtree.getNode(treeNode);
  494               if (node == null) return;
  495               Node parent = node.getParentNode();
  496               if (parent == null) return;
  497   
  498               parent.removeChild(node);
  499       
  500               ((DefaultTreeModel)jtree.getModel()).removeNodeFromParent((MutableTreeNode)treeNode);
  501               return;
  502           } 
  503           
  504           if (e.getSource() == previousSiblingButton) {          
  505               Node node = treeWalker.previousSibling();
  506               handleButton(node, "previousSibling()");
  507               return;
  508           } 
  509           
  510           if (e.getSource() == firstChildButton) {          
  511               Node node = treeWalker.firstChild();
  512               handleButton(node, "firstChild()");
  513               return;
  514           } 
  515           
  516           if (e.getSource() == lastChildButton) {          
  517               Node node = treeWalker.lastChild();
  518               handleButton(node, "lastChild()");
  519               return;
  520           } 
  521           
  522           if (e.getSource() == nextSiblingButton) {          
  523               Node node = treeWalker.nextSibling();
  524               handleButton(node, "nextSibling()");
  525               return;
  526           } 
  527           
  528           if (e.getSource() == parentButton) {          
  529               Node node = treeWalker.parentNode();
  530               handleButton(node, "parentNode()");
  531               return;
  532           } 
  533           
  534           if (e.getSource() == nextButton) {          
  535               Node node = treeWalker.nextNode();
  536               handleButton(node, "nextNode()");
  537               return;
  538           } 
  539           
  540           if (e.getSource() == prevButton) {          
  541               Node node = treeWalker.previousNode();
  542               handleButton(node, "previousNode()");
  543               return;
  544           }
  545           
  546       }
  547       
  548       /** handle a button press: output messages and select node. */
  549       void handleButton( Node node, String function) {
  550           
  551           setMessage("treeWalker."+function+" == "+node);
  552      
  553           if (node==null) return;
  554   
  555           TreeNode treeNode = jtree.getTreeNode(node);
  556           if (treeNode == null) {
  557               setMessage("No JTree TreeNode for Node name:" + node.getNodeName());
  558               return;
  559           }
  560               
  561           TreePath path = new TreePath(
  562                   ((DefaultTreeModel)jtree.getModel()).getPathToRoot(treeNode));
  563           jtree.requestFocus();
  564           jtree.setSelectionPath(path);
  565           jtree.scrollPathToVisible(path);
  566       }
  567       
  568       /** Helper function to set messages */
  569       void setMessage(String string) {
  570           messageText.selectAll();
  571           messageText.cut();
  572           messageText.append(string);
  573           messageText.setCaretPosition(0);
  574       }
  575           
  576       /** called when our JTree's nodes are selected.
  577        */
  578       void nodeSelected(TreeNode treeNode) {
  579   
  580           lastSelected = treeNode;
  581           Node node = jtree.getNode(treeNode);
  582           
  583           if (node == null) return;
  584                               
  585           setMessage(DOMTreeFull.toString(node));
  586       }
  587       
  588       /** Utility function to expand the jtree */
  589       void expandTree() {
  590           for (int i = 0; i < jtree.getRowCount(); i++) {
  591               jtree.expandRow(i);
  592           }
  593       }
  594       
  595       class Errors implements ErrorHandler {
  596   
  597           Hashtable errorNodes = new Hashtable();
  598   
  599           public void warning(SAXParseException ex) {
  600               store(ex, "[Warning]");
  601           }
  602   
  603           public void error(SAXParseException ex) {
  604               store(ex, "[Error]");
  605           }
  606   
  607           public void fatalError(SAXParseException ex) throws SAXException {
  608               store(ex, "[Fatal Error]");
  609           }
  610   
  611           public Hashtable getErrorNodes() {
  612               return errorNodes;
  613           }
  614   
  615           public Object getError(Node node) {
  616               return errorNodes.get(node);
  617           }
  618   
  619           public void clearErrors() {
  620               errorNodes.clear();
  621           }
  622   
  623           void store(SAXParseException ex, String type) {
  624   
  625               // build error text
  626               String errorString= type+" at line number, "+ex.getLineNumber()
  627                   +": "+ex.getMessage()+"\n";
  628   
  629               Node currentNode = null;
  630               try {
  631                   currentNode = (Node)parser.getProperty("http://apache.org/xml/properties/dom-node");
  632               } catch (SAXException se) {
  633                   System.err.println(se.getMessage());
  634                   return;
  635               }
  636               if (currentNode == null) return;
  637   
  638               // accumulate any multiple errors per node in the Hashtable.
  639               String previous = (String) errorNodes.get(currentNode);
  640               if (previous != null)
  641                   errorNodes.put(currentNode, previous +errorString);
  642               else
  643                   errorNodes.put(currentNode, errorString);
  644           }
  645       }
  646       
  647   }

Save This Page
Home » Xerces-J-src.2.9.1 » dom » traversal » [javadoc | source]