Added softwares and software page.

This commit is contained in:
Christian P. MOMON 2020-09-25 15:46:30 +02:00
parent 01df6b63c0
commit 344e1bfa1c
20 changed files with 1355 additions and 11 deletions

View file

@ -37,6 +37,43 @@ public class Categories extends ArrayList<Category>
super(); super();
} }
/**
* Find by software.
*
* @param name
* the name
* @return the category
*/
public Category findBySoftware(final String softwareName)
{
Category result;
boolean ended = false;
Iterator<Category> iterator = this.iterator();
result = null;
while (!ended)
{
if (iterator.hasNext())
{
Category category = iterator.next();
if (category.getSoftwares().contains(softwareName))
{
ended = true;
result = category;
}
}
else
{
ended = true;
result = null;
}
}
//
return result;
}
/** /**
* Matches. * Matches.
* *

View file

@ -183,6 +183,35 @@ public class Federation extends PathPropertyList
return result; return result;
} }
/**
* Gets the software catalog.
*
* @return the software catalog
*/
public Softwares getSoftwares()
{
Softwares result;
result = new Softwares();
for (Service service : getAllServices())
{
if (StringUtils.isNotBlank(service.getSoftwareName()))
{
Software software = result.get(service.getSoftwareName());
if (software == null)
{
software = new Software(service.getSoftwareName(), service.get("software.description"));
result.put(software);
}
}
}
//
return result;
}
/** /**
* Gets the technical name. * Gets the technical name.
* *

View file

@ -21,6 +21,8 @@ package fr.devinsy.statoolinfos.core;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import org.apache.commons.lang3.StringUtils;
/** /**
* The Class Services. * The Class Services.
*/ */
@ -61,6 +63,33 @@ public class Services extends ArrayList<Service>
return result; return result;
} }
/**
* Gets the by.
*
* @param software
* the software
* @return the by
*/
public Services getBy(final Software software)
{
Services result;
result = new Services();
for (Service service : this)
{
String serviceSoftwareName = StatoolInfosUtils.toTechnicalName(service.getSoftwareName());
String softwareName = StatoolInfosUtils.toTechnicalName(software.getName());
if (StringUtils.equals(serviceSoftwareName, softwareName))
{
result.add(service);
}
}
//
return result;
}
/** /**
* Reverse. * Reverse.
* *

View file

@ -0,0 +1,130 @@
/*
* Copyright (C) 2020 Christian Pierre MOMON <christian@momon.org>
*
* This file is part of StatoolInfos, simple service statistics tool.
*
* StatoolInfos is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* StatoolInfos is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with StatoolInfos. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.devinsy.statoolinfos.core;
import fr.devinsy.strings.StringList;
/**
* The Class Software.
*/
public class Software
{
private String name;
private String description;
private StringList aliases;
/**
* Instantiates a new software.
*
* @param name
* the name
*/
public Software(final String name)
{
this(name, "");
}
/**
* Instantiates a new software.
*
* @param name
* the name
* @param description
* the description
*/
public Software(final String name, final String description)
{
this.name = name;
this.description = description;
this.aliases = new StringList(name);
}
/**
* Instantiates a new software.
*
* @param name
* the name
* @param description
* the description
* @param softwares
* the softwares
*/
public Software(final String name, final String description, final StringList softwares)
{
this.name = name;
this.description = description;
this.aliases = new StringList(softwares);
}
public StringList getAliases()
{
return this.aliases;
}
public String getDescription()
{
return this.description;
}
public String getName()
{
return this.name;
}
/**
* Gets the technical name.
*
* @return the technical name
*/
public String getTechnicalName()
{
String result;
result = StatoolInfosUtils.toTechnicalName(getName());
//
return result;
}
public void setDescription(final String description)
{
this.description = description;
}
public void setName(final String name)
{
this.name = name;
}
/**
* To string.
*
* @return the string
*/
@Override
public String toString()
{
String result;
result = String.format("[name=%s][description=%s][aliases=%s]", this.name, this.description, this.aliases.toStringSeparatedBy(','));
//
return result;
}
}

View file

