001/* 002 * Copyright 2023 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.plugins.forms.statistics; 017 018import java.util.ArrayList; 019import java.util.List; 020import java.util.stream.IntStream; 021 022import javax.jcr.Node; 023import javax.jcr.NodeIterator; 024import javax.jcr.Repository; 025import javax.jcr.Session; 026import javax.jcr.query.Query; 027import javax.jcr.query.QueryManager; 028 029import org.apache.avalon.framework.service.ServiceException; 030import org.apache.avalon.framework.service.ServiceManager; 031import org.apache.avalon.framework.service.Serviceable; 032import org.apache.jackrabbit.JcrConstants; 033import org.slf4j.Logger; 034 035import org.ametys.plugins.forms.content.table.FormTableManager; 036import org.ametys.plugins.repository.provider.AbstractRepository; 037import org.ametys.runtime.i18n.I18nizableText; 038import org.ametys.runtime.plugin.component.AbstractLogEnabled; 039import org.ametys.runtime.plugin.component.PluginAware; 040import org.ametys.runtime.plugins.admin.statistics.Statistics; 041import org.ametys.runtime.plugins.admin.statistics.StatisticsNode; 042import org.ametys.runtime.plugins.admin.statistics.StatisticsProvider; 043import org.ametys.runtime.plugins.admin.statistics.StatisticsValue; 044 045/** 046 * Stats for the "old" content forms 047 */ 048public class ContentFormsStatisticsProvider extends AbstractLogEnabled implements StatisticsProvider, Serviceable, PluginAware 049{ 050 private String _id; 051 private FormTableManager _formTableManager; 052 private Repository _repository; 053 054 public void service(ServiceManager manager) throws ServiceException 055 { 056 _repository = (Repository) manager.lookup(AbstractRepository.ROLE); 057 _formTableManager = (FormTableManager) manager.lookup(FormTableManager.ROLE); 058 } 059 060 public void setPluginInfo(String pluginName, String featureName, String id) 061 { 062 _id = id; 063 } 064 065 public Statistics getStatistics() 066 { 067 List<Integer> formsSubmissions = _getFormsSubmissions(); 068 int submissions = formsSubmissions.stream().flatMapToInt(IntStream::of).sum(); 069 070 return new StatisticsNode( 071 _id, 072 new I18nizableText("plugin.forms", "PLUGINS_FORMS_STATISTICS_CONTENTFORMS_LABEL"), 073 "ametysicon-code-html-form", 074 formsSubmissions.size(), 075 List.of( 076 new StatisticsNode( 077 "submissions", 078 new I18nizableText("plugin.forms", "PLUGINS_FORMS_STATISTICS_CONTENTFORMS_SUBMISSIONS_LABEL"), 079 "ametysicon-desktop-school-tool", 080 submissions, 081 List.of( 082 new StatisticsValue( 083 "max", 084 new I18nizableText("plugin.forms", "PLUGINS_FORMS_STATISTICS_CONTENTFORMS_SUBMISSIONS_MAX_LABEL"), 085 "ametysicon-sort51", 086 formsSubmissions.size() > 0 ? formsSubmissions.get(formsSubmissions.size() - 1) : 0 087 ), 088 new StatisticsValue( 089 "median", 090 new I18nizableText("plugin.forms", "PLUGINS_FORMS_STATISTICS_CONTENTFORMS_SUBMISSIONS_MEDIAN_LABEL"), 091 "ametysicon-maths-window-symbol-x", 092 formsSubmissions.size() > 0 ? formsSubmissions.get(formsSubmissions.size() / 2) : 0 093 ) 094 ), 095 false 096 ) 097 ), 098 true 099 ); 100 } 101 102 private List<String> _getFormsIds() 103 { 104 Session session = null; 105 try 106 { 107 session = _repository.login(); 108 109 QueryManager queryManager = session.getWorkspace().getQueryManager(); 110 @SuppressWarnings("deprecation") 111 Query query = queryManager.createQuery("//element(ametys-internal:forms, " + JcrConstants.NT_UNSTRUCTURED + ")/*", Query.XPATH); 112 NodeIterator nodeIterator = query.execute().getNodes(); 113 114 List<String> formsIds = new ArrayList<>(); 115 while (nodeIterator.hasNext()) 116 { 117 Node node = nodeIterator.nextNode(); 118 119 formsIds.add(node.getName()); 120 } 121 122 return formsIds; 123 } 124 catch (Exception e) 125 { 126 throw new IllegalStateException("Cannot get forms", e); 127 } 128 finally 129 { 130 if (session != null) 131 { 132 session.logout(); 133 } 134 } 135 } 136 137 private List<Integer> _getFormsSubmissions() 138 { 139 final Logger logger = getLogger(); 140 try 141 { 142 return _getFormsIds().stream() 143 .map(id -> { 144 try 145 { 146 return _formTableManager.getTotalSubmissions(id); 147 } 148 catch (Exception e) 149 { 150 151 logger.warn("An error occurred while retrieving the total submissions for the form " + id + ". It will be ignored.", e); 152 /* ignore */ 153 return 0; 154 } 155 }) 156 .sorted() 157 .toList(); 158 } 159 catch (Exception e) 160 { 161 throw new IllegalStateException("Cannot compute content forms statistics", e); 162 } 163 } 164}