From 1815a1f7f6135219a4946d4e13aa6bb963d4c687 Mon Sep 17 00:00:00 2001 From: pb Date: Fri, 28 Aug 2009 16:32:01 +0000 Subject: [PATCH] Integrating r1936 - ccm-cms: Added new Reports tab to the content center, initially with 'Content Section Summar' report. git-svn-id: https://svn.libreccm.org/ccm/trunk@248 8810af33-2d31-482b-a856-94f89814c4df --- .../content-section/Report-queries.pdl | 68 +++++ .../arsdigita/cms/ui/CMSResources.properties | 15 + .../arsdigita/cms/ui/ContentSectionPage.java | 11 + .../src/com/arsdigita/cms/ui/ReportPane.java | 158 +++++++++++ ...SectionSummaryReportTableModelBuilder.java | 263 ++++++++++++++++++ .../ui/report/ContentSectionSummaryTable.java | 48 ++++ .../com/arsdigita/cms/ui/report/Report.java | 65 +++++ .../cms/ui/report/ReportListModel.java | 58 ++++ 8 files changed, 686 insertions(+) create mode 100644 ccm-cms/pdl/com/arsdigita/content-section/Report-queries.pdl create mode 100644 ccm-cms/src/com/arsdigita/cms/ui/ReportPane.java create mode 100644 ccm-cms/src/com/arsdigita/cms/ui/report/ContentSectionSummaryReportTableModelBuilder.java create mode 100644 ccm-cms/src/com/arsdigita/cms/ui/report/ContentSectionSummaryTable.java create mode 100644 ccm-cms/src/com/arsdigita/cms/ui/report/Report.java create mode 100644 ccm-cms/src/com/arsdigita/cms/ui/report/ReportListModel.java diff --git a/ccm-cms/pdl/com/arsdigita/content-section/Report-queries.pdl b/ccm-cms/pdl/com/arsdigita/content-section/Report-queries.pdl new file mode 100644 index 000000000..6a89369af --- /dev/null +++ b/ccm-cms/pdl/com/arsdigita/content-section/Report-queries.pdl @@ -0,0 +1,68 @@ +// +// 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 +// + +model com.arsdigita.cms; + +query getContentSectionSummary { + BigDecimal folderId; + String folder; + BigDecimal subfolderCount; + + do { + SELECT ci.item_id as folder_id, + ci.name AS folder, + (SELECT COUNT(*)-1 + FROM cms_items ci2 + WHERE ci2.type_id is null + START WITH ci2.item_id = ci.item_id + CONNECT BY PRIOR ci2.item_id = ci2.parent_id + ) AS subfolder_count + FROM content_sections cs, + cms_items ci + WHERE ci.section_id = cs.section_id + AND cs.section_id = :sectionId + AND ci.type_id is null + AND ci.master_id is null + AND ((ci.parent_id = cs.root_folder_id) or (ci.item_id = cs.root_folder_id)) + order by ci.name + } map { + folderId = folder_id; + folder = folder; + subfolderCount = subfolder_count; + } +} + +query getContentTypeCountPerFolder { + String contentType; + Long typeCount; + + do { + SELECT ct.label as content_type, + COUNT(*) as type_count + FROM content_types ct, + (SELECT * + FROM cms_items ci + START WITH ci.parent_id = :folderId + CONNECT BY PRIOR ci.item_id = ci.parent_id and ci.language is null) ci + WHERE ci.type_id = ct.type_id + GROUP BY ct.label + } map { + contentType = content_type; + typeCount = type_count; + } +} diff --git a/ccm-cms/src/com/arsdigita/cms/ui/CMSResources.properties b/ccm-cms/src/com/arsdigita/cms/ui/CMSResources.properties index d13ae9475..56ad542fa 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/CMSResources.properties +++ b/ccm-cms/src/com/arsdigita/cms/ui/CMSResources.properties @@ -823,3 +823,18 @@ Thank you for using {3}.\n cms.contentassets.ui.description=Description cms.ui.content_check_alert.subject=Content Check Alert cms.ui.content_check_alert.body=Dear Author\n\nYou are listed as the Content Owner for the following {0} web page(s). Please check if they need amending or updating in any way:\n\n{1}\nIf you have any amendments or questions please email the appropriate web editor:\n\nsally.editor@aplaws.org (Council & Democracy, Environment, Education)\njohn.editor@aplaws.org (Community & Living, Business, Social Care)\nfrank.editor@aplaws.org (Council & Democracy, Environment, Education)\n\nYou can contact webmanager@aplaws.org with any questions about this email\n +# +# Reports section +# +cms.ui.reports=Reports +cms.ui.reports.header=Reports +cms.ui.reports.intro=Please select a report. +# Columns for ContentSectionSummary report +cms.ui.reports.css.emptyResult=No matching content items found. +cms.ui.reports.css.reportName=Content Section Summary +cms.ui.reports.css.contentSection=Content Section +cms.ui.reports.css.folder=Folder +cms.ui.reports.css.subfolderCount=Subfolders +cms.ui.reports.css.contentType=Content Type +cms.ui.reports.css.draft=Draft +cms.ui.reports.css.live=Live diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ContentSectionPage.java b/ccm-cms/src/com/arsdigita/cms/ui/ContentSectionPage.java index ebb8eada0..4a5ff5c80 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/ContentSectionPage.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ContentSectionPage.java @@ -142,6 +142,7 @@ public class ContentSectionPage extends CMSPage implements ActionListener { private ContentTypeAdminPane m_typePane; private UserAdminPane m_userAdminPane; private ContentSoonExpiredPane m_csePane; + private ReportPane m_reportPane; private static class TitlePrinter implements PrintListener { public void prepare(PrintEvent e) { @@ -173,6 +174,7 @@ public class ContentSectionPage extends CMSPage implements ActionListener { m_typePane = getContentTypeAdminPane(); m_userAdminPane = getUserAdminPane(); m_csePane = getCSEPane(); + m_reportPane = getReportPane(); // The panes m_tabbedPane = createTabbedPane(); @@ -204,6 +206,7 @@ public class ContentSectionPage extends CMSPage implements ActionListener { m_tabbedPane.setTabVisible(state, m_rolePane, sm.canAccess(user,SecurityConstants.STAFF_ADMIN)); // csePane: should check permission m_tabbedPane.setTabVisible(state, m_csePane, true); + // TODO Check for reportPane as well } } }); @@ -313,6 +316,13 @@ public class ContentSectionPage extends CMSPage implements ActionListener { return m_csePane; } + protected ReportPane getReportPane() { + if (m_reportPane == null) { + m_reportPane = new ReportPane(); + } + return m_reportPane; + } + /** * Adds the specified component, with the specified tab name, to * the tabbed pane only if it is not null. @@ -359,6 +369,7 @@ public class ContentSectionPage extends CMSPage implements ActionListener { tab(pane, "cms.ui.content_types", getContentTypeAdminPane()); tab(pane, "cms.ui.user_admin", getUserAdminPane()); tab(pane, "cms.ui.cse", getCSEPane()); + tab(pane, "cms.ui.reports", getReportPane()); return pane; } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ReportPane.java b/ccm-cms/src/com/arsdigita/cms/ui/ReportPane.java new file mode 100644 index 000000000..b754384f1 --- /dev/null +++ b/ccm-cms/src/com/arsdigita/cms/ui/ReportPane.java @@ -0,0 +1,158 @@ +/* + * 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; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; + +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.List; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.ParameterSingleSelectionModel; +import com.arsdigita.bebop.SingleSelectionModel; +import com.arsdigita.bebop.event.ChangeEvent; +import com.arsdigita.bebop.event.ChangeListener; +import com.arsdigita.bebop.list.ListModel; +import com.arsdigita.bebop.list.ListModelBuilder; +import com.arsdigita.bebop.parameters.StringParameter; +import com.arsdigita.cms.ui.report.ContentSectionSummaryTable; +import com.arsdigita.cms.ui.report.Report; +import com.arsdigita.cms.ui.report.ReportListModel; +import com.arsdigita.toolbox.ui.ActionGroup; +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 + */ +public class ReportPane extends BaseAdminPane { + + private final SingleSelectionModel m_selectionModel; + private final java.util.List m_availableReports; + + public ReportPane() { + m_availableReports = getReports(); + + m_selectionModel = new ParameterSingleSelectionModel(new StringParameter(List.SELECTED)); + m_selectionModel.addChangeListener(new SelectionListener()); + setSelectionModel(m_selectionModel); + + List m_reports = new List(new ReportListModelBuilder(m_availableReports)); + m_reports.setSelectionModel(m_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()); + } + + 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; + } + + /** + * 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; + } + + /** + * UI section for left-hand list of reports. + */ + private class ReportsListSection extends Section { + ReportsListSection(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. + */ + private class SelectionListener implements ChangeListener { + + public final void stateChanged(final ChangeEvent e) { + + final PageState state = e.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()); + } + } + } + + } + + /** + * 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; + } + + public final ListModel makeModel(final List list, + final PageState state) { + return new ReportListModel(reports); + } + } + +} diff --git a/ccm-cms/src/com/arsdigita/cms/ui/report/ContentSectionSummaryReportTableModelBuilder.java b/ccm-cms/src/com/arsdigita/cms/ui/report/ContentSectionSummaryReportTableModelBuilder.java new file mode 100644 index 000000000..5df8caead --- /dev/null +++ b/ccm-cms/src/com/arsdigita/cms/ui/report/ContentSectionSummaryReportTableModelBuilder.java @@ -0,0 +1,263 @@ +/* + * 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 com.arsdigita.cms.Folder; +import com.arsdigita.persistence.DataCollection; +import com.arsdigita.persistence.DataQuery; +import com.arsdigita.persistence.DataQueryDataCollectionAdapter; +import com.arsdigita.persistence.Session; +import com.arsdigita.persistence.SessionManager; + +/** + * TableModelBuilder that creates a model for the content section summary report. + * + * @author thomas-buckel + */ +public class ContentSectionSummaryReportTableModelBuilder extends AbstractTableModelBuilder +{ + + @Override + public TableModel makeModel(Table t, PageState s) + { + 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/com/arsdigita/cms/ui/report/ContentSectionSummaryTable.java b/ccm-cms/src/com/arsdigita/cms/ui/report/ContentSectionSummaryTable.java new file mode 100644 index 000000000..fa63b0728 --- /dev/null +++ b/ccm-cms/src/com/arsdigita/cms/ui/report/ContentSectionSummaryTable.java @@ -0,0 +1,48 @@ +/* + * 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; +import com.arsdigita.cms.util.GlobalizationUtil; + +/** + * Table component for content section summary report. + * + * @author thomas-buckel + */ +public class ContentSectionSummaryTable extends Table +{ + + 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/com/arsdigita/cms/ui/report/Report.java b/ccm-cms/src/com/arsdigita/cms/ui/report/Report.java new file mode 100644 index 000000000..738443a4f --- /dev/null +++ b/ccm-cms/src/com/arsdigita/cms/ui/report/Report.java @@ -0,0 +1,65 @@ +/* + * 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.cms.util.GlobalizationUtil; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.util.Assert; + +/** + * UI model for a report. + * A report has a name and a component that displays the report. + * + * @author thomas-buckel + * @author tim-permeance + */ +public class Report { + + private final String m_key; + private final String m_name; + private final Component m_component; + + public Report(String key, 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"); + + m_key = key; + m_name = gz(m_key).localize().toString(); + m_component = component; + } + + public String getKey() { + return m_key; + } + + public String getName() { + return m_name; + } + + public Component getComponent() { + return m_component; + } + + protected final static GlobalizedMessage gz(final String key) { + return GlobalizationUtil.globalize(key); + } + +} diff --git a/ccm-cms/src/com/arsdigita/cms/ui/report/ReportListModel.java b/ccm-cms/src/com/arsdigita/cms/ui/report/ReportListModel.java new file mode 100644 index 000000000..6c2719f39 --- /dev/null +++ b/ccm-cms/src/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); + } + +}