@ -0,0 +1,110 @@
/*
*
*/
package fr.devinsy.statoolinfos.core;
import java.util.Comparator;
import fr.devinsy.statoolinfos.util.CompareUtils;
/**
* The Class SoftwareComparator.
*/
public class SoftwareComparator implements Comparator<Software>
{
public enum Sorting
{
NAME
}
private Sorting sorting;
/**
* Instantiates a new organization comparator.
*
* @param sorting
* the sorting
*/
public SoftwareComparator(final Sorting sorting)
{
this.sorting = sorting;
}
/**
* Compare.
*
* @param alpha
* the alpha
* @param bravo
* the bravo
* @return the int
*/
@Override
public int compare(final Software alpha, final Software bravo)
{
int result;
result = compare(alpha, bravo, this.sorting);
//
return result;
}
/**
* Compare.
*
* @param alpha
* the alpha
* @param bravo
* the bravo
* @param sorting
* the sorting
* @return the int
*/
public static int compare(final Software alpha, final Software bravo, final Sorting sorting)
{
int result;
if (sorting == null)
{
result = 0;
}
else
{
switch (sorting)
{
default:
case NAME:
result = CompareUtils.compare(getName(alpha), getName(bravo));
break;
}
}
//
return result;
}
/**
* Gets the name.
*
* @param source
* the source
* @return the name
*/
public static String getName(final Software source)
{
String result;
if (source == null)
{
result = null;
}
else
{
result = source.getName();
}
//
return result;
}
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (C) 2020 Christian Pierre MOMON <christian@momon.org>
*
* This file is part of StatoolInfos, simple service statistics tool.
*
* StatoolInfos is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* StatoolInfos is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with StatoolInfos. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.devinsy.statoolinfos.core;
import java.util.ArrayList;
import java.util.Collections;
/**
* The Class Categories.
*/
public class SoftwareList extends ArrayList<Software>
{
private static final long serialVersionUID = -3197394621123996060L;
/**
* Instantiates a new software list.
*/
public SoftwareList()
{
super();
}
/**
* Reverse.
*
* @return the software list
*/
public SoftwareList reverse()
{
SoftwareList result;
Collections.reverse(this);
result = this;
//
return result;
}
/**
* Sort.
*
* @param sorting
* the sorting
* @return the issues
*/
public SoftwareList sort(final SoftwareComparator.Sorting sorting)
{
SoftwareList result;
sort(new SoftwareComparator(sorting));
result = this;
//
return result;
}
/**
* Sort by name.
*
* @return the services
*/
public SoftwareList sortByName()
{
SoftwareList result;
result = sort(SoftwareComparator.Sorting.NAME);
//
return result;
}
}

View file

@ -0,0 +1,85 @@
/*
* Copyright (C) 2020 Christian Pierre MOMON <christian@momon.org>
*
* This file is part of StatoolInfos, simple service statistics tool.
*
* StatoolInfos is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* StatoolInfos is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with StatoolInfos. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.devinsy.statoolinfos.core;
import java.util.HashMap;
/**
* The Class Softwares.
*/
public class Softwares extends HashMap<String, Software>
{
private static final long serialVersionUID = 4780901718767657693L;
/**
* Instantiates a new softwares.
*/
public Softwares()
{
super();
}
/**
* Builds the key.
*
* @param source
* the source
* @return the string
*/
private String buildKey(final String source)
{
String result;
result = StatoolInfosUtils.toTechnicalName(source);
//
return result;
}
/**
* Gets the.
*
* @param key
* the key
* @return the software
*/
public Software get(final String key)
{
Software result;
result = super.get(buildKey(key));
//
return result;
}
/**
* Put.
*
* @param software
* the software
*/
public void put(final Software software)
{
for (String alias : software.getAliases())
{
put(buildKey(alias), software);
}
}
}

View file

@ -29,7 +29,7 @@ import fr.devinsy.xidyn.data.TagDataManager;
import fr.devinsy.xidyn.presenters.PresenterUtils; import fr.devinsy.xidyn.presenters.PresenterUtils;
/** /**
* The Class ServicesPage. * The Class CategoriesPage.
*/ */
public class CategoriesPage public class CategoriesPage
{ {
@ -62,6 +62,7 @@ public class CategoriesPage
data.setEscapedContent("categoryListLine", index, "categoryListLineNameLink", stat.getCategory().getName()); data.setEscapedContent("categoryListLine", index, "categoryListLineNameLink", stat.getCategory().getName());
data.setAttribute("categoryListLine", index, "categoryListLineNameLink", "href", "category-" + stat.getCategory().getTechnicalName() + ".xhtml"); data.setAttribute("categoryListLine", index, "categoryListLineNameLink", "href", "category-" + stat.getCategory().getTechnicalName() + ".xhtml");
data.setAttribute("categoryListLine", index, "categoryListLineNameLink", "title", stat.getCategory().getDescription()); data.setAttribute("categoryListLine", index, "categoryListLineNameLink", "title", stat.getCategory().getDescription());
data.setEscapedContent("categoryListLine", index, "categoryListLineSoftwares", stat.getCategory().getSoftwares().toStringWithFrenchCommas()); data.setEscapedContent("categoryListLine", index, "categoryListLineSoftwares", stat.getCategory().getSoftwares().toStringWithFrenchCommas());
data.setContent("categoryListLine", index, "categoryListLineOrganizationCount", stat.getOrganizationCount()); data.setContent("categoryListLine", index, "categoryListLineOrganizationCount", stat.getOrganizationCount());
data.setContent("categoryListLine", index, "categoryListLineServiceCount", stat.getServiceCount()); data.setContent("categoryListLine", index, "categoryListLineServiceCount", stat.getServiceCount());
@ -78,7 +79,7 @@ public class CategoriesPage
} }
catch (XidynException exception) catch (XidynException exception)
{ {
throw new StatoolInfosException("Error building service page: " + exception.getMessage(), exception); throw new StatoolInfosException("Error building categories page: " + exception.getMessage(), exception);
} }
// //

View file

@ -83,12 +83,12 @@ public class CategoryPage
BreadcrumbTrail trail = new BreadcrumbTrail(); BreadcrumbTrail trail = new BreadcrumbTrail();
trail.add("Catégories", "categories.xhtml"); trail.add("Catégories", "categories.xhtml");
trail.add("Catégorie", "category.xhtml"); trail.add(category.getName(), "category-" + category.getTechnicalName() + ".xhtml");
result = WebCharterView.build(content, trail); result = WebCharterView.build(content, trail);
} }
catch (XidynException exception) catch (XidynException exception)
{ {
throw new StatoolInfosException("Error building service page: " + exception.getMessage(), exception); throw new StatoolInfosException("Error building category page: " + exception.getMessage(), exception);
} }
// //

