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.io.IOException;
019import java.util.ArrayList;
020import java.util.Collection;
021import java.util.Date;
022import java.util.HashMap;
023import java.util.List;
024import java.util.Map;
025import java.util.regex.Matcher;
026import java.util.regex.Pattern;
027
028import org.apache.cocoon.ProcessingException;
029import org.apache.cocoon.generation.ServiceableGenerator;
030import org.apache.cocoon.xml.XMLUtils;
031import org.apache.excalibur.source.SourceException;
032import org.apache.excalibur.source.TraversableSource;
033import org.xml.sax.SAXException;
034
035import org.ametys.runtime.parameter.ParameterHelper;
036
037/**
038 * SAXes the list of logs
039 */
040public class LogsGenerator extends ServiceableGenerator
041{
042    private static final Pattern __DATED_LOG_FILENAME = Pattern.compile("(.*)[-_]\\d{4}[-_]\\d{2}[-_]\\d{2}.*\\.log");
043    
044    public void generate() throws IOException, SAXException, ProcessingException
045    {
046        contentHandler.startDocument();
047        XMLUtils.startElement(contentHandler, "logs");
048        _logs();
049        XMLUtils.endElement(contentHandler, "logs");
050        contentHandler.endDocument();
051    }
052    
053    private void _logs() throws IOException, SAXException
054    {
055        TraversableSource logsDirectorySource = (TraversableSource) resolver.resolveURI("ametys-home://logs");
056        
057        try
058        {
059            Map<String, List<TraversableSource>> logs = _prepareLogs(logsDirectorySource);
060            
061            for (String logname : logs.keySet())
062            {
063                List<TraversableSource> logSources = logs.get(logname);
064                for (TraversableSource logSource : logSources)
065                {
066                    XMLUtils.startElement(contentHandler, "log");
067                    XMLUtils.createElement(contentHandler, "name", logname);
068                    XMLUtils.createElement(contentHandler, "location", logSource.getURI().substring(logSource.getURI().lastIndexOf('/') + 1));
069                    XMLUtils.createElement(contentHandler, "lastModified", ParameterHelper.valueToString(new Date(logSource.getLastModified())));
070                    XMLUtils.createElement(contentHandler, "size", Long.toString(logSource.getContentLength()));
071                    XMLUtils.endElement(contentHandler, "log");
072                }
073                
074            }
075        }
076        finally
077        {
078            resolver.release(logsDirectorySource);
079        }
080    }
081    
082    private Map<String, List<TraversableSource>> _prepareLogs(TraversableSource logsDirectorySource) throws SourceException
083    {
084        Map<String, List<TraversableSource>> logs = new HashMap<>();
085        
086        if (logsDirectorySource.exists())
087        {
088            Collection<TraversableSource> logFiles = logsDirectorySource.getChildren();
089            for (TraversableSource logSource : logFiles)
090            {
091                if (!logSource.isCollection())
092                {
093                    String name = logSource.getName();
094                    String canonicalName = _getCanonicalName(name);
095                    
096                    if (canonicalName != null)
097                    {
098                        List<TraversableSource> underLogs = logs.get(canonicalName);
099                        if (underLogs == null)
100                        {
101                            underLogs = new ArrayList<>();
102                            logs.put(canonicalName, underLogs);
103                        }
104                        
105                        underLogs.add(logSource);
106                    }
107                }
108            }
109        }
110        
111        return logs;
112    }
113
114    private String _getCanonicalName(String name)
115    {
116        Matcher matcher = __DATED_LOG_FILENAME.matcher(name);
117        if (matcher.matches())
118        {
119            return matcher.group(1);
120        }
121        else if (name.endsWith(".log"))
122        {
123            return name;
124        }
125        else
126        {
127            return null;
128        }
129    }
130}