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.cms.statistics; 017 018import java.util.ArrayList; 019import java.util.Comparator; 020import java.util.List; 021 022import org.apache.avalon.framework.service.ServiceException; 023import org.apache.avalon.framework.service.ServiceManager; 024import org.apache.avalon.framework.service.Serviceable; 025import org.apache.commons.lang3.StringUtils; 026 027import org.ametys.cms.contenttype.ContentType; 028import org.ametys.cms.contenttype.ContentTypeExtensionPoint; 029import org.ametys.cms.repository.Content; 030import org.ametys.cms.repository.ContentQueryHelper; 031import org.ametys.cms.repository.ContentTypeExpression; 032import org.ametys.core.util.I18nUtils; 033import org.ametys.plugins.repository.AmetysObjectIterable; 034import org.ametys.plugins.repository.AmetysObjectResolver; 035import org.ametys.plugins.repository.query.expression.AndExpression; 036import org.ametys.plugins.repository.query.expression.Expression; 037import org.ametys.plugins.repository.query.expression.Expression.Operator; 038import org.ametys.plugins.repository.query.expression.NotExpression; 039import org.ametys.runtime.i18n.I18nizableText; 040import org.ametys.runtime.plugin.component.PluginAware; 041import org.ametys.runtime.plugins.admin.statistics.Statistics; 042import org.ametys.runtime.plugins.admin.statistics.StatisticsNode; 043import org.ametys.runtime.plugins.admin.statistics.StatisticsProvider; 044import org.ametys.runtime.plugins.admin.statistics.StatisticsValue; 045 046/** 047 * CMS statistics 048 */ 049public class CMSStatisticsProvider implements StatisticsProvider, Serviceable, PluginAware 050{ 051 private String _id; 052 private AmetysObjectResolver _ametysResolver; 053 private ContentTypeExtensionPoint _contentTypeExtensionPoint; 054 private I18nUtils _i18nUtils; 055 056 public void service(ServiceManager manager) throws ServiceException 057 { 058 _ametysResolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 059 _contentTypeExtensionPoint = (ContentTypeExtensionPoint) manager.lookup(ContentTypeExtensionPoint.ROLE); 060 _i18nUtils = (I18nUtils) manager.lookup(I18nUtils.ROLE); 061 } 062 063 public void setPluginInfo(String pluginName, String featureName, String id) 064 { 065 _id = id; 066 } 067 068 public Statistics getStatistics() 069 { 070 return new StatisticsNode( 071 _id, 072 new I18nizableText("plugin.cms", "PLUGINS_CMS_STATISTICS_LABEL"), 073 "ametysicon-desktop-archive-black", 074 null, 075 List.of( 076 new StatisticsNode( 077 "contents", 078 new I18nizableText("plugin.cms", "PLUGINS_CMS_STATISTICS_CONTENTS_LABEL"), 079 "ametysicon-text70", 080 _countAllContents(null), 081 _getContentTypes(), 082 false 083 ) 084 ), 085 true 086 ); 087 } 088 089 private List<Statistics> _getContentTypes() 090 { 091 List<Statistics> stats = new ArrayList<>(); 092 093 List<Expression> notContentType = new ArrayList<>(); 094 095 for (String contentTypeId : _contentTypeExtensionPoint.getExtensionsIds()) 096 { 097 ContentType contentType = _contentTypeExtensionPoint.getExtension(contentTypeId); 098 099 if (!contentType.isAbstract()) 100 { 101 stats.add(new StatisticsValue( 102 contentTypeId, 103 new I18nizableText(StringUtils.defaultString(_i18nUtils.translate(contentType.getLabel(), contentType.getId()))), // Translate now for sorting 104 StringUtils.defaultIfBlank(contentType.getIconGlyph(), "ametysicon-text61"), 105 _countAllContents(contentTypeId) 106 )); 107 108 notContentType.add(new NotExpression(new ContentTypeExpression(Operator.EQ, contentTypeId))); 109 } 110 } 111 112 stats.sort(new Comparator<>() { 113 public int compare(Statistics o1, Statistics o2) 114 { 115 return o1.getLabel().getLabel().compareTo(o2.getLabel().getLabel()); 116 } 117 }); 118 119 String query = ContentQueryHelper.getContentXPathQuery(new AndExpression(notContentType.toArray(new NotExpression[notContentType.size()]))); 120 try (AmetysObjectIterable<Content> contents = _ametysResolver.query(query)) 121 { 122 stats.add(0, new StatisticsValue( 123 "unknown", 124 new I18nizableText("plugin.cms", "PLUGINS_CMS_STATISTICS_CONTENTS_UNKNOWN_LABEL"), 125 "ametysicon-file-extension-generic-unknown", 126 contents.getSize() 127 )); 128 } 129 130 return stats; 131 } 132 133 private long _countAllContents(String contentTypeId) 134 { 135 String query = ContentQueryHelper.getContentXPathQuery(contentTypeId != null ? new ContentTypeExpression(Operator.EQ, contentTypeId) : null); 136 try (AmetysObjectIterable<Content> contents = _ametysResolver.query(query)) 137 { 138 return contents.getSize(); 139 } 140 } 141}