001/*
002 *  Copyright 2016 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.core.util;
017
018import java.lang.management.ManagementFactory;
019import java.util.Collection;
020import java.util.HashSet;
021import java.util.Map;
022import java.util.Set;
023
024import org.apache.avalon.framework.component.Component;
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.avalon.framework.service.Serviceable;
028import org.apache.commons.collections.CollectionUtils;
029import org.apache.commons.lang3.StringUtils;
030
031import org.ametys.core.ui.Callable;
032import org.ametys.core.version.Version;
033import org.ametys.core.version.VersionsHandler;
034
035/**
036 * Component that centralizes and provides the system status
037 */
038public class SystemStatus implements Component, Serviceable
039{
040    /** The Avalon Role */
041    public static final String ROLE = SystemStatus.class.getName();
042    
043    private Set<String> _systemStatus = new HashSet<>();
044
045    private VersionsHandler _versionHandler;
046
047    private Map<String, Object> _infos;
048    
049    public void service(ServiceManager manager) throws ServiceException
050    {
051        _versionHandler = (VersionsHandler) manager.lookup(VersionsHandler.ROLE);
052    }
053    
054    /**
055     * Get info about the current system status
056     * @return a map of info
057     */
058    @Callable(rights = Callable.NO_CHECK_REQUIRED)
059    public Map<String, Object> getInfo()
060    {
061        if (_infos == null)
062        {
063            _infos = Map.of(
064                "version", getVersion(),
065                "status", _systemStatus,    // pass the set directly so that the reference is constant but the value is updated when necessary
066                "startupTime", ManagementFactory.getRuntimeMXBean().getStartTime()
067            );
068        }
069        
070        return _infos;
071    }
072
073    private int getVersion()
074    {
075        StringBuffer value = new StringBuffer();
076        
077        Collection<Version> versions = _versionHandler.getVersions();
078        for (Version version : versions)
079        {
080            if (value.length() > 0)
081            {
082                value.append(" / ");
083            }
084            
085            value.append(version.getName());
086            
087            if (StringUtils.isNotBlank(version.getVersion()))
088            {
089                value.append(" - ");
090                value.append(version.getVersion());
091            }
092            
093            if (version.getDate() != null)
094            {
095                value.append(" - ");
096                value.append(Long.toString(version.getDate().getTime()));
097            }
098        }
099        
100        return value.toString().hashCode();
101    }
102    
103    /**
104     * Returns the system status
105     * @return The collection of system status
106     */
107    public Collection<String> getStatus()
108    {
109        return CollectionUtils.unmodifiableCollection(_systemStatus);
110    }
111    
112    /**
113     * Add a system status
114     * @param status The system status to add
115     * @return <code>true</code> if the system status did not already contain the specified status
116     */
117    public boolean addStatus(String status)
118    {
119        return _systemStatus.add(status);
120    }
121    
122    /**
123     * Add a system status
124     * @param status The system status to remove
125     * @return <code>true</code> if the system status contained the specified element
126     */
127    public boolean removeStatus(String status)
128    {
129        return _systemStatus.remove(status);
130    }
131}