View file

@ -35,6 +35,8 @@ import fr.devinsy.statoolinfos.core.Federation;
import fr.devinsy.statoolinfos.core.Organization; import fr.devinsy.statoolinfos.core.Organization;
import fr.devinsy.statoolinfos.core.Service; import fr.devinsy.statoolinfos.core.Service;
import fr.devinsy.statoolinfos.core.Services; import fr.devinsy.statoolinfos.core.Services;
import fr.devinsy.statoolinfos.core.Software;
import fr.devinsy.statoolinfos.core.Softwares;
import fr.devinsy.statoolinfos.core.StatoolInfosException; import fr.devinsy.statoolinfos.core.StatoolInfosException;
import fr.devinsy.statoolinfos.core.StatoolInfosUtils; import fr.devinsy.statoolinfos.core.StatoolInfosUtils;
import fr.devinsy.statoolinfos.crawl.CrawlCache; import fr.devinsy.statoolinfos.crawl.CrawlCache;
@ -42,6 +44,7 @@ import fr.devinsy.statoolinfos.stats.StatAgent;
import fr.devinsy.statoolinfos.stats.categories.CategoryStats; import fr.devinsy.statoolinfos.stats.categories.CategoryStats;
import fr.devinsy.statoolinfos.stats.properties.PropertyStats; import fr.devinsy.statoolinfos.stats.properties.PropertyStats;
import fr.devinsy.statoolinfos.stats.propertyfiles.PropertiesFileStats; import fr.devinsy.statoolinfos.stats.propertyfiles.PropertiesFileStats;
import fr.devinsy.statoolinfos.stats.softwares.SoftwareStats;
/** /**
* The Class Htmlizer. * The Class Htmlizer.
@ -293,7 +296,7 @@ public class Htmlizer
// //
{ {
logger.info("Htmlize category page."); logger.info("Htmlize category pages.");
for (Category category : categories) for (Category category : categories)
{ {
Services services = federation.getAllServices().getBy(category); Services services = federation.getAllServices().getBy(category);
@ -301,6 +304,26 @@ public class Htmlizer
FileUtils.write(new File(htmlizeDirectory, "category-" + category.getTechnicalName() + ".xhtml"), page, StandardCharsets.UTF_8); FileUtils.write(new File(htmlizeDirectory, "category-" + category.getTechnicalName() + ".xhtml"), page, StandardCharsets.UTF_8);
} }
} }
//
{
logger.info("Htmlize softwares page.");
SoftwareStats stats = StatAgent.statAllSoftwares(federation, categories);
page = SoftwaresPage.build(stats);
FileUtils.write(new File(htmlizeDirectory, "softwares.xhtml"), page, StandardCharsets.UTF_8);
}
//
{
logger.info("Htmlize software pages.");
Softwares catalog = federation.getSoftwares();
for (Software software : catalog.values())
{
Services services = federation.getAllServices().getBy(software);
page = SoftwarePage.build(software, services);
FileUtils.write(new File(htmlizeDirectory, "software-" + software.getTechnicalName() + ".xhtml"), page, StandardCharsets.UTF_8);
}
}
} }
/** /**

View file

@ -0,0 +1,98 @@
/*
* Copyright (C) 2020 Christian Pierre MOMON <christian@momon.org>
*
* This file is part of StatoolInfos, simple service statistics tool.
*
* StatoolInfos is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* StatoolInfos is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with StatoolInfos. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.devinsy.statoolinfos.htmlize;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.statoolinfos.core.Service;
import fr.devinsy.statoolinfos.core.Services;
import fr.devinsy.statoolinfos.core.Software;
import fr.devinsy.statoolinfos.core.StatoolInfosException;
import fr.devinsy.xidyn.XidynException;
import fr.devinsy.xidyn.data.TagDataManager;
import fr.devinsy.xidyn.presenters.PresenterUtils;
/**
* The Class SoftwarePage.
*/
public class SoftwarePage
{
private static Logger logger = LoggerFactory.getLogger(SoftwarePage.class);
/**
* Builds the.
*
* @param software
* the software
* @param services
* the services
* @return the string
* @throws StatoolInfosException
* the statool infos exception
*/
public static String build(final Software software, final Services services) throws StatoolInfosException
{
String result;
try
{
logger.debug("Building services page.");
TagDataManager data = new TagDataManager();
data.setContent("softwareName", software.getName());
data.setContent("softwareDesciprtion", software.getDescription());
data.setContent("serviceCount", services.size());
int index = 0;
for (Service service : services)
{
data.setAttribute("serviceListLine", index, "serviceListLineLogo", "src", service.getOrganization().getTechnicalName() + "-" + service.getTechnicalName() + "-logo.png");
data.setEscapedContent("serviceListLine", index, "serviceListLineNameValue", service.getName());
data.setAttribute("serviceListLine", index, "serviceListLineNameLink", "href", service.getOrganization().getTechnicalName() + "-" + service.getTechnicalName() + ".xhtml");
data.setAttribute("serviceListLine", index, "serviceListLineOrganizationLink", "href", service.getOrganization().getTechnicalName() + ".xhtml");
data.setAttribute("serviceListLine", index, "serviceListLineOrganizationLogo", "src", service.getOrganization().getTechnicalName() + "-logo.png");
data.setEscapedContent("serviceListLine", index, "serviceListLineOrganizationValue", service.getOrganization().getName());
data.setEscapedContent("serviceListLine", index, "serviceListLineUrlLink", service.getWebsite());
data.setEscapedContent("serviceListLine", index, "serviceListLineWebsiteLink", service.getWebsite());
data.setAttribute("serviceListLine", index, "serviceListLineWebsiteLink", "href", service.getWebsite());
data.setEscapedContent("serviceListLine", index, "serviceListLineSoftware", service.getSoftwareName());
index += 1;
}
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/software.xhtml", data).toString();
BreadcrumbTrail trail = new BreadcrumbTrail();
trail.add("Logiciels", "softwares.xhtml");
trail.add(software.getName(), "software-" + software.getTechnicalName() + ".xhtml");
result = WebCharterView.build(content, trail);
}
catch (XidynException exception)
{
throw new StatoolInfosException("Error building software page: " + exception.getMessage(), exception);
}
//
return result;
}
}

