From 4f0be369314644d76e8fddf922d5be759c759ca5 Mon Sep 17 00:00:00 2001 From: jensp Date: Mon, 16 Jan 2017 20:03:20 +0000 Subject: [PATCH] CCM NG/ccm-cms: First part of migration the ReportPane git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4520 8810af33-2d31-482b-a856-94f89814c4df --- .../com/arsdigita/cms/ui/BaseAdminPane.java | 18 +- .../com/arsdigita/cms/ui/ReportPane.java.todo | 147 +++++----- .../ContentSectionSummaryController.java.todo | 215 +++++++++++++++ ...onSummaryReportTableModelBuilder.java.todo | 251 ++++++++++++++++++ .../ContentSectionSummaryTable.java.todo | 54 ++++ .../com/arsdigita/cms/ui/report/Report.java | 67 +++++ .../cms/ui/report/ReportListModel.java | 58 ++++ .../org/librecms/contentsection/Folder.java | 13 +- .../arsdigita/toolbox/ui/SelectionPanel.java | 186 ++++++------- 9 files changed, 836 insertions(+), 173 deletions(-) create mode 100644 ccm-cms/src/main/java/com/arsdigita/cms/ui/report/ContentSectionSummaryController.java.todo create mode 100644 ccm-cms/src/main/java/com/arsdigita/cms/ui/report/ContentSectionSummaryReportTableModelBuilder.java.todo create mode 100644 ccm-cms/src/main/java/com/arsdigita/cms/ui/report/ContentSectionSummaryTable.java.todo create mode 100644 ccm-cms/src/main/java/com/arsdigita/cms/ui/report/Report.java create mode 100644 ccm-cms/src/main/java/com/arsdigita/cms/ui/report/ReportListModel.java diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/BaseAdminPane.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/BaseAdminPane.java index b232d9c4d..56b689a10 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/BaseAdminPane.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/BaseAdminPane.java @@ -24,21 +24,18 @@ import com.arsdigita.bebop.list.ListModelBuilder; import com.arsdigita.bebop.tree.TreeModelBuilder; import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.toolbox.ui.SelectionPanel; -import org.apache.log4j.Logger; + import org.librecms.CmsConstants; /** * A base component for use in CMS admin panes. * + * @param Type managed by the {@link SingleSelectionModel} used by instances + * of this class. + * * @author Justin Ross <jross@redhat.com> */ -public abstract class BaseAdminPane extends SelectionPanel { - - /** Internal logger instance to faciliate debugging. Enable logging output - * by editing /WEB-INF/conf/log4j.properties int the runtime environment - * and set com.arsdigita.cms.ui.BaseAdminPane=DEBUG - * by uncommenting or adding the line. */ - private static final Logger s_log = Logger.getLogger(BaseAdminPane.class); +public abstract class BaseAdminPane extends SelectionPanel { protected BaseAdminPane() { super(); @@ -56,13 +53,13 @@ public abstract class BaseAdminPane extends SelectionPanel { protected BaseAdminPane(final Component title, final Component selector, - final SingleSelectionModel model) { + final SingleSelectionModel model) { super(title, selector, model); } protected BaseAdminPane(final GlobalizedMessage title, final Component selector, - final SingleSelectionModel model) { + final SingleSelectionModel model) { super(title, selector, model); } @@ -93,4 +90,5 @@ public abstract class BaseAdminPane extends SelectionPanel { protected static String lz(final String key) { return (String) gz(key).localize(); } + } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/ReportPane.java.todo b/ccm-cms/src/main/java/com/arsdigita/cms/ui/ReportPane.java.todo index 04de51549..0eb5efee3 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/ReportPane.java.todo +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/ReportPane.java.todo @@ -15,7 +15,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - package com.arsdigita.cms.ui; import java.util.ArrayList; @@ -40,119 +39,133 @@ import com.arsdigita.toolbox.ui.Section; import com.arsdigita.util.LockableImpl; /** - * A pane that shows selectable reports and their results. - * A selectable list of reports is shown on the left-hand side, a selected report is shown as - * body. - * - * @author thomas-buckel - * @author tim-permeance + * A pane that shows selectable reports and their results. A selectable list of + * reports is shown on the left-hand side, a selected report is shown as body. + * + * @author + * thomas-buckel + * @author + * tim-permeance + * @author Jens Pelzetter */ -public class ReportPane extends BaseAdminPane { +public class ReportPane extends BaseAdminPane { - private final SingleSelectionModel m_selectionModel; - private final java.util.List m_availableReports; + private final SingleSelectionModel selectionModel; + private final java.util.List availableReports; public ReportPane() { - m_availableReports = getReports(); - - m_selectionModel = new ParameterSingleSelectionModel(new StringParameter(List.SELECTED)); - m_selectionModel.addChangeListener(new SelectionListener()); - setSelectionModel(m_selectionModel); + availableReports = getReports(); - List m_reports = new List(new ReportListModelBuilder(m_availableReports)); - m_reports.setSelectionModel(m_selectionModel); + selectionModel = new ParameterSingleSelectionModel<>( + new StringParameter(List.SELECTED)); + selectionModel.addChangeListener(new SelectionListener()); + setSelectionModel(selectionModel); - final ReportsListSection reportsListSection = new ReportsListSection(m_reports); + List m_reports = new List(new ReportListModelBuilder(availableReports)); + m_reports.setSelectionModel(selectionModel); + + final ReportsListSection reportsListSection = new ReportsListSection( + m_reports); setLeft(reportsListSection); // Register the actual components of the reports for later usage - for (Report report : m_availableReports) { - getBody().add(report.getComponent()); - } + for (Report report : availableReports) { + getBody().add(report.getComponent()); + } setIntroPane(new Label(gz("cms.ui.reports.intro"))); } - + /** * @return List of available reports. */ private java.util.List getReports() { - java.util.List reports = new ArrayList(); - reports.add(new Report("cms.ui.reports.css.reportName", new ContentSectionSummaryTable())); - // Add other reports as required - - Collections.sort(reports, new Comparator() { - @Override - public int compare(Report r1, Report r2) { - return r1.getName().compareTo(r2.getName()); - } - }); - return reports; + java.util.List reports = new ArrayList<>(); + reports.add(new Report("cms.ui.reports.css.reportName", + new ContentSectionSummaryTable())); + // Add other reports as required + + Collections.sort( + reports, + (r1, r2) -> r1.getName().compareTo(r2.getName())); + + return reports; } /** - * Get the report model that matches the given key. - * @param key Key to match. - * @return Report model that matches that given key, null if no matching report was found. + * Get the report model that matches the given key. + * + * @param key Key to match. + * + * @return Report model that matches that given key, null if no matching + * report was found. */ - private Report getReportByKey(String key) { - for (Report report : m_availableReports) { - if (report.getKey().equals(key)) { - return report; - } - } - return null; + private Report getReportByKey(final String key) { + for (Report report : availableReports) { + if (report.getKey().equals(key)) { + return report; + } + } + return null; } /** - * UI section for left-hand list of reports. + * UI section for left-hand list of reports. */ private class ReportsListSection extends Section { - ReportsListSection(List reports) { + + ReportsListSection(final List reports) { setHeading(gz("cms.ui.reports.header")); ActionGroup group = new ActionGroup(); setBody(group); group.setSubject(reports); } + } - + /** - * SelectionListener for selected report. It shows the selected report in the body of this - * component. + * SelectionListener for selected report. It shows the selected report in + * the body of this component. */ private class SelectionListener implements ChangeListener { - - public final void stateChanged(final ChangeEvent e) { - final PageState state = e.getPageState(); + @Override + public final void stateChanged(final ChangeEvent event) { + + final PageState state = event.getPageState(); getBody().reset(state); - - if (m_selectionModel.isSelected(state)) { - Report selectedReport = getReportByKey(m_selectionModel.getSelectedKey(state).toString()); - if (selectedReport != null) { - getBody().push(state, selectedReport.getComponent()); - } + + if (selectionModel.isSelected(state)) { + Report selectedReport = getReportByKey(selectionModel + .getSelectedKey(state).toString()); + if (selectedReport != null) { + getBody().push(state, selectedReport.getComponent()); + } } } - + } /** * ListModelBuilder creating a ReportListModel for a list of reports. */ - private static class ReportListModelBuilder extends LockableImpl implements ListModelBuilder { - - private java.util.List reports; - - private ReportListModelBuilder(java.util.List reports) { - this.reports = reports; - } - + private static class ReportListModelBuilder + extends LockableImpl + implements ListModelBuilder { + + private final java.util.List reports; + + private ReportListModelBuilder(final java.util.List reports) { + this.reports = reports; + } + + @Override public final ListModel makeModel(final List list, final PageState state) { - return new ReportListModel(reports); + return new ReportListModel(reports); } + } } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/report/ContentSectionSummaryController.java.todo b/ccm-cms/src/main/java/com/arsdigita/cms/ui/report/ContentSectionSummaryController.java.todo new file mode 100644 index 000000000..2ee3fbfc5 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/report/ContentSectionSummaryController.java.todo @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * This library 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 library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.cms.ui.report; + +import com.arsdigita.bebop.table.RowData; + +import org.libreccm.categorization.Categorization; +import org.libreccm.l10n.GlobalizationHelper; +import org.librecms.contentsection.ContentItem; +import org.librecms.contentsection.ContentItemManager; +import org.librecms.contentsection.ContentSection; +import org.librecms.contentsection.ContentSectionRepository; +import org.librecms.contentsection.ContentType; +import org.librecms.contentsection.Folder; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.transaction.Transactional; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +public class ContentSectionSummaryController { + + @Inject + private ContentSectionRepository sectionRepo; + + @Inject + private ContentItemManager itemManager; + + @Inject + private GlobalizationHelper globalizationHelper; + + @Transactional(Transactional.TxType.REQUIRED) + public List> createReportData(final ContentSection section) { + final ContentSection contentSection = sectionRepo.findById( + section.getObjectId()); + + final List rootFolders = contentSection.getRootDocumentsFolder() + .getSubFolders(); + + final List> data = new ArrayList<>(); + + for (final Folder folder : rootFolders) { + data.addAll(createFolderData(folder)); + } + + return data; + } + + private List> createFolderData(final Folder folder) { + final List> data = new ArrayList<>(); + + final long subFolderCount = countSubFolders(folder); + final List contentTypeInfo = generateContentTypeInfoForFolder( + folder); + + final RowData firstRow = new RowData<>(5); + firstRow.setRowKey(-1L); + firstRow.setColData(ContentSectionSummaryTable.COL_FOLDER_NAME, + folder.getDisplayName()); + firstRow.setColData(ContentSectionSummaryTable.COL_SUBFOLDER_COUNT, + Long.toString(subFolderCount)); + firstRow.setColData(ContentSectionSummaryTable.COL_CONTENT_TYPE, + contentTypeInfo.get(0).getTypeName()); + firstRow.setColData(ContentSectionSummaryTable.COL_CONTENT_TYPE, + Long.toString(contentTypeInfo.get(0).getDraftCount())); + firstRow.setColData(ContentSectionSummaryTable.COL_CONTENT_TYPE, + Long.toString(contentTypeInfo.get(0).getLiveCount())); + data.add(firstRow); + + for(int i = 1; i < contentTypeInfo.size(); i++) { + data.add(createRow(contentTypeInfo.get(i))); + } + + return data; + } + + private RowData createRow(final ContentTypeFolderInfo info) { + final RowData row = new RowData<>(5); + + row.setRowKey(-1L); + row.setColData(ContentSectionSummaryTable.COL_FOLDER_NAME, ""); + row.setColData(ContentSectionSummaryTable.COL_SUBFOLDER_COUNT, ""); + row.setColData(ContentSectionSummaryTable.COL_CONTENT_TYPE, + info.getTypeClassName()); + row.setColData(ContentSectionSummaryTable.COL_DRAFT_COUNT, + Long.toString(info.getDraftCount())); + row.setColData(ContentSectionSummaryTable.COL_LIVE_COUNT, + Long.toString(info.getLiveCount())); + + return row; + } + + private long countSubFolders(final Folder folder) { + long count = 0; + for (final Folder subFolder : folder.getSubFolders()) { + count++; + count += countSubFolders(subFolder); + } + + return count; + } + + private List generateContentTypeInfoForFolder( + final Folder folder) { + + final Map dataMap = new HashMap<>(); + generateContentTypeInfoForFolder(folder, dataMap); + final List data = new ArrayList<>(dataMap + .values()); + Collections.sort( + data, + (info1, info2) -> { + return info1.getTypeName().compareTo(info2.getTypeName()); + }); + return data; + } + + private void generateContentTypeInfoForFolder( + final Folder folder, final Map data) { + + for (final Categorization categorization : folder.getObjects()) { + if (!(categorization.getCategorizedObject() instanceof ContentItem)) { + continue; + } + + final ContentItem item = (ContentItem) categorization + .getCategorizedObject(); + final ContentType type = item.getContentType(); + + final ContentTypeFolderInfo info; + if (data.containsKey(type.getContentItemClass())) { + info = data.get(type.getContentItemClass()); + } else { + info = new ContentTypeFolderInfo( + type.getContentItemClass(), + type.getLabel().getValue(globalizationHelper + .getNegotiatedLocale())); + } + info.increaseDraftCount(); + if (itemManager.isLive(item)) { + info.increaseLiveCount(); + } + } + + for (final Folder subFolder : folder.getSubFolders()) { + generateContentTypeInfoForFolder(subFolder, data); + } + } + + private class ContentTypeFolderInfo { + + private final String typeClassName; + private final String typeName; + private long draftCount = 0; + private long liveCount = 0; + + public ContentTypeFolderInfo(final String typeClassName, + final String typeName) { + this.typeClassName = typeClassName; + this.typeName = typeName; + } + + public String getTypeClassName() { + return typeClassName; + } + + public String getTypeName() { + return typeName; + } + + public long getDraftCount() { + return draftCount; + } + + public void increaseDraftCount() { + draftCount++; + } + + public long getLiveCount() { + return liveCount; + } + + public void increaseLiveCount() { + liveCount++; + } + + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/report/ContentSectionSummaryReportTableModelBuilder.java.todo b/ccm-cms/src/main/java/com/arsdigita/cms/ui/report/ContentSectionSummaryReportTableModelBuilder.java.todo new file mode 100644 index 000000000..0c1b7a8ac --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/report/ContentSectionSummaryReportTableModelBuilder.java.todo @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2009 Permeance Technologies Pty Ltd. All Rights Reserved. + * + * This library 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 library 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 library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package com.arsdigita.cms.ui.report; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.Table; +import com.arsdigita.bebop.table.AbstractTableModelBuilder; +import com.arsdigita.bebop.table.TableModel; +import com.arsdigita.cms.CMS; +import org.librecms.contentsection.Folder; + +/** + * TableModelBuilder that creates a model for the content section summary + * report. + * + * @author + * thomas-buckel + * @author Jens Pelzetter + */ +public class ContentSectionSummaryReportTableModelBuilder + extends AbstractTableModelBuilder { + + @Override + public TableModel makeModel(final Table table, final PageState state) { + + + Session session = SessionManager.getSession(); + DataQuery query = session.retrieveQuery( + "com.arsdigita.cms.getContentSectionSummary"); + query.setParameter("sectionId", CMS.getContext().getContentSection() + .getID()); + return new CSSRModel(new DataQueryDataCollectionAdapter(query, "folder")); + } + + /** + * Generates a table model by combining a list of top level folder (content + * items) with statistics about content items with in the folder in draft + * and live versions. + */ + private class CSSRModel implements TableModel { + + private final DataCollection m_folders; + + private String m_folderName; + + private BigDecimal m_subfolderCount; + + private ContentTypeStatistics m_currentStatsRow; + + private Iterator m_contentTypeStatIter; + + CSSRModel(DataCollection folders) { + m_folders = folders; + } + + @Override + public final int getColumnCount() { + return 5; + } + + /** + * Combines an 'outer' iterator over the given DataCollection with an + * 'inner' iterator that contains rows for each row of the outer + * collection. {@inheritDoc} + */ + @Override + public final boolean nextRow() { + if ((m_contentTypeStatIter == null) && m_folders.next()) { + m_folderName = (String) m_folders.get("folder"); + m_subfolderCount = (BigDecimal) m_folders.get("subfolderCount"); + Folder draftFolder = new Folder((BigDecimal) m_folders.get( + "folderId")); + + m_contentTypeStatIter = retrieveContentTypeStats(draftFolder); + if (m_contentTypeStatIter.hasNext()) { + m_currentStatsRow = m_contentTypeStatIter.next(); + } else { + // Rather than recursing into nextRow() again, a m_currentStatsRow == null + // is rendered to show one row for the folder but with no content type or values. + m_contentTypeStatIter = null; + m_currentStatsRow = null; + } + return true; + } else if (m_contentTypeStatIter != null) { + if (m_contentTypeStatIter.hasNext()) { + m_currentStatsRow = m_contentTypeStatIter.next(); + } else { + m_contentTypeStatIter = null; + return nextRow(); + } + return true; + } else { + m_folders.close(); + return false; + } + } + + @Override + public final Object getKeyAt(final int column) { + return -1; + } + + @Override + public final Object getElementAt(final int column) { + switch (column) { + case 0: + return m_folderName; + case 1: + return m_subfolderCount.toString(); + case 2: + return (m_currentStatsRow != null) ? m_currentStatsRow + .getContentType() : "N/A"; + case 3: + return (m_currentStatsRow != null) ? m_currentStatsRow + .getDraftCount() : "N/A"; + case 4: + return (m_currentStatsRow != null) ? m_currentStatsRow + .getLiveCount() : "N/A"; + default: + throw new IllegalArgumentException("Illegal column index " + + column); + } + } + + /** + * Retrieve a list of content types used within a folder and for each + * content type the number of draft and live content items of this type. + * + * @param draftFolder Draft folder to retrieve stats for. + * + * @return Iterator over the retrieved statistics. Empty iterator with + * no results where found. + */ + private Iterator retrieveContentTypeStats( + Folder draftFolder) { + + Session session = SessionManager.getSession(); + + // Query the number of content items per content type for drafts + DataQuery query = session.retrieveQuery( + "com.arsdigita.cms.getContentTypeCountPerFolder"); + query.setParameter("folderId", draftFolder.getID()); + DataCollection types = new DataQueryDataCollectionAdapter(query, + "types"); + Map draftContentTypeCounts + = new HashMap(); + try { + while (types.next()) { + draftContentTypeCounts + .put((String) types.get("contentType"), (Long) types + .get("typeCount")); + } + } finally { + types.close(); + } + + // If there's a live version of the folder, query the number of content items per content type for it + // and merge both draft and live numbers + List result + = new ArrayList(); + Folder liveFolder = (Folder) draftFolder.getLiveVersion(); + if (liveFolder != null) { + query = session.retrieveQuery( + "com.arsdigita.cms.getContentTypeCountPerFolder"); + query.setParameter("folderId", liveFolder.getID()); + types = new DataQueryDataCollectionAdapter(query, "types"); + try { + while (types.next()) { + String contentType = (String) types.get("contentType"); + long draftCount = (draftContentTypeCounts.get( + contentType) != null) + ? draftContentTypeCounts + .get(contentType) : 0; + long liveCount = (Long) types.get("typeCount"); + result.add(new ContentTypeStatistics(contentType, + draftCount, + liveCount)); + draftContentTypeCounts.remove(contentType); + } + } finally { + types.close(); + } + } + + // Add all draft stats that haven't been merged + for (Map.Entry draftCount : draftContentTypeCounts + .entrySet()) { + result.add(new ContentTypeStatistics(draftCount.getKey(), + draftCount.getValue(), 0)); + } + + return result.iterator(); + } + + } + + /** + * Value object that holds content type statistics for a folder. + */ + private static class ContentTypeStatistics { + + private final String m_contentType; + + private final long m_draftCount; + + private final long m_liveCount; + + public ContentTypeStatistics(String contentType, long draftCount, + long liveCount) { + m_contentType = contentType; + m_draftCount = draftCount; + m_liveCount = liveCount; + } + + public String getContentType() { + return m_contentType; + } + + public long getDraftCount() { + return m_draftCount; + } + + public long getLiveCount() { + return m_liveCount; + } + + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/report/ContentSectionSummaryTable.java.todo b/ccm-cms/src/main/java/com/arsdigita/cms/ui/report/ContentSectionSummaryTable.java.todo new file mode 100644 index 000000000..63b5d7f44 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/report/ContentSectionSummaryTable.java.todo @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 Permeance Technologies Pty Ltd. All Rights Reserved. + * + * This library 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 library 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 library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package com.arsdigita.cms.ui.report; + +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.Table; + +/** + * Table component for content section summary report. + * + * @author + * thomas-buckel + */ +public class ContentSectionSummaryTable extends Table { + + public static final int COL_FOLDER_NAME = 0; + public static final int COL_SUBFOLDER_COUNT = 1; + public static final int COL_CONTENT_TYPE = 2; + public static final int COL_DRAFT_COUNT = 3; + public static final int COL_LIVE_COUNT = 4; + + private static final String[] s_fixedReportColumns = new String[]{ + lz("cms.ui.reports.css.folder"), + lz("cms.ui.reports.css.subfolderCount"), + lz("cms.ui.reports.css.contentType"), + lz("cms.ui.reports.css.draft"), + lz("cms.ui.reports.css.live"),}; + + public ContentSectionSummaryTable() { + super(new ContentSectionSummaryReportTableModelBuilder(), + s_fixedReportColumns); + setEmptyView(new Label(lz("cms.ui.reports.css.emptyResult"))); + } + + private static String lz(final String key) { + return (String) GlobalizationUtil.globalize(key).localize(); + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/report/Report.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/report/Report.java new file mode 100644 index 000000000..f3bb4d558 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/report/Report.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2009 Permeance Technologies Pty Ltd. All Rights Reserved. + * + * This library 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 library 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 library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package com.arsdigita.cms.ui.report; + +import com.arsdigita.bebop.Component; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.util.Assert; + +import org.librecms.CmsConstants; + +/** + * UI model for a report. + * A report has a name and a component that displays the report. + * + * @author thomas-buckel + * @author tim-permeance + * @author Jens Pelzetter + */ +public class Report { + + private final String key; + private final String name; + private final Component component; + + public Report(final String key, final Component component) { + Assert.exists(key, "Key for report is required"); + Assert.isTrue(key.length() > 0, "Key for report must not be empty"); + Assert.exists(component, "Component for report is required"); + + this.key = key; + name = gz(key).localize().toString(); + this.component = component; + } + + public String getKey() { + return key; + } + + public String getName() { + return name; + } + + public Component getComponent() { + return component; + } + + protected final static GlobalizedMessage gz(final String key) { + return new GlobalizedMessage(key, CmsConstants.CMS_BUNDLE); + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/report/ReportListModel.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/report/ReportListModel.java new file mode 100644 index 000000000..ebcca8a84 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/report/ReportListModel.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2009 Permeance Technologies Pty Ltd. All Rights Reserved. + * + * This library 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 library 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 library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package com.arsdigita.cms.ui.report; + +import java.util.List; + +import com.arsdigita.bebop.list.ListModel; +import com.arsdigita.util.Assert; + +/** + * ListModel for Reports. + * + * @author thomas-buckel + * @author tim-permeance + */ +public class ReportListModel implements ListModel { + + private int m_index = -1; + private final List m_reports; + + public ReportListModel(List reports) { + Assert.exists(reports); + m_reports = reports; + } + + @Override + public Object getElement() { + return m_reports.get(m_index).getName(); + } + + @Override + public String getKey() { + return m_reports.get(m_index).getKey(); + } + + @Override + public boolean next() { + m_index++; + return (m_reports.size() > m_index); + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/Folder.java b/ccm-cms/src/main/java/org/librecms/contentsection/Folder.java index 3c927c1c6..d9d5d1e03 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/Folder.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/Folder.java @@ -54,7 +54,8 @@ import static org.librecms.CmsConstants.*; name = "Folder.rootFolders", query = "SELECT f FROM Folder f " + "WHERE f.parentCategory IS NULL " - + " AND f.type = :type"), + + " AND f.type = :type") + , @NamedQuery( name = "Folder.findByName", query = "SELECT f FROM Folder f WHERE f.name = :name") @@ -92,7 +93,7 @@ public class Folder extends Category implements InheritsPermissions, protected void setType(final FolderType type) { this.type = type; } - + @Override public Optional getParent() { if (getParentFolder() == null) { @@ -110,10 +111,10 @@ public class Folder extends Category implements InheritsPermissions, public List getSubFolders() { return Collections.unmodifiableList( getSubCategories() - .stream() - .filter(subCategory -> subCategory instanceof Folder) - .map(subCategory -> (Folder) subCategory) - .collect(Collectors.toList())); + .stream() + .filter(subCategory -> subCategory instanceof Folder) + .map(subCategory -> (Folder) subCategory) + .collect(Collectors.toList())); } public Folder getParentFolder() { diff --git a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/SelectionPanel.java b/ccm-core/src/main/java/com/arsdigita/toolbox/ui/SelectionPanel.java index 055073a6d..fb6d7d8d4 100755 --- a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/SelectionPanel.java +++ b/ccm-core/src/main/java/com/arsdigita/toolbox/ui/SelectionPanel.java @@ -33,69 +33,73 @@ import com.arsdigita.bebop.list.ListModelBuilder; import com.arsdigita.bebop.tree.TreeModelBuilder; import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.util.Assert; -import org.apache.log4j.Logger; -/** - * TODO Needs description +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * @param Type managed by the {@link SingleSelectionModel} used in instances + * of this class. + * + * @author unknown + * @author Jens Pelzetter */ -public class SelectionPanel extends LayoutPanel implements Resettable { +public class SelectionPanel extends LayoutPanel implements Resettable { - private static final Logger s_log = Logger.getLogger(SelectionPanel.class); + private static final Logger LOGGER = LogManager.getLogger( + SelectionPanel.class); - private SingleSelectionModel m_model; - private Component m_selector; - private ActionGroup m_group; - private final ModalPanel m_body; + private SingleSelectionModel selectionModel; + private Component selector; + private ActionGroup actionGroup; + private final ModalPanel body; - private Component m_introPane; - private Component m_itemPane; + private Component introPane; + private Component itemPane; - private ActionLink m_addLink; - private Form m_addForm; - private ActionLink m_editLink; - private Form m_editForm; - private ActionLink m_deleteLink; - private Form m_deleteForm; + private ActionLink addLink; + private Form addForm; + private ActionLink editLink; + private Form editForm; + private ActionLink deleteLink; + private Form deleteForm; protected void build(final Component title, - final Component selector, - final SingleSelectionModel model) { - m_model = model; - m_selector = selector; + final Component selector, + final SingleSelectionModel model) { + selectionModel = model; + this.selector = selector; final Section section = new Section(); setLeft(section); section.setHeading(title); - m_group = new ActionGroup(); - section.setBody(m_group); + actionGroup = new ActionGroup(); + section.setBody(actionGroup); - m_group.setSubject(selector); + actionGroup.setSubject(selector); } protected SelectionPanel() { - m_body = new ModalPanel(); - setBody(m_body); + body = new ModalPanel(); + setBody(body); - m_introPane = new NullComponent(); - m_body.add(m_introPane); - m_body.setDefault(m_introPane); + introPane = new NullComponent(); + body.add(introPane); + body.setDefault(introPane); - m_itemPane = new NullComponent(); - m_body.add(m_itemPane); + itemPane = new NullComponent(); + body.add(itemPane); - m_addLink = null; - m_addForm = null; - m_editLink = null; - m_editForm = null; - m_deleteLink = null; - m_deleteForm = null; + addLink = null; + addForm = null; + editLink = null; + editForm = null; + deleteLink = null; + deleteForm = null; } - /** - * @pre selector instanceof Tree || selector instanceof List - */ public SelectionPanel(final Component title, final Component selector) { this(); @@ -107,7 +111,6 @@ public class SelectionPanel extends LayoutPanel implements Resettable { } // Making up now for some untoward modeling in Bebop. - if (selector instanceof List) { final List list = (List) selector; @@ -125,7 +128,7 @@ public class SelectionPanel extends LayoutPanel implements Resettable { public SelectionPanel(final Component title, final Component selector, - final SingleSelectionModel model) { + final SingleSelectionModel model) { this(); if (Assert.isEnabled()) { @@ -143,7 +146,7 @@ public class SelectionPanel extends LayoutPanel implements Resettable { public SelectionPanel(final GlobalizedMessage title, final Component selector, - final SingleSelectionModel model) { + final SingleSelectionModel model) { this(new Label(title), selector, model); } @@ -169,12 +172,12 @@ public class SelectionPanel extends LayoutPanel implements Resettable { @Override public void reset(final PageState state) { - s_log.debug("Resetting to default initial state"); + LOGGER.debug("Resetting to default initial state"); - if (m_selector instanceof Resettable) { - ((Resettable) m_selector).reset(state); + if (selector instanceof Resettable) { + ((Resettable) selector).reset(state); } else { - m_model.clearSelection(state); + selectionModel.clearSelection(state); } // The SelectionListener, on hearing the clearSelection event, @@ -182,35 +185,35 @@ public class SelectionPanel extends LayoutPanel implements Resettable { } public final void addAction(final Component action) { - m_group.addAction(action); + actionGroup.addAction(action); } public final void addAction(final Component action, final String clacc) { - m_group.addAction(action, clacc); + actionGroup.addAction(action, clacc); } public final Component getSelector() { - return m_selector; + return selector; } - protected final void setSelector(Component selector) { - m_selector = selector; + protected final void setSelector(final Component selector) { + this.selector = selector; } - public final void setSelectionModel(final SingleSelectionModel model) { - m_model = model; + public final void setSelectionModel(final SingleSelectionModel model) { + selectionModel = model; } - public final SingleSelectionModel getSelectionModel() { - return m_model; + public final SingleSelectionModel getSelectionModel() { + return selectionModel; } public final ActionLink getAddLink() { - return m_addLink; + return addLink; } public final Form getAddForm() { - return m_addForm; + return addForm; } public final void setAdd(final GlobalizedMessage message, @@ -224,20 +227,20 @@ public class SelectionPanel extends LayoutPanel implements Resettable { Assert.exists(form, "Form form"); Assert.isUnlocked(this); - m_addForm = form; - m_body.add(m_addForm); + addForm = form; + body.add(addForm); - m_addLink = addLink; + this.addLink = addLink; - m_body.connect(m_addLink, m_addForm); + body.connect(addLink, addForm); } public final ActionLink getEditLink() { - return m_editLink; + return editLink; } public final Form getEditForm() { - return m_editForm; + return editForm; } public final void setEdit(final GlobalizedMessage message, @@ -251,21 +254,21 @@ public class SelectionPanel extends LayoutPanel implements Resettable { Assert.exists(form, "Form form"); Assert.isUnlocked(this); - m_editForm = form; - m_body.add(m_editForm); + editForm = form; + body.add(editForm); - m_editLink = editLink; + this.editLink = editLink; - m_body.connect(m_editLink, m_editForm); - m_body.connect(m_editForm); + body.connect(editLink, editForm); + body.connect(editForm); } public final ActionLink getDeleteLink() { - return m_deleteLink; + return deleteLink; } public final Form getDeleteForm() { - return m_deleteForm; + return deleteForm; } public final void setDelete(final GlobalizedMessage message, @@ -279,59 +282,62 @@ public class SelectionPanel extends LayoutPanel implements Resettable { Assert.exists(form, "Form form"); Assert.isUnlocked(this); - m_deleteForm = form; - m_body.add(m_deleteForm); + deleteForm = form; + body.add(deleteForm); - m_deleteLink = deleteLink; + this.deleteLink = deleteLink; - m_body.connect(m_deleteLink, m_deleteForm); + body.connect(deleteLink, deleteForm); } public final ModalPanel getBody() { - return m_body; + return body; } public final Component getIntroPane() { - return m_introPane; + return introPane; } public final void setIntroPane(final Component pane) { Assert.exists(pane, Component.class); Assert.isUnlocked(this); - m_introPane = pane; - m_body.add(m_introPane); - m_body.setDefault(m_introPane); + introPane = pane; + body.add(introPane); + body.setDefault(introPane); } public final Component getItemPane() { - return m_itemPane; + return itemPane; } public final void setItemPane(final Component pane) { Assert.exists(pane, "Component pane"); Assert.isUnlocked(this); - m_itemPane = pane; - m_body.add(m_itemPane); + itemPane = pane; + body.add(itemPane); } public class SelectionListener implements ChangeListener { + @Override public final void stateChanged(final ChangeEvent e) { - s_log.debug("Selection state changed; I may change " + - "the body's visible pane"); + LOGGER.debug("Selection state changed; I may change " + + "the body's visible pane"); final PageState state = e.getPageState(); - m_body.reset(state); + body.reset(state); - if (m_model.isSelected(state)) { - s_log.debug("The selection model is selected; displaying " + - "the item pane"); + if (selectionModel.isSelected(state)) { + LOGGER.debug("The selection model is selected; displaying " + + "the item pane"); - m_body.push(state, m_itemPane); + body.push(state, itemPane); } } + } + }