org.openmrs.module.logmanager.impl.LogManagerServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.openmrs.module.logmanager.impl.LogManagerServiceImpl.java

Source

/**
 * The contents of this file are subject to the OpenMRS Public License
 * Version 1.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://license.openmrs.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * Copyright (C) OpenMRS, LLC.  All Rights Reserved.
 */
package org.openmrs.module.logmanager.impl;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Appender;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.xml.Log4jEntityResolver;
import org.openmrs.api.APIException;
import org.openmrs.api.impl.BaseOpenmrsService;
import org.openmrs.module.Module;
import org.openmrs.module.ModuleFactory;
import org.openmrs.module.logmanager.Constants;
import org.openmrs.module.logmanager.LogManagerService;
import org.openmrs.module.logmanager.Preset;
import org.openmrs.module.logmanager.QueryField;
import org.openmrs.module.logmanager.db.LogManagerDAO;
import org.openmrs.module.logmanager.util.LogManagerUtils;
import org.openmrs.module.logmanager.util.PagingInfo;
import org.openmrs.util.OpenmrsUtil;
import org.w3c.dom.Document;

/**
 * Implementation of the log manager service
 */
public class LogManagerServiceImpl extends BaseOpenmrsService implements LogManagerService {

    protected static final Log log = LogFactory.getLog(LogManagerServiceImpl.class);

    protected LogManagerDAO dao;

