001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.log4j.chainsaw; 018 019import java.awt.event.ActionEvent; 020import java.io.File; 021import java.io.IOException; 022import java.io.StringReader; 023import javax.swing.AbstractAction; 024import javax.swing.JFileChooser; 025import javax.swing.JFrame; 026import javax.swing.JOptionPane; 027import javax.xml.parsers.ParserConfigurationException; 028import javax.xml.parsers.SAXParserFactory; 029import org.apache.log4j.Logger; 030import org.xml.sax.InputSource; 031import org.xml.sax.SAXException; 032import org.xml.sax.XMLReader; 033 034/** 035 * Encapsulates the action to load an XML file. 036 * 037 * @author <a href="mailto:oliver@puppycrawl.com">Oliver Burn</a> 038 * @version 1.0 039 */ 040class LoadXMLAction 041 extends AbstractAction 042{ 043 /** use to log messages **/ 044 private static final Logger LOG = Logger.getLogger(LoadXMLAction.class); 045 046 /** the parent frame **/ 047 private final JFrame mParent; 048 049 /** 050 * the file chooser - configured to allow only the selection of a 051 * single file. 052 */ 053 private final JFileChooser mChooser = new JFileChooser(); 054 { 055 mChooser.setMultiSelectionEnabled(false); 056 mChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); 057 } 058 059 /** parser to read XML files **/ 060 private final XMLReader mParser; 061 /** the content handler **/ 062 private final XMLFileHandler mHandler; 063 064 065 /** 066 * Creates a new <code>LoadXMLAction</code> instance. 067 * 068 * @param aParent the parent frame 069 * @param aModel the model to add events to 070 * @exception SAXException if an error occurs 071 * @throws ParserConfigurationException if an error occurs 072 */ 073 LoadXMLAction(JFrame aParent, MyTableModel aModel) 074 throws SAXException, ParserConfigurationException 075 { 076 mParent = aParent; 077 mHandler = new XMLFileHandler(aModel); 078 mParser = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); 079 mParser.setContentHandler(mHandler); 080 } 081 082 /** 083 * Prompts the user for a file to load events from. 084 * @param aIgnore an <code>ActionEvent</code> value 085 */ 086 public void actionPerformed(ActionEvent aIgnore) { 087 LOG.info("load file called"); 088 if (mChooser.showOpenDialog(mParent) == JFileChooser.APPROVE_OPTION) { 089 LOG.info("Need to load a file"); 090 final File chosen = mChooser.getSelectedFile(); 091 LOG.info("loading the contents of " + chosen.getAbsolutePath()); 092 try { 093 final int num = loadFile(chosen.getAbsolutePath()); 094 JOptionPane.showMessageDialog( 095 mParent, 096 "Loaded " + num + " events.", 097 "CHAINSAW", 098 JOptionPane.INFORMATION_MESSAGE); 099 } catch (Exception e) { 100 LOG.warn("caught an exception loading the file", e); 101 JOptionPane.showMessageDialog( 102 mParent, 103 "Error parsing file - " + e.getMessage(), 104 "CHAINSAW", 105 JOptionPane.ERROR_MESSAGE); 106 } 107 } 108 } 109 110 /** 111 * Loads the contents of file into the model 112 * 113 * @param aFile the file to extract events from 114 * @return the number of events loaded 115 * @throws SAXException if an error occurs 116 * @throws IOException if an error occurs 117 */ 118 private int loadFile(String aFile) 119 throws SAXException, IOException 120 { 121 synchronized (mParser) { 122 // Create a dummy document to parse the file 123 final StringBuffer buf = new StringBuffer(); 124 buf.append("<?xml version=\"1.0\" standalone=\"yes\"?>\n"); 125 buf.append("<!DOCTYPE log4j:eventSet "); 126 buf.append("[<!ENTITY data SYSTEM \"file:///"); 127 buf.append(aFile); 128 buf.append("\">]>\n"); 129 buf.append("<log4j:eventSet xmlns:log4j=\"Claira\">\n"); 130 buf.append("&data;\n"); 131 buf.append("</log4j:eventSet>\n"); 132 133 final InputSource is = 134 new InputSource(new StringReader(buf.toString())); 135 mParser.parse(is); 136 return mHandler.getNumEvents(); 137 } 138 } 139}