Skip to content

Commit

Permalink
Implement a section showing a list of empty pages xwikisas#95 (xwikis…
Browse files Browse the repository at this point in the history
…as#96)

* created EmptyDocumentsProvider.java usage provider for empty documents
* created a new page to view the empty pages live data table
* created a live data table JSON for the empty pages
* created a modal macro for the empty pages live data table
* created and adapted tests
* modified the spam pages to return a DocumentReference instead of a XWikiDocument
* adapted SpamPages code
* added unstable annotation and since tag to the script service public API
* added comments
* added translations
* code refactoring
* removed code leftover
  • Loading branch information
ChiuchiuSorin authored Aug 13, 2024
1 parent a890d6b commit 0ad01fd
Show file tree
Hide file tree
Showing 17 changed files with 740 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@
import org.xwiki.component.annotation.Component;
import org.xwiki.component.manager.ComponentLookupException;
import org.xwiki.component.manager.ComponentManager;
import org.xwiki.model.reference.DocumentReference;

import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.doc.XWikiAttachment;
import com.xpn.xwiki.objects.BaseObject;
import com.xpn.xwiki.objects.classes.BaseClass;
import com.xwiki.admintools.DataProvider;
import com.xwiki.admintools.internal.data.identifiers.CurrentServer;
import com.xwiki.admintools.internal.files.ImportantFilesManager;
Expand Down Expand Up @@ -147,7 +150,7 @@ public String getInstanceSizeTemplate()
* @param order the order of the sort.
* @return a {@link List} with the documents that have more than the given number of comments.
*/
public List<XWikiDocument> getPagesOverGivenNumberOfComments(long maxComments, Map<String, String> filters,
public List<DocumentReference> getPagesOverGivenNumberOfComments(long maxComments, Map<String, String> filters,
String sortColumn, String order)
{
return instanceUsageManager.getSpammedPages(maxComments, filters, sortColumn, order);
Expand Down Expand Up @@ -179,4 +182,18 @@ public List<WikiSizeResult> getWikiSizeResults(Map<String, String> filters, Stri
{
return this.instanceUsageManager.getWikisSize(filters, sortColumn, order);
}

/**
* Retrieves those documents that have no content, {@link XWikiAttachment}, {@link BaseClass}, {@link BaseObject},
* or comments.
*
* @param filters {@link Map} of filters to be applied on the gathered list.
* @param sortColumn target column to apply the sort on.
* @param order the order of the sort.
* @return a filtered and sorted {@link List} of {@link DocumentReference}.
*/
public List<DocumentReference> getEmptyDocuments(Map<String, String> filters, String sortColumn, String order)
{
return this.instanceUsageManager.getEmptyDocuments(filters, sortColumn, order);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@
import javax.inject.Inject;
import javax.inject.Provider;

import org.xwiki.model.reference.DocumentReference;
import org.xwiki.wiki.descriptor.WikiDescriptor;
import org.xwiki.wiki.descriptor.WikiDescriptorManager;
import org.xwiki.wiki.manager.WikiManagerException;

import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xwiki.admintools.usage.WikiUsageResult;

/**
Expand All @@ -57,6 +60,9 @@ public abstract class AbstractInstanceUsageProvider

private static final String DESCENDING_ORDER = "desc";

@Inject
protected Provider<XWikiContext> xcontextProvider;

@Inject
private Provider<WikiDescriptorManager> wikiDescriptorManagerProvider;

Expand Down Expand Up @@ -140,25 +146,39 @@ public void applySort(List<WikiUsageResult> list, String sortColumn, String orde
* @param sortColumn the column after which to be sorted.
* @param order the sort oder.
*/
public void applyDocumentsSort(List<XWikiDocument> list, String sortColumn, String order)
public void applyDocumentsSort(List<DocumentReference> list, String sortColumn, String order)
{
Comparator<XWikiDocument> comparator = null;
XWikiContext xWikiContext = xcontextProvider.get();
XWiki xWiki = xWikiContext.getWiki();
Comparator<DocumentReference> comparator = null;
switch (sortColumn) {
case WIKI_NAME_KEY:
comparator = Comparator.comparing(doc -> {
try {
return wikiDescriptorManagerProvider.get()
.getById(doc.getDocumentReference().getWikiReference().getName()).getPrettyName();
return wikiDescriptorManagerProvider.get().getById(doc.getWikiReference().getName())
.getPrettyName();
} catch (Exception e) {
throw new RuntimeException(e);
}
});
break;
case "docName":
comparator = Comparator.comparing(XWikiDocument::getTitle);
comparator = Comparator.comparing(doc -> {
try {
return xWiki.getDocument(doc, xWikiContext).getTitle();
} catch (XWikiException e) {
throw new RuntimeException(e);
}
});
break;
case "commentsCount":
comparator = Comparator.comparing(doc -> doc.getComments().size());
comparator = Comparator.comparing(doc -> {
try {
return xWiki.getDocument(doc, xWikiContext).getComments().size();
} catch (XWikiException e) {
throw new RuntimeException(e);
}
});
break;
default:
break;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package com.xwiki.admintools.internal.usage;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.xwiki.component.annotation.Component;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.query.Query;
import org.xwiki.query.QueryException;
import org.xwiki.query.QueryFilter;
import org.xwiki.query.QueryManager;
import org.xwiki.wiki.descriptor.WikiDescriptor;
import org.xwiki.wiki.manager.WikiManagerException;

import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.doc.XWikiAttachment;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.objects.BaseObject;
import com.xpn.xwiki.objects.classes.BaseClass;

/**
* Retrieve data about wikis empty pages.
*
* @version $Id$
* @since 1.1
*/
@Component(roles = EmptyDocumentsProvider.class)
@Singleton
public class EmptyDocumentsProvider extends AbstractInstanceUsageProvider
{
@Inject
private QueryManager queryManager;

@Inject
@Named("hidden/document")
private QueryFilter hiddenDocumentFilter;

@Inject
@Named("document")
private QueryFilter documentFilter;

@Inject
@Named("viewable")
private QueryFilter viewableFilter;

/**
* Retrieves those documents that have no content, {@link XWikiAttachment}, {@link BaseClass}, {@link BaseObject},
* or comments.
*
* @param filters {@link Map} of filters to be applied on the gathered list.
* @param sortColumn target column to apply the sort on.
* @param order the order of the sort.
* @return a {@link List} with the {@link DocumentReference} of the empty documents.
*/
public List<DocumentReference> getEmptyDocuments(Map<String, String> filters, String sortColumn, String order)
throws WikiManagerException
{
Collection<WikiDescriptor> searchedWikis = getRequestedWikis(filters);
List<DocumentReference> emptyDocuments = new ArrayList<>();
XWikiContext wikiContext = xcontextProvider.get();
XWiki wiki = wikiContext.getWiki();
searchedWikis.forEach(wikiDescriptor -> {
try {
List<DocumentReference> queryResults = getEmptyDocumentsForWiki(wikiDescriptor.getId());
for (DocumentReference docRef : queryResults) {
XWikiDocument wikiDocument = wiki.getDocument(docRef, wikiContext);
if (wikiDocument.getXClassXML().isEmpty() && !wikiDocument.isHidden()) {
emptyDocuments.add(docRef);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
});
applyDocumentsSort(emptyDocuments, sortColumn, order);
return emptyDocuments;
}

/**
* Get the {@link DocumentReference} of empty documents in wiki.
*
* @param wikiId the wiki for which the data will be retrieved.
* @return a {@link List} with the {@link DocumentReference} of the empty documents.
* @throws QueryException if there are any exceptions while running the queries for data retrieval.
*/
public List<DocumentReference> getEmptyDocumentsForWiki(String wikiId) throws QueryException
{
return this.queryManager.createQuery(
"select doc.fullName from XWikiDocument doc "
+ "where (doc.content = '' or trim(doc.content) = '') "
+ "and not exists (select obj from BaseObject obj where obj.name = doc.fullName) "
+ "and not exists (select att from XWikiAttachment att where att.docId = doc.id)", Query.HQL)
.setWiki(wikiId)
.addFilter(hiddenDocumentFilter)
.addFilter(documentFilter)
.addFilter(viewableFilter)
.execute();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
import org.xwiki.wiki.descriptor.WikiDescriptorManager;

import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.doc.XWikiAttachment;
import com.xpn.xwiki.objects.BaseObject;
import com.xpn.xwiki.objects.classes.BaseClass;
import com.xwiki.admintools.internal.data.identifiers.CurrentServer;
import com.xwiki.admintools.internal.usage.wikiResult.WikiRecycleBins;
import com.xwiki.admintools.internal.usage.wikiResult.WikiSizeResult;
Expand Down Expand Up @@ -86,6 +88,9 @@ public class InstanceUsageManager
@Inject
private SpamPagesProvider spamPagesProvider;

@Inject
private EmptyDocumentsProvider emptyDocumentsProvider;

@Inject
private RecycleBinsProvider recycleBinsProvider;

Expand Down Expand Up @@ -157,7 +162,7 @@ public List<WikiSizeResult> getWikisSize(Map<String, String> filters, String sor
* @param order the order of the sort.
* @return a {@link List} with the documents that have more than the given number of comments.
*/
public List<XWikiDocument> getSpammedPages(long maxComments, Map<String, String> filters, String sortColumn,
public List<DocumentReference> getSpammedPages(long maxComments, Map<String, String> filters, String sortColumn,
String order)
{
try {
Expand All @@ -169,6 +174,26 @@ public List<XWikiDocument> getSpammedPages(long maxComments, Map<String, String>
}
}

/**
* Retrieves those documents that have no content, {@link XWikiAttachment}, {@link BaseClass}, {@link BaseObject},
* or comments.
*
* @param filters {@link Map} of filters to be applied on the gathered list.
* @param sortColumn target column to apply the sort on.
* @param order the order of the sort.
* @return a {@link List} with the {@link DocumentReference} of the empty documents.
*/
public List<DocumentReference> getEmptyDocuments(Map<String, String> filters, String sortColumn, String order)
{
try {
return emptyDocumentsProvider.getEmptyDocuments(filters, sortColumn, order);
} catch (Exception e) {
logger.warn("There have been issues while gathering wikis empty pages. Root cause is: [{}]",
ExceptionUtils.getRootCauseMessage(e));
throw new RuntimeException(e);
}
}

/**
* Get a {@link List} of {@link WikiRecycleBins} with the options to sort it and apply filters on it.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import org.xwiki.query.QueryException;
import org.xwiki.query.QueryManager;
import org.xwiki.wiki.descriptor.WikiDescriptor;
import org.xwiki.wiki.descriptor.WikiDescriptorManager;
import org.xwiki.wiki.manager.WikiManagerException;

import com.xwiki.admintools.internal.usage.wikiResult.WikiRecycleBins;
Expand All @@ -48,9 +47,6 @@
@Singleton
public class RecycleBinsProvider extends AbstractInstanceUsageProvider
{
@Inject
private WikiDescriptorManager wikiDescriptorManager;

@Inject
private QueryManager queryManager;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,17 @@

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton;

import org.xwiki.component.annotation.Component;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.DocumentReferenceResolver;
import org.xwiki.query.Query;
import org.xwiki.query.QueryException;
import org.xwiki.query.QueryFilter;
import org.xwiki.query.QueryManager;
import org.xwiki.wiki.descriptor.WikiDescriptor;
import org.xwiki.wiki.descriptor.WikiDescriptorManager;
import org.xwiki.wiki.manager.WikiManagerException;

import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.doc.XWikiDocument;

/**
* Provide data for the documents that are spammed.
*
Expand All @@ -53,15 +46,6 @@
@Singleton
public class SpamPagesProvider extends AbstractInstanceUsageProvider
{
@Inject
private Provider<XWikiContext> xcontextProvider;

@Inject
private WikiDescriptorManager wikiDescriptorManager;

@Inject
private DocumentReferenceResolver<String> resolver;

@Inject
private QueryManager queryManager;

Expand Down Expand Up @@ -90,21 +74,16 @@ public class SpamPagesProvider extends AbstractInstanceUsageProvider
* @param order the order of the sort.
* @return a {@link List} with the documents that have more than the given number of comments.
*/
public List<XWikiDocument> getDocumentsOverGivenNumberOfComments(long maxComments, Map<String, String> filters,
public List<DocumentReference> getDocumentsOverGivenNumberOfComments(long maxComments, Map<String, String> filters,
String sortColumn, String order) throws WikiManagerException
{
Collection<WikiDescriptor> searchedWikis = getRequestedWikis(filters);
List<XWikiDocument> spammedDocuments = new ArrayList<>();
List<DocumentReference> spammedDocuments = new ArrayList<>();
searchedWikis.forEach(wikiDescriptor -> {
try {
List<DocumentReference> queryResults =
getCommentsForWiki(maxComments, filters.get("docName"), wikiDescriptor.getId());
for (DocumentReference docRef : queryResults) {
XWikiContext xWikiContext = xcontextProvider.get();
XWiki xWiki = xWikiContext.getWiki();
XWikiDocument wikiDocument = xWiki.getDocument(docRef, xWikiContext);
spammedDocuments.add(wikiDocument);
}
spammedDocuments.addAll(queryResults);
} catch (Exception e) {
throw new RuntimeException(e);
}
Expand Down
Loading

0 comments on commit 0ad01fd

Please sign in to comment.