View file

@ -0,0 +1,92 @@
/*
* Copyright (C) 2020 Christian Pierre MOMON <christian@momon.org>
*
* This file is part of StatoolInfos, simple service statistics tool.
*
* StatoolInfos is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* StatoolInfos is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with StatoolInfos. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.devinsy.statoolinfos.htmlize;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.statoolinfos.core.StatoolInfosException;
import fr.devinsy.statoolinfos.stats.softwares.SoftwareStat;
import fr.devinsy.statoolinfos.stats.softwares.SoftwareStats;
import fr.devinsy.xidyn.XidynException;
import fr.devinsy.xidyn.data.TagDataManager;
import fr.devinsy.xidyn.presenters.PresenterUtils;
/**
* The Class ServicesPage.
*/
public class SoftwaresPage
{
private static Logger logger = LoggerFactory.getLogger(SoftwaresPage.class);
/**
* Builds the.
*
* @param categories
* the services
* @return the string
* @throws StatoolInfosException
* the statool infos exception
*/
public static String build(final SoftwareStats stats) throws StatoolInfosException
{
String result;
try
{
logger.debug("Building softwares page.");
TagDataManager data = new TagDataManager();
data.setContent("softwareCount", stats.size());
int index = 0;
for (SoftwareStat stat : stats)
{
data.setEscapedContent("softwareListLine", index, "softwareListLineNameLink", stat.getName());
data.setAttribute("softwareListLine", index, "softwareListLineNameLink", "href", "software-" + stat.getTechnicalName() + ".xhtml");
data.setEscapedContent("softwareListLine", index, "softwareListLineCategoryLink", stat.getCategory().getName());
data.setAttribute("softwareListLine", index, "softwareListLineCategoryLink", "href", "category-" + stat.getCategory().getTechnicalName() + ".xhtml");
data.setAttribute("softwareListLine", index, "softwareListLineCategoryLink", "title", stat.getCategory().getDescription());
data.setEscapedContent("softwareListLine", index, "softwareListLineSoftwares", stat.getCategory().getName());
data.setContent("softwareListLine", index, "softwareListLineOrganizationCount", stat.getOrganizationCount());
data.setContent("softwareListLine", index, "softwareListLineServiceCount", stat.getServiceCount());
data.setContent("softwareListLine", index, "categoryListLineUserCount", stat.getUserCount());
index += 1;
}
String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/softwares.xhtml", data).toString();
BreadcrumbTrail trail = new BreadcrumbTrail();
trail.add("Logiciels", "softwares.xhtml");
result = WebCharterView.build(content, trail);
}
catch (XidynException exception)
{
throw new StatoolInfosException("Error building softwares page: " + exception.getMessage(), exception);
}
//
return result;
}
}