    /**
     * Sets the database access object for this service
     * @param dao the database access object
     */
    public void setLogManagerDAO(LogManagerDAO dao) {
        this.dao = dao;
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#getLoggers(boolean)
     */
    public List<LoggerProxy> getLoggers(boolean incImplicit) {
        return ManagerProxy.getLoggers(incImplicit);
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#getLoggers(String, int)
     */
    public List<LoggerProxy> getLoggers(String prefix, int limit) {
        return ManagerProxy.getLoggers(prefix, limit);
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#getAppender(int)
     */
    public AppenderProxy getAppender(int id) throws APIException {
        return ManagerProxy.getAppender(id);
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#getAppenders()
     */
    public Collection<AppenderProxy> getAppenders(boolean sorted) {
        Set<AppenderProxy> appenders = ManagerProxy.getAppenders();

        // Optionally sort into a list
        if (sorted) {
            List<AppenderProxy> appenderList = new ArrayList<AppenderProxy>(appenders);
            Collections.sort(appenderList, new Comparator<AppenderProxy>() {
                public int compare(AppenderProxy ap1, AppenderProxy ap2) {
                    String s1 = ap1.getName() != null ? ap1.getName() : "";
                    String s2 = ap2.getName() != null ? ap2.getName() : "";
                    return s1.compareToIgnoreCase(s2);
                }
            });
            return appenderList;
        } else
            return appenders;
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#addAppender(org.openmrs.module.logmanager.impl.AppenderProxy, java.lang.String)
     */
    public void addAppender(AppenderProxy appender, String loggerName) throws APIException {

        if (loggerName == null)
            LogManager.getRootLogger().addAppender(appender.getTarget());
        else
            LogManager.getLogger(loggerName).addAppender(appender.getTarget());
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#deleteAppender(AppenderProxy)
     */
    @SuppressWarnings("unchecked")
    public void deleteAppender(AppenderProxy appender) throws APIException {
        // Get all loggers
        Enumeration<Logger> loggersEnum = (Enumeration<Logger>) LogManager.getCurrentLoggers();

        // Remove from root logger
        LogManager.getRootLogger().removeAppender(appender.getTarget());

        // Remove appender from all other loggers
        while (loggersEnum.hasMoreElements()) {
            Logger logger = loggersEnum.nextElement();
            logger.removeAppender(appender.getTarget());
        }

        // Close appender to release resources
        appender.getTarget().close();
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#getAppenderEvents(Appender, Level, int, QueryField, String, Paging)
     */
    public List<EventProxy> getAppenderEvents(AppenderProxy appender, LevelProxy level, int levelOp,
            QueryField queryField, String queryValue, PagingInfo paging) throws APIException {

        Collection<LoggingEvent> eventsAll = appender.getLoggingEvents();
        List<EventProxy> events = new LinkedList<EventProxy>();

        for (LoggingEvent event : eventsAll) {
            if (level != null && !testLevel(new LevelProxy(event.getLevel()), levelOp, level))
                continue;

            if (queryValue != null) {
                switch (queryField) {
                case LOGGER_NAME:
                    if (!event.getLoggerName().contains(queryValue))
                        continue;
                    break;
                case CLASS_NAME:
                    if (!event.locationInformationExists()
                            || !event.getLocationInformation().getClassName().contains(queryValue))
                        continue;
                    break;
                case FILE_NAME:
                    if (!event.locationInformationExists()
                            || !event.getLocationInformation().getFileName().contains(queryValue))
                        continue;
                    break;
                }
            }

            events.add(0, new EventProxy(event));
        }

        if (paging != null)
            // Select only the events for this page
            return selectListPage(events, paging);

        return events;
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#getAppenderEvent(org.openmrs.module.logmanager.impl.AppenderProxy, int)
     */
    public EventProxy getAppenderEvent(AppenderProxy appender, int id) {
        return getAppenderEvent(appender, id, null, 0);
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#getAppenderEvent(AppenderProxy, int, List, int)
     */
    public EventProxy getAppenderEvent(AppenderProxy appender, int id, List<EventProxy> contextEvents,
            int contextCount) throws APIException {
        Collection<LoggingEvent> events = appender.getLoggingEvents();
        LoggingEvent prevEvent = null;

        for (Iterator<LoggingEvent> iter = events.iterator(); iter.hasNext();) {
            LoggingEvent e = iter.next();

            if (e.hashCode() == id) {
                if (contextEvents != null) {
                    // Add next n events in list
                    if (contextEvents != null && contextCount > 0)
                        for (; iter.hasNext() && contextEvents.size() <= contextCount;)
                            contextEvents.add(new EventProxy(iter.next()));
                    // And previous and next events
                    else if (contextCount == -1) {
                        contextEvents.add(iter.hasNext() ? new EventProxy(iter.next()) : null);
                        contextEvents.add(prevEvent != null ? new EventProxy(prevEvent) : null);
                    }
                }

                return new EventProxy(e);
            }

            prevEvent = e;
        }
        return null;
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#updateAppender(AppenderProxy)
     */
    public void updateAppender(AppenderProxy appender) {
        // Ensure appender exists and is synced with proxy
        appender.updateTarget();

        // Some appenders require initialising after options have been loaded
        if (appender.isActivationRequired())
            appender.activate();
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#getPreset(int)
     */
    public Preset getPreset(int presetId) throws APIException {
        return dao.getPreset(presetId);
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#getPresets()
     */
    public List<Preset> getPresets() throws APIException {
        return dao.getPresets();
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#savePreset(Preset)
     */
    public void saveCurrentLoggersAsPreset(Preset preset) throws APIException {
        Map<String, Integer> loggerMap = preset.getLoggerMap();
        loggerMap.clear();

        // Add root logger to map
        LoggerProxy rootLogger = ManagerProxy.getRootLogger();
        loggerMap.put("ROOT", rootLogger.getLevelInt());

        // Add all other loggers
        List<LoggerProxy> loggers = getLoggers(false);
        for (LoggerProxy logger : loggers)
            loggerMap.put(logger.getName(), logger.getLevelInt());

        dao.savePreset(preset);
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#activatePreset(org.openmrs.module.logmanager.Preset)
     */
    public void activatePreset(Preset preset) throws APIException {
        // Nullify all existing loggers
        for (LoggerProxy logger : getLoggers(false))
            logger.makeImplicit(false);

        // Activate each loggers from preset
        for (Map.Entry<String, Integer> entry : preset.getLoggerMap().entrySet()) {
            String name = entry.getKey();
            LevelProxy level = new LevelProxy(entry.getValue());

            // Check for root logger
            if (name.equals("ROOT")) {
                LoggerProxy rootLogger = ManagerProxy.getRootLogger();
                rootLogger.setLevel(level);
                rootLogger.updateTarget();
            } else {
                LoggerProxy logger = new LoggerProxy(name, level);
                logger.updateTarget();
            }
        }
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#deletePreset(Preset)
     */
    public void deletePreset(Preset preset) throws APIException {
        dao.deletePreset(preset);
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#saveConfiguration()
     */
    public void clearConfiguration() throws APIException {
        ConfigurationManager.clearConfiguration();
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#saveConfiguration()
     */
    public void saveConfiguration() throws APIException {
        try {
            String path = OpenmrsUtil.getApplicationDataDirectory() + File.separator
                    + Constants.EXTERNAL_CONFIG_NAME;
            FileWriter writer = new FileWriter(path);

            Document document = ConfigurationBuilder.currentConfiguration();
            LogManagerUtils.writeDocument(document, writer);

            writer.close();

        } catch (IOException e) {
            throw new APIException("Unable to save external logging configuration", e);
        }
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#loadConfiguration()
     */
    public void loadConfiguration() throws APIException {
        String path = OpenmrsUtil.getApplicationDataDirectory() + File.separator + Constants.EXTERNAL_CONFIG_NAME;

        Document document = ConfigurationManager.readConfiguration(path);
        if (document != null)
            ConfigurationManager.parseConfiguration(document);
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#loadConfiguration(org.w3c.dom.Document)
     */
    public void loadConfiguration(Document document) throws APIException {
        ConfigurationManager.parseConfiguration(document);
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#loadConfigurationFromSource()
     */
    public void loadConfigurationFromSource() throws APIException {
        try {
            URL url = LogManagerServiceImpl.class.getResource("/" + Constants.INTERNAL_CONFIG_NAME);

            // Read as document
            Reader reader = new InputStreamReader(url.openStream());
            Document document = LogManagerUtils.readDocument(reader, new Log4jEntityResolver());
            reader.close();

            ConfigurationManager.parseConfiguration(document);
        } catch (Exception e) {
            throw new APIException("Unable to read internal logging configuration", e);
        }
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#loadConfigurationFromModules(java.lang.String[])
     */
    public void loadConfigurationFromModules(String[] moduleIds) throws APIException {
        // Load from each specified module
        for (String moduleId : moduleIds) {
            try {
                Module module = ModuleFactory.getModuleById(moduleId);
                Document log4jDoc = module.getLog4j();
                if (module.getLog4j() != null)
                    ConfigurationManager.parseConfiguration(log4jDoc);
            } catch (Exception e) {
                log.error(e);
            }
        }
    }

    /**
     * @see org.openmrs.module.logmanager.LogManagerService#getMySQLVersion()
     */
    public String getMySQLVersion() throws APIException {
        return dao.getMySQLVersion();
    }

    /**
     * Selects a range of elements from a list
     * @param <T> the type of each list element
     * @param list the list to select from
     * @return a new list containing only those list elements in the current page
     */
    private static <T> List<T> selectListPage(List<T> list, PagingInfo paging) {
        List<T> selection = new ArrayList<T>();

        int lStart = Math.max(0, Math.min(paging.getPageOffset(), list.size()));
        int lEnd = Math.max(0, Math.min(paging.getPageOffset() + paging.getPageSize(), list.size()));
        for (int l = lStart; l < lEnd; l++)
            selection.add(list.get(l));

        paging.setResultsTotal(list.size());

        return selection;
    }

    /**
     * Compares two level values with a given boolean operator 
     * @param level1 the first level value
     * @param levelOp the boolean operator (-1: LE, 0: EQ, 1: GE)
     * @param level2 the second level value
     * @return value of the comparison
     */
    private boolean testLevel(LevelProxy level1, int levelOp, LevelProxy level2) {
        if (level1.getIntValue() == LevelProxy.ALL.getIntValue()
                || level2.getIntValue() == LevelProxy.ALL.getIntValue())
            return true;

        switch (levelOp) {
        case Constants.BOOL_OP_LE:
            return (level1.getIntValue() <= level2.getIntValue());
        case Constants.BOOL_OP_GE:
            return (level1.getIntValue() >= level2.getIntValue());
        default:
            return (level1.getIntValue() == level2.getIntValue());
        }
    }
}