/***********************************************************************
*
* $CVSHeader$
*
* This file is part of WebScarab, an Open Web Application Security
* Project utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2004 Rogan Dawes
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source
* ==============
*
* Source for this application is maintained at Sourceforge.net, a
* repository for free software projects.
*
* For details, please see http://www.sourceforge.net/projects/owasp
*
*/
/*
* XMLPanel.java
*
* Created on November 4, 2003, 8:23 AM
*/
package org.owasp.webscarab.ui.swing.editors;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.DefaultMutableTreeNode;
import org.owasp.webscarab.util.swing.TreeUtil;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.awt.Component;
import javax.swing.JTree;
import org.owasp.webscarab.util.swing.MultiLineTreeCellRenderer;
import org.owasp.webscarab.util.swing.DOMTreeModel;
import org.ccil.cowan.tagsoup.Parser;
import org.owasp.webscarab.util.DOMHandler;
import org.xml.sax.InputSource;
/**
*
* @author rdawes
*/
public class XMLPanel extends javax.swing.JPanel implements ByteArrayEditor {
/**
*
*/
private static final long serialVersionUID = -244729718376716387L;
private boolean _editable = false;
private boolean _modified = false;
private byte[] _data = new byte[0];
/** Creates new form XMLPanel */
public XMLPanel() {
initComponents();
setName("XML");
xmlTree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode("No content")));
xmlTree.setCellRenderer(new XMLTreeNodeRenderer());
}
public void setEditable(boolean editable) {
}
public void setBytes(String contentType, byte[] bytes) {
_data = bytes;
if (bytes != null) {
InputStream is = new ByteArrayInputStream(bytes);
Element rootElement = null;
try {
Document document = null;
if (contentType.matches("text/xml.*")) {
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setIgnoringElementContentWhitespace(true);
DocumentBuilder builder = builderFactory.newDocumentBuilder();
document = builder.parse(is);
} else if (contentType.matches("text/html.*")) {
DOMHandler domHandler = new DOMHandler();
Parser parser = new Parser();
parser.setContentHandler(domHandler);
parser.parse(new InputSource(is));
document = domHandler.getDocument();
}
if (document != null) {
document.getDocumentElement().normalize();
rootElement = document.getDocumentElement();
TreeModel tm = new DOMTreeModel(rootElement);
xmlTree.setModel(tm);
} else {
xmlTree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode("Invalid content")));
}
} catch (Exception e) {
xmlTree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode("Error: " + e.getMessage())));
e.printStackTrace();
}
} else {
xmlTree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode("No elements")));
}
TreeUtil.expandAll(xmlTree, true);
}
public boolean isModified() {
return _editable && _modified;
}
public byte[] getBytes() {
return _data;
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
private void initComponents() {
treeScrollPane = new javax.swing.JScrollPane();
xmlTree = new javax.swing.JTree();
setLayout(new java.awt.BorderLayout());
treeScrollPane.setViewportView(xmlTree);
add(treeScrollPane, java.awt.BorderLayout.CENTER);
}
// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JScrollPane treeScrollPane;
private javax.swing.JTree xmlTree;
// End of variables declaration//GEN-END:variables
private class XMLTreeNodeRenderer extends MultiLineTreeCellRenderer {
/**
*
*/
private static final long serialVersionUID = 4591128488009949423L;
/** Creates a new instance of UrlTreeRenderer */
public XMLTreeNodeRenderer() {
}
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
if (value instanceof Node) {
Node node = (Node) value;
String text = value.toString();
int type = node.getNodeType();
// System.out.println("Type: " + type + ": " + node.toString());
switch (type) {
case Node.ATTRIBUTE_NODE: text = "ATTRIBUTE_NODE"; break;
case Node.CDATA_SECTION_NODE: text = "CDATA_SECTION_NODE"; break;
case Node.COMMENT_NODE: text = "COMMENT_NODE"; break;
case Node.ELEMENT_NODE:
text = "<" + node.getNodeName();
NamedNodeMap nnm = node.getAttributes();
if (nnm.getLength()>0) {
StringBuffer buff = new StringBuffer();
Node attr = nnm.item(0);
buff.append(attr.getNodeName()).append("=\"").append(attr.getNodeValue()).append("\"");
for (int i=1; i<nnm.getLength();i++) {
attr = nnm.item(i);
buff.append(" ").append(attr.getNodeName()).append("=\"").append(attr.getNodeValue()).append("\"");
}
text = text + " " + buff.toString();
}
text = text + ">";
break;
case Node.TEXT_NODE: text = node.getNodeValue(); break;
default: value = "Type: " + node.getNodeType() + node.toString();
}
value = text.trim();
}
return super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
}
}
public static void main(String[] args) throws Exception {
javax.swing.JFrame top = new javax.swing.JFrame("XML Editor");
top.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
System.exit(0);
}
});
byte[] bytes;
if (args.length > 0) {
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
InputStream is = new java.io.FileInputStream(args[0]);
byte[] buff = new byte[1024];
int got;
while ((got = is.read(buff)) > 0) {
baos.write(buff,0,got);
}
bytes = baos.toByteArray();
} else {
bytes = ("<b>NOTE: For security reasons, using the administration webapp\n" +
" is restricted to users with role \"admin\". The manager webapp\n" +
"is restricted to users with role \"manager\".</b>").getBytes();
}
XMLPanel xp = new XMLPanel();
top.getContentPane().add(xp);
top.setBounds(100,100,600,400);
try {
xp.setBytes("text/xml",bytes);
xp.setEditable(true);
top.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
}