001/*
002 *  Copyright 2015 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.runtime.plugins.admin.logs;
017
018import java.util.ArrayList;
019import java.util.Collections;
020import java.util.Enumeration;
021import java.util.HashMap;
022import java.util.HashSet;
023import java.util.List;
024import java.util.Map;
025import java.util.Set;
026
027import org.apache.avalon.framework.parameters.Parameters;
028import org.apache.cocoon.acting.ServiceableAction;
029import org.apache.cocoon.environment.ObjectModelHelper;
030import org.apache.cocoon.environment.Redirector;
031import org.apache.cocoon.environment.Request;
032import org.apache.cocoon.environment.SourceResolver;
033import org.apache.commons.lang3.StringUtils;
034import org.apache.log4j.Level;
035import org.apache.log4j.LogManager;
036import org.apache.log4j.Logger;
037import org.apache.log4j.spi.LoggerRepository;
038
039import org.ametys.core.cocoon.JSonReader;
040
041/**
042 * Get the log levels' 
043 */
044@SuppressWarnings("unchecked")
045public class GetLogsLevel extends ServiceableAction
046{
047    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
048    {
049        Request request = ObjectModelHelper.getRequest(objectModel);
050        Map<String, Object> result = new HashMap<> ();
051        
052        try
053        {
054            LoggerRepository loggerRepository = LogManager.getLoggerRepository();
055            List<Logger> loggers = new ArrayList<>();
056            Enumeration<org.apache.log4j.Logger> enumLogger = loggerRepository.getCurrentLoggers();
057            
058            while (enumLogger.hasMoreElements())
059            {
060                loggers.add(enumLogger.nextElement());
061            }
062            
063            loggers.add(loggerRepository.getRootLogger());
064            
065            Collections.sort(loggers, new LoggerComparator());
066            
067            Map<String, Object> logCategories = new HashMap<>();
068            Set<Map<String, String>> categoryLevels = new HashSet<> ();
069            
070            for (Logger logger : loggers)
071            {
072                Level level = logger.getLevel();
073
074                String category = logger.getName();
075                if (category.equals("root"))
076                {
077                    logCategories.put("children", new ArrayList<> ());
078                    logCategories.put("name", "root");
079                    logCategories.put("fullname", "root");
080                    logCategories.put("level", level.toString());
081                }
082                else
083                {
084                    Map<String, String> categoryLevel = new HashMap<>();
085                    categoryLevel.put("category", category);
086                    categoryLevel.put("level", level == null ? "inherit" : level.toString());
087                    categoryLevels.add(categoryLevel);
088                }
089            }
090
091            String fullName = null;
092            for (Map<String, String> categoryLevel : categoryLevels)
093            {
094                fullName = categoryLevel.get("category");
095                createCategory((List<Map<String, Object>>) logCategories.get("children"), fullName, categoryLevel.get("level"), fullName);
096            }
097            
098            result.put("children", logCategories);
099        }
100        catch (Exception e) 
101        {
102             // nothing to do
103            getLogger().warn("Unable to access internal logger properties", e);
104        }
105        
106        request.setAttribute(JSonReader.OBJECT_TO_READ, result);
107        return EMPTY_MAP;
108    }
109    
110    /**
111     * Creates a log category 
112     * @param children the list of categories already created
113     * @param categoryName the name of the category to create
114     * @param level the level of the category to create
115     * @param fullName the full name of the category
116     */
117    public void createCategory(List<Map<String, Object>> children, String categoryName, String level, String fullName)
118    {
119        int i = categoryName.indexOf(".");
120        if (i != -1)
121        {
122            // Creates intermediary tree nodes
123            String parentCategoryName = categoryName.substring(0, i);
124            String childCategoryName = categoryName.substring(i + 1);
125            
126            Map<String, Object> parentCategoryNode = _getNode(children, parentCategoryName);
127            
128            if (parentCategoryNode == null)
129            {
130                // We did not find any existing node, let's create it
131                parentCategoryNode = new HashMap<> ();
132                parentCategoryNode.put("children", new ArrayList<> ());
133                parentCategoryNode.put("leaf", false);
134                parentCategoryNode.put("level", "inherit");
135                parentCategoryNode.put("name", parentCategoryName);
136                parentCategoryNode.put("fullname", fullName.substring(0, fullName.indexOf(parentCategoryName)) + parentCategoryName);
137                
138                children.add(parentCategoryNode);
139            }
140            
141            parentCategoryNode.put("leaf", false);
142            
143            createCategory((List<Map<String, Object>>) parentCategoryNode.get("children"), childCategoryName, level, fullName);
144        }
145        else
146        {
147            Map<String, Object> categoryNode = _getNode(children, categoryName);
148            if (categoryNode == null)
149            {
150                // Creates tree leaves
151                categoryNode = new HashMap<> ();
152                
153                categoryNode.put("children", new ArrayList<> ());
154                categoryNode.put("leaf", true);
155                categoryNode.put("level", level);
156                categoryNode.put("name", categoryName);
157                categoryNode.put("fullname", fullName);
158    
159                children.add(categoryNode);
160            }
161            else
162            {
163                // The intermediary node was already created, let's update it
164                categoryNode.put("level", level);
165            }
166        }
167    }
168    
169    private Map<String, Object> _getNode(List<Map<String, Object>> children, String categoryName)
170    {
171        for (Map<String, Object> child : children)
172        {
173            if (StringUtils.equals((String) child.get("name"), categoryName))
174            {
175                return child;
176            }
177        }
178        return null;
179    }
180}