org.apache.log4j.chainsaw.LoadXMLAction Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.chainsaw;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import javax.swing.AbstractAction;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import org.apache.log4j.Logger;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
/**
* Encapsulates the action to load an XML file.
*
* @author Oliver Burn
* @version 1.0
*/
class LoadXMLAction extends AbstractAction {
/**
* use to log messages
**/
private static final Logger LOG = Logger.getLogger(LoadXMLAction.class);
/**
* the parent frame
**/
private final JFrame mParent;
/**
* the file chooser - configured to allow only the selection of a single file.
*/
private final JFileChooser mChooser = new JFileChooser();
{
mChooser.setMultiSelectionEnabled(false);
mChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
}
/**
* parser to read XML files
**/
private final XMLReader mParser;
/**
* the content handler
**/
private final XMLFileHandler mHandler;
/**
* Creates a new LoadXMLAction
instance.
*
* @param aParent the parent frame
* @param aModel the model to add events to
* @throws SAXException if an error occurs
* @throws ParserConfigurationException if an error occurs
*/
LoadXMLAction(JFrame aParent, MyTableModel aModel) throws SAXException, ParserConfigurationException {
mParent = aParent;
mHandler = new XMLFileHandler(aModel);
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
// prevent XXE attacks
saxParserFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
saxParserFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
mParser = saxParserFactory.newSAXParser().getXMLReader();
mParser.setContentHandler(mHandler);
}
/**
* Prompts the user for a file to load events from.
*
* @param aIgnore an ActionEvent
value
*/
public void actionPerformed(ActionEvent aIgnore) {
LOG.info("load file called");
if (mChooser.showOpenDialog(mParent) == JFileChooser.APPROVE_OPTION) {
LOG.info("Need to load a file");
final File chosen = mChooser.getSelectedFile();
LOG.info("loading the contents of " + chosen.getAbsolutePath());
try {
final int num = loadFile(chosen.getAbsolutePath());
JOptionPane.showMessageDialog(mParent, "Loaded " + num + " events.", "CHAINSAW",
JOptionPane.INFORMATION_MESSAGE);
} catch (Exception e) {
LOG.warn("caught an exception loading the file", e);
JOptionPane.showMessageDialog(mParent, "Error parsing file - " + e.getMessage(), "CHAINSAW",
JOptionPane.ERROR_MESSAGE);
}
}
}
/**
* Loads the contents of file into the model
*
* @param aFile the file to extract events from
* @return the number of events loaded
* @throws SAXException if an error occurs
* @throws IOException if an error occurs
*/
private int loadFile(String aFile) throws SAXException, IOException {
synchronized (mParser) {
// Create a dummy document to parse the file
final StringBuilder buf = new StringBuilder();
buf.append("\n");
buf.append("]>\n");
buf.append("\n");
buf.append("&data;\n");
buf.append(" \n");
final InputSource is = new InputSource(new StringReader(buf.toString()));
mParser.parse(is);
return mHandler.getNumEvents();
}
}
}