/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *    "Apache Jetspeed" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    "Apache Jetspeed", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
package org.apache.jetspeed.modules.actions.portlets;

// Java classes
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

import java.util.Enumeration;
import java.util.HashMap;

// Log4J classes
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import org.apache.log4j.Appender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.spi.LoggerRepository;

// Turbine classes
import org.apache.turbine.util.RunData;

// Velocity classes
import org.apache.velocity.context.Context;

// Jetspeed classes
import org.apache.jetspeed.portal.Portlet;

/**
 * This class is the action class for a portlet that lets you view the Log4J 
 * logfiles defined in your Jetspeed installation.<br/>
 * the portlet iterates through the Log4J appender defined that are of type 
 * FileAppender or its subclasses, and lists the filenames in a listbox.<br/>
 *
 * The portlet puts the following in the context:<br/>
 * <code>appenders</code> - a HashMap with the appenders found<br/>
 * <code>files</code> - a HashMap with the filenames without path<br/>
 * <code>logfile</code> - the content of the file indicated by <code>selectedfile</code><br/>
 * 
 * 
 * @author <a href="mailto:harald@ommang.com">Harald Ommang</a>
 * @version $Id: LogfileViewerAction.java,v 1.2 2003/08/28 20:32:42 taylor Exp $
 */
public class LogfileViewerAction extends GenericMVCAction
{
    /**
     * Static initialization of the logger for this class
     */    
     private static final Logger logger = LogManager.getLogger(LogfileViewerAction.class.getName());

     private static HashMap appenders = null;

    /** Creates a new instance of LogFileViewerAction */
    public LogfileViewerAction() 
    {
    }
    
    /** 
     * Lists the current logfiles
     * @param portlet The current portlet
     * @param context the current portlet context
     * @paran rundata the Turbine rundata
     *
     */
    protected void buildNormalContext(Portlet portlet, Context context, RunData rundata) throws Exception 
    {
        String tempName;
        LoggerRepository repos = logger.getLoggerRepository();
        Enumeration loggerEnum = repos.getCurrentLoggers();
        HashMap files = new HashMap();
        HashMap fileNames = new HashMap();
        appenders = new HashMap();
        
        while ( loggerEnum.hasMoreElements() )
        {
            Logger appLogger = (Logger) loggerEnum.nextElement();
            Enumeration appenderEnum = appLogger.getAllAppenders();
            String name;

            while ( appenderEnum.hasMoreElements() )
            {
                Appender appender = (Appender) appenderEnum.nextElement();
                if (appender instanceof FileAppender)
                {
                    name = appender.getName();
                    tempName = ((FileAppender)appender).getFile();
                    tempName = tempName.substring(tempName.lastIndexOf(System.getProperty("file.separator")) + 1);
                    if (name == null)
                    {
                        name = tempName;
                        appender.setName(name);
                    }
 
                    if (logger.isDebugEnabled())
                    {
                        logger.debug("AppenderName " + name);
                    }
                    appenders.put(name, appender);
                    files.put(name, tempName);
                }
            }
        }        
        context.put("appenders", appenders.values());
        context.put("files", files);
    }
    
    /** 
     * If a file is selected, it's contents is put in "logfile"
     * @paran rundata the Turbine rundata
     * @param context the current portlet context
     *
     */    
    public void doUpdate(RunData data, Context context)
    {
        try 
        {        
            String fileName = data.getParameters().getString("selectedfile");
            logger.debug("selectedfile: " + fileName);
            if (fileName != null)
            {
                String content = readFile(fileName);
                context.put("logfile", content);
            }
            else
            {
                context.put("logfile", null);
            }
        }
        catch (Exception ex)
        {
            logger.error("Exception in viewing logfile: ", ex);
        }
    }

    /** 
     * Reads the contents of a file and returns in \n separated lines.
     * @paran filename Name of file to read
     *
     */        
    private String readFile (String filename) 
    {
        StringBuffer buf = new StringBuffer("");
        try 
        {
            String line;
            BufferedReader in = new BufferedReader(new FileReader(filename));
            while ((line = in.readLine()) != null) 
            {
                buf.append(line + "\n");
            }
            in.close();
        } 
        catch (IOException ioe) 
        {
            logger.error("Error reading file " + filename, ioe);
        }
        return buf.toString();
    } // readFile
    
} // class LogfileViewerAction