View file

@ -22,16 +22,18 @@
<th class="">Nom de la catégorie</th> <th class="">Nom de la catégorie</th>
<th class="">Logiciels</th> <th class="">Logiciels</th>
<th class="" style="width: 100px;">Services</th> <th class="" style="width: 100px;">Services</th>
<th class="" style="width: 100px;">Organizations</th> <th class="" style="width: 100px;">Organisations</th>
<th class="" style="width: 100px;">Utilisateurs mensuels</th> <th class="" style="width: 100px;">Utilisateurs mensuels</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr id="categoryListLine"> <tr id="categoryListLine">
<td id="categoryListLineName" style="padding-top: 0; padding-bottom: 0;"> <td id="categoryListLineName" style="padding-top: 0; padding-bottom: 0;">
<a href="#" id="categoryListLineNameLink" title="categoryListLineNameDescription">n/a</a> <a href="#" id="categoryListLineNameLink" title="">n/a</a>
</td>
<td id="categoryListLineCategory" style="padding-top: 0; padding-bottom: 0;">
<a href="#" id="categoryListLineCategoryLink" title="categoryListLineCategoryDescription">n/a</a>
</td> </td>
<td id="categoryListLineSoftwares">n/a</td>
<td id="categoryListLineServiceCount" class="td_number">n/a</td> <td id="categoryListLineServiceCount" class="td_number">n/a</td>
<td id="categoryListLineOrganizationCount" class="td_number">n/a</td> <td id="categoryListLineOrganizationCount" class="td_number">n/a</td>
<td id="categoryListLineUserCount" class="td_number">n/a</td> <td id="categoryListLineUserCount" class="td_number">n/a</td>

View file

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>StatoolInfos</title>
<meta charset="UTF-8" />
<meta name="keywords" content="statoolinfos,devinsy,federation" />
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="statoolinfos.css" />
<script src="sorttable.js" />
<script src="Chart.bundle.min.js"></script>
</head>
<body>
<div class="center">
<h2>Logiciel <span id="softwareName">n/a</span></h2>
<p id="softwareDescription">Bla bla description</p>
<div>Nombre de services : <span id="serviceCount">n/a</span></div>
<div class="left">
<table class="table_classic center_table sortable" style="width: 900px; margin-left: auto; margin-right: auto;">
<thead>
<tr>
<th class="" style="width: 200px;">Nom du service</th>
<th class="" style="width: 200px;">Organisation</th>
<th class="" style="width: 200px;">URL</th>
<th class="" style="width: 200px;">Logiciel</th>
<th class="" style="width: 100px;">Utilisateurs mensuels</th>
</tr>
</thead>
<tbody>
<tr id="serviceListLine">
<td id="serviceListLineName" style="padding-top: 0; padding-bottom: 0;">
<a href="#" id="serviceListLineNameLink">
<img id="serviceListLineLogo" src="" style="width: 26px; height: 26px; padding-top:0; padding-bottom: 0; vertical-align: middle;"/>
&#160;<span id="serviceListLineNameValue">n/a</span>
</a>
</td>
<td id="serviceListLineOrganization" style="padding-top: 0; padding-bottom: 0;">
<a href="#" id="serviceListLineOrganizationLink">
<img id="serviceListLineOrganizationLogo" src="" style="width: 26px; height: 26px; padding-top:0; padding-bottom: 0; vertical-align: middle;"/>
&#160;<span id="serviceListLineOrganizationValue">n/a</span>
</a>
</td>
<td id="serviceListLineWebsite"><a href="#" id="serviceListLineWebsiteLink">n/a</a></td>
<td id="serviceListLineSoftware">n/a</td>
<td id="serviceListLineUserCount" class="td_number">n/a</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>StatoolInfos</title>
<meta charset="UTF-8" />
<meta name="keywords" content="statoolinfos,devinsy,federation" />
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="statoolinfos.css" />
<script src="sorttable.js" />
<script src="Chart.bundle.min.js"></script>
</head>
<body>
<div class="center">
<h2>Logiciels</h2>
<div>Nombre de logiciels : <span id="softwareCount">n/a</span></div>
<div class="left">
<table class="table_classic center_table sortable" style="width: 900px; margin-left: auto; margin-right: auto;">
<thead>
<tr>
<th class="">Nom</th>
<th class="">Catégorie</th>
<th class="" style="width: 100px;">Services</th>
<th class="" style="width: 100px;">Organisations</th>
<th class="" style="width: 100px;">Utilisateurs mensuels</th>
</tr>
</thead>
<tbody>
<tr id="softwareListLine">
<td id="softwareListLineName" style="padding-top: 0; padding-bottom: 0;">
<a href="#" id="softwareListLineNameLink" title="">n/a</a>
</td>
<td id="softwareListLineCategory" style="padding-top: 0; padding-bottom: 0;">
<a href="#" id="softwareListLineCategoryLink" title="">n/a</a>
</td>
<td id="softwareListLineServiceCount" class="td_number">n/a</td>
<td id="softwareListLineOrganizationCount" class="td_number">n/a</td>
<td id="softwareListLineUserCount" class="td_number">n/a</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

View file

@ -20,8 +20,7 @@
<a id="propertiesRawButton" href="propertyStats.xhtml" class="button">Propriétés</a> <a id="propertiesRawButton" href="propertyStats.xhtml" class="button">Propriétés</a>
<a id="" href="services.xhtml" class="button">Services</a> <a id="" href="services.xhtml" class="button">Services</a>
<a id="" href="categories.xhtml" class="button">Catégories</a> <a id="" href="categories.xhtml" class="button">Catégories</a>
<a id="" href="#" class="button">Logiciels</a> <a id="" href="softwares.xhtml" class="button">Logiciels</a>
<a id="" href="#" class="button">Candidats</a>
</div> </div>
<div id="breadcrumbTrail" style="margin: 5px;">n/a > n/a</div> <div id="breadcrumbTrail" style="margin: 5px;">n/a > n/a</div>

View file

@ -21,6 +21,9 @@ package fr.devinsy.statoolinfos.stats;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.statoolinfos.core.Categories; import fr.devinsy.statoolinfos.core.Categories;
import fr.devinsy.statoolinfos.core.Category; import fr.devinsy.statoolinfos.core.Category;
import fr.devinsy.statoolinfos.core.Federation; import fr.devinsy.statoolinfos.core.Federation;
@ -28,11 +31,15 @@ import fr.devinsy.statoolinfos.core.Organization;
import fr.devinsy.statoolinfos.core.Organizations; import fr.devinsy.statoolinfos.core.Organizations;
import fr.devinsy.statoolinfos.core.Service; import fr.devinsy.statoolinfos.core.Service;
import fr.devinsy.statoolinfos.core.Services; import fr.devinsy.statoolinfos.core.Services;
import fr.devinsy.statoolinfos.core.Software;
import fr.devinsy.statoolinfos.core.Softwares;
import fr.devinsy.statoolinfos.crawl.CrawlCache; import fr.devinsy.statoolinfos.crawl.CrawlCache;
import fr.devinsy.statoolinfos.stats.categories.CategoryStat; import fr.devinsy.statoolinfos.stats.categories.CategoryStat;
import fr.devinsy.statoolinfos.stats.categories.CategoryStats; import fr.devinsy.statoolinfos.stats.categories.CategoryStats;
import fr.devinsy.statoolinfos.stats.properties.PropertyStats; import fr.devinsy.statoolinfos.stats.properties.PropertyStats;
import fr.devinsy.statoolinfos.stats.propertyfiles.PropertiesFileStats; import fr.devinsy.statoolinfos.stats.propertyfiles.PropertiesFileStats;
import fr.devinsy.statoolinfos.stats.softwares.SoftwareStat;
import fr.devinsy.statoolinfos.stats.softwares.SoftwareStats;
import fr.devinsy.strings.StringSet; import fr.devinsy.strings.StringSet;
/** /**
@ -40,12 +47,13 @@ import fr.devinsy.strings.StringSet;
*/ */
public class StatAgent public class StatAgent
{ {
private static Logger logger = LoggerFactory.getLogger(StatAgent.class);
/** /**
* Instantiates a new stat agent. * Instantiates a new stat agent.
*/ */
private StatAgent() private StatAgent()
{ {
} }
/** /**
@ -144,6 +152,46 @@ public class StatAgent
return result; return result;
} }
/**
* Stat all softwares.
*
* @param federation
* the federation
* @return the software stats
*/
public static SoftwareStats statAllSoftwares(final Federation federation, final Categories categories)
{
SoftwareStats result;
// Build catalog.
Softwares catalog = federation.getSoftwares();
logger.info("CATALOG={}", catalog.size());
// Stat.
result = new SoftwareStats();
for (Software software : catalog.values())
{
SoftwareStat stat = new SoftwareStat(software.getName());
StringSet organizations = new StringSet();
for (Service service : federation.getAllServices())
{
Software current = catalog.get(service.getSoftwareName());
if (current == software)
{
stat.incServiceCount();
stat.incUserCount(service.getUserCount());
stat.setCategory(categories.findBySoftware(service.getSoftwareName()));
organizations.add(service.getOrganization().getName());
}
}
stat.setOrganizationCount(organizations.size());
result.add(stat);
}
//
return result;
}
/** /**
* Stat federation properties. * Stat federation properties.
* *

View file

@ -0,0 +1,141 @@
/*
* Copyright (C) 2020 Christian Pierre MOMON <christian@momon.org>
*
* This file is part of StatoolInfos, simple service statistics tool.
*
* StatoolInfos is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* StatoolInfos is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with StatoolInfos. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.devinsy.statoolinfos.stats.softwares;
import fr.devinsy.statoolinfos.core.Category;
import fr.devinsy.statoolinfos.core.StatoolInfosUtils;
/**
* The Class SoftwareStat.
*/
public class SoftwareStat
{
private String name;
private Category category;
private int serviceCount;
private int organizationCount;
private int userCount;
/**
* Instantiates a new software stat.
*
* @param name
* the name
*/
public SoftwareStat(final String name)
{
this.name = name;
this.category = null;
this.serviceCount = 0;
this.organizationCount = 0;
this.userCount = 0;
}
public Category getCategory()
{
return this.category;
}
public String getName()
{
return this.name;
}
public int getOrganizationCount()
{
return this.organizationCount;
}
public int getServiceCount()
{
return this.serviceCount;
}
/**
* Gets the technical name.
*
* @return the technical name
*/
public String getTechnicalName()
{
String result;
result = StatoolInfosUtils.toTechnicalName(this.name);
//
return result;
}
public int getUserCount()
{
return this.userCount;
}
/**
* Inc service count.
*/
public void incServiceCount()
{
this.serviceCount += 1;
}
/**
* Inc user count.
*/
public void incUserCount()
{
this.serviceCount += 1;
}
/**
* Inc user count.
*
* @param value
* the value
*/
public void incUserCount(final int value)
{
this.userCount += value;
}
public void setCategory(final Category category)
{
this.category = category;
}
public void setName(final String name)
{
this.name = name;
}
public void setOrganizationCount(final int organizationCount)
{
this.organizationCount = organizationCount;
}
public void setServiceCount(final int serviceCount)
{
this.serviceCount = serviceCount;
}
public void setUserCount(final int userCount)
{
this.userCount = userCount;
}
}

View file

@ -0,0 +1,198 @@
/*
*
*/
package fr.devinsy.statoolinfos.stats.softwares;
import java.util.Comparator;
import fr.devinsy.statoolinfos.util.CompareUtils;
/**
* The Class SoftwareStatComparator.
*/
public class SoftwareStatComparator implements Comparator<SoftwareStat>
{
public enum Sorting
{
NAME,
SERVICE_COUNT,
ORGANIZATION_COUNT,
USER_COUNT
}
private Sorting sorting;
/**
* Instantiates a new category stat comparator.
*
* @param sorting
* the sorting
*/
public SoftwareStatComparator(final Sorting sorting)
{
//
this.sorting = sorting;
}
/**
* Compare.
*
* @param alpha
* the alpha
* @param bravo
* the bravo
* @return the int
*/
@Override
public int compare(final SoftwareStat alpha, final SoftwareStat bravo)
{
int result;
result = compare(alpha, bravo, this.sorting);
//
return result;
}
/**
* Compare.
*
* @param alpha
* the alpha
* @param bravo
* the bravo
* @param sorting
* the sorting
* @return the int
*/
public static int compare(final SoftwareStat alpha, final SoftwareStat bravo, final Sorting sorting)
{
int result;
if (sorting == null)
{
result = 0;
}
else
{
switch (sorting)
{
default:
case NAME:
result = CompareUtils.compare(getName(alpha), getName(bravo));
break;
case SERVICE_COUNT:
result = CompareUtils.compare(getServiceCount(alpha), getServiceCount(bravo));
break;
case ORGANIZATION_COUNT:
result = CompareUtils.compare(getOrganizationCount(alpha), getOrganizationCount(bravo));
break;
case USER_COUNT:
result = CompareUtils.compare(getUserCount(alpha), getUserCount(bravo));
break;
}
}
//
return result;
}
/**
* Gets the name.
*
* @param source
* the source
* @return the name
*/
public static String getName(final SoftwareStat source)
{
String result;
if (source == null)
{
result = null;
}
else
{
result = source.getCategory().getName();
}
//
return result;
}
/**
* Gets the organization count.
*
* @param source
* the source
* @return the organization count
*/
public static Long getOrganizationCount(final SoftwareStat source)
{
Long result;
if (source == null)
{
result = null;
}
else
{
result = (long) source.getOrganizationCount();
}
//
return result;
}
/**
* Gets the id.
*
* @param source
* the source
* @return the id
*/
public static Long getServiceCount(final SoftwareStat source)
{
Long result;
if (source == null)
{
result = null;
}
else
{
result = (long) source.getServiceCount();
}
//
return result;
}
/**
* Gets the user count.
*
* @param source
* the source
* @return the user count
*/
public static Long getUserCount(final SoftwareStat source)
{
Long result;
if (source == null)
{
result = null;
}
else
{
result = (long) source.getUserCount();
}
//
return result;
}
}

View file

@ -0,0 +1,134 @@
/*
* Copyright (C) 2020 Christian Pierre MOMON <christian@momon.org>
*
* This file is part of StatoolInfos, simple service statistics tool.
*
* StatoolInfos is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* StatoolInfos is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with StatoolInfos. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.devinsy.statoolinfos.stats.softwares;
import java.util.ArrayList;
import java.util.Collections;
/**
* The Class SoftwareStats.
*/
public class SoftwareStats extends ArrayList<SoftwareStat>
{
private static final long serialVersionUID = 3512825968551889090L;
/**
* Instantiates a new software stats.
*/
public SoftwareStats()
{
super();
}
/**
* Reverse.
*
* @return the software stats
*/
public SoftwareStats reverse()
{
SoftwareStats result;
Collections.reverse(this);
result = this;
//
return result;
}
/**
* Sort.
*
* @param sorting
* the sorting
* @return the issues
*/
public SoftwareStats sort(final SoftwareStatComparator.Sorting sorting)
{
SoftwareStats result;
sort(new SoftwareStatComparator(sorting));
result = this;
//
return result;
}
/**
* Sort by name.
*
* @return the software stats
*/
public SoftwareStats sortByName()
{
SoftwareStats result;
result = sort(SoftwareStatComparator.Sorting.NAME);
//
return result;
}
/**
* Sort by organization count.
*
* @return the software stats
*/
public SoftwareStats sortByOrganizationCount()
{
SoftwareStats result;
result = sort(SoftwareStatComparator.Sorting.ORGANIZATION_COUNT);
//
return result;
}
/**
* Sort by service count.
*
* @return the category stats
*/
public SoftwareStats sortByServiceCount()
{
SoftwareStats result;
result = sort(SoftwareStatComparator.Sorting.SERVICE_COUNT);
//
return result;
}
/**
* Sort by user count.
*
* @return the category stats
*/
public SoftwareStats sortByUserCount()
{
SoftwareStats result;
result = sort(SoftwareStatComparator.Sorting.USER_COUNT);
//
return result;
}
}