diff --git a/ccm-sci-project-navigation/application.xml b/ccm-sci-project-navigation/application.xml new file mode 100644 index 000000000..f793a189b --- /dev/null +++ b/ccm-sci-project-navigation/application.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + Provides special navigation components for displaying lists of publications. + + + diff --git a/ccm-sci-project-navigation/src/ccm-sci-project-navigation.config b/ccm-sci-project-navigation/src/ccm-sci-project-navigation.config new file mode 100644 index 000000000..0ece1ac86 --- /dev/null +++ b/ccm-sci-project-navigation/src/ccm-sci-project-navigation.config @@ -0,0 +1,3 @@ + + + diff --git a/ccm-sci-project-navigation/src/ccm-sci-project-navigation.load b/ccm-sci-project-navigation/src/ccm-sci-project-navigation.load new file mode 100644 index 000000000..c4bf456c0 --- /dev/null +++ b/ccm-sci-project-navigation/src/ccm-sci-project-navigation.load @@ -0,0 +1,15 @@ + + + +
+
+
+ + + + + + + + + diff --git a/ccm-sci-project-navigation/src/com/arsdigita/cms/sciproject/navigation/SciProjectList.java b/ccm-sci-project-navigation/src/com/arsdigita/cms/sciproject/navigation/SciProjectList.java new file mode 100644 index 000000000..5f64ba4a3 --- /dev/null +++ b/ccm-sci-project-navigation/src/com/arsdigita/cms/sciproject/navigation/SciProjectList.java @@ -0,0 +1,313 @@ +package com.arsdigita.cms.sciproject.navigation; + +import com.arsdigita.navigation.Navigation; +import com.arsdigita.navigation.ui.AbstractComponent; +import com.arsdigita.persistence.SessionManager; +import com.arsdigita.util.UncheckedWrapperException; +import com.arsdigita.xml.Element; + +import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Calendar; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author Jens Pelzetter + */ +public class SciProjectList extends AbstractComponent { + + private static final String PROJECTS_QUERY_TEMPLATE + = "SELECT cms_items.item_id, name, version, language, object_type, " + + "master_id, parent_id, title, cms_pages.description as page_description, " + + "projectbegin, projectbegin_skip_month, projectbegin_skip_day, " + + "projectend, projectend_skip_month, projectend_skip_day, " + + "shortdesc, ct_sci_projects.description AS project_description, funding, funding_volume " + + "FROM cms_items " + + "JOIN cms_pages ON cms_items.item_id = cms_pages.item_id " + + "JOIN content_types ON cms_items.type_id = content_types.type_id " + + "JOIN ct_sci_projects ON cms_items.item_id = ct_sci_projects.project_id " + + "WHERE parent_id IN (SELECT object_id FROM cat_object_category_map WHERE category_id = ?) AND version = 'live' %s" + + "%s" + + "LIMIT ? OFFSET ?"; + + private static final String COUNT_PROJECTS_QUERY_TEMPLATE + = "SELECT COUNT(*) " + + "FROM cms_items " + + "JOIN cms_pages ON cms_items.item_id = cms_pages.item_id " + + "JOIN content_types ON cms_items.type_id = content_types.type_id " + + "JOIN ct_sci_projects ON cms_items.item_id = ct_sci_projects.project_id " + + "WHERE parent_id IN (SELECT object_id FROM cat_object_category_map WHERE category_id = ?) AND version = 'live' %s"; + + private final PreparedStatement projectMembersQueryStatement; + + private int limit = 20; + + public SciProjectList() { + + try { + final Connection connection = SessionManager + .getSession() + .getConnection(); + + projectMembersQueryStatement = connection.prepareStatement( + "SELECT surname, givenname, titlepre, titlepost " + + "FROM cms_persons " + + "JOIN cms_items ON cms_persons.person_id = cms_items.item_id " + + "JOIN cms_bundles ON cms_items.parent_id = cms_bundles.bundle_id " + + "JOIN cms_orgaunits_person_map ON cms_bundles.bundle_id = cms_orgaunits_person_map.person_id " + + "WHERE orgaunit_id = ? " + + "ORDER BY surname, givenname" + ); + } catch (SQLException ex) { + throw new UncheckedWrapperException(ex); + } + + } + + public int getLimit() { + return limit; + } + + public void setLimit(final int limit) { + this.limit = limit; + } + + @Override + public Element generateXML(final HttpServletRequest request, + final HttpServletResponse response) { + + final Connection connection = SessionManager + .getSession() + .getConnection(); + + final String categoryId = getCategory().getID().toString(); + + final Element listElem = Navigation.newElement( + "sci-project-list"); + final Element filtersElem = listElem.newChildElement("filters"); + final Element sortElem = filtersElem.newChildElement("sort"); + + final PreparedStatement projectsQueryStatement; + final StringBuffer whereBuffer = new StringBuffer(); + final int page; + final int offset; + try { + final String titleFilter = request.getParameter("title"); + final BigDecimal categoryFilter; + if (request.getParameter("category") == null) { + categoryFilter = null; + } else if (request.getParameter("category").matches("\\d*")) { + categoryFilter + = new BigDecimal(request.getParameter("category")); + } else { + categoryFilter = null; + } + + if (titleFilter != null && !titleFilter.trim().isEmpty() + || categoryFilter != null) { + + whereBuffer.append(" AND "); + } + if (titleFilter != null && !titleFilter.trim().isEmpty()) { + whereBuffer + .append("LOWER(title) LIKE '%%") + .append(titleFilter.toLowerCase()) + .append("%%' "); + final Element titleFilterElem = filtersElem + .newChildElement("title"); + titleFilterElem.setText(titleFilter); + } + if (categoryFilter != null) { + if (titleFilter != null && !titleFilter.trim().isEmpty()) { + whereBuffer.append(" AND "); + } + + whereBuffer.append("parent_id IN (SELECT object_id " + + "FROM cat_object_category_map " + + "WHERE category_id = ") + .append(categoryFilter.toString()) + .append(") "); + } + + final String orderBy + = "ORDER BY projectbegin DESC, projectend DESC, title ASC "; + + projectsQueryStatement = connection + .prepareStatement(String.format(PROJECTS_QUERY_TEMPLATE, + whereBuffer.toString(), + orderBy)); + projectsQueryStatement.setString(1, categoryId); + projectsQueryStatement.setInt(2, limit); + + if (request.getParameter("page") == null) { + page = 1; + projectsQueryStatement.setInt(3, 0); + offset = 0; + } else { + page = Integer.parseInt(request.getParameter("page")); + offset = (page - 1) * limit; + + projectsQueryStatement.setInt(3, offset); + } + + } catch (SQLException ex) { + throw new UncheckedWrapperException(ex); + } + + try (final ResultSet mainQueryResult = projectsQueryStatement + .executeQuery()) { + + final Element paginatorElem = listElem.newChildElement("paginator"); + + final PreparedStatement countProjectQueryStatement = connection + .prepareStatement(String.format(COUNT_PROJECTS_QUERY_TEMPLATE, + whereBuffer.toString())); + + countProjectQueryStatement.setString(1, categoryId); + final ResultSet countResultSet = countProjectQueryStatement + .executeQuery(); + final int count; + if (countResultSet.next()) { + count = countResultSet.getInt(1); + paginatorElem.addAttribute("count", Integer.toString(count)); + } else { + count = 0; + } + + final int maxPages = (int) Math.ceil(count / (double) limit); + + paginatorElem.addAttribute("maxPages", Integer.toString(maxPages)); + paginatorElem.addAttribute("currentPage", Integer.toString(page)); + paginatorElem.addAttribute("offset", Integer.toString(offset)); + paginatorElem.addAttribute("limit", Integer.toString(limit)); + + while (mainQueryResult.next()) { + + generateResultEntry(mainQueryResult, listElem); + } + + return listElem; + + } catch (SQLException ex) { + throw new UncheckedWrapperException(ex); + } + } + + private void generateResultEntry(final ResultSet resultSet, + final Element parent) throws SQLException { + + final Element projectElem = parent.newChildElement("project"); + + final Element itemIdElem = projectElem.newChildElement("item-id"); + itemIdElem.setText(resultSet.getBigDecimal("item_id").toString()); + + final Element parentIdElem = projectElem + .newChildElement("parent-id"); + parentIdElem.setText(resultSet.getBigDecimal("parent_id").toString()); + + final Element nameElem = projectElem.newChildElement("name"); + nameElem.setText(resultSet.getString("name")); + + projectElem.addAttribute("object-type", + resultSet.getString("object_type")); + + final Element titleElem = projectElem.newChildElement("title"); + titleElem.setText(resultSet.getString("title")); + + final String description = resultSet.getString("page_description"); + if (description != null && !description.trim().isEmpty()) { + final Element descriptionElem = projectElem + .newChildElement("description"); + descriptionElem.setText(description); + } + + if (resultSet.getDate("projectbegin") != null) { + + final Element projectBeginElem = projectElem.newChildElement( + "project-begin"); + final Calendar projectBegin = Calendar.getInstance(); + projectBegin.setTime(resultSet.getDate("projectbegin")); + + projectBeginElem.addAttribute("year", Integer.toString(projectBegin + .get(Calendar.YEAR))); + projectBeginElem.addAttribute("month", Integer.toString(projectBegin + .get(Calendar.MONTH))); + projectBeginElem.addAttribute("day", Integer.toString(projectBegin + .get(Calendar.DAY_OF_MONTH))); + + projectBeginElem.addAttribute( + "skip-month", + Boolean + .toString(resultSet.getBoolean("projectbegin_skip_month"))); + projectBeginElem.addAttribute( + "skip-day", + Boolean.toString(resultSet.getBoolean("projectbegin_skip_day"))); + } + + if (resultSet.getDate("projectend") != null) { + + final Element projectBeginElem = projectElem.newChildElement( + "project-begin"); + final Calendar projectBegin = Calendar.getInstance(); + projectBegin.setTime(resultSet.getDate("projectend")); + + projectBeginElem.addAttribute("year", Integer.toString(projectBegin + .get(Calendar.YEAR))); + projectBeginElem.addAttribute("month", Integer.toString(projectBegin + .get(Calendar.MONTH))); + projectBeginElem.addAttribute("day", Integer.toString(projectBegin + .get(Calendar.DAY_OF_MONTH))); + + projectBeginElem.addAttribute( + "skip-month", + Boolean + .toString(resultSet.getBoolean("projectend_skip_month"))); + projectBeginElem.addAttribute( + "skip-day", + Boolean.toString(resultSet.getBoolean("projectend_skip_day"))); + } + + final Element shortDescElem = projectElem.newChildElement("project-short-desc"); + shortDescElem.setText(resultSet.getString("shortdesc")); + + final Element descriptionElem = projectElem.newChildElement( + "project-description"); + descriptionElem.setText(resultSet.getString("project_description")); + + generateMembers(resultSet.getBigDecimal("parent_id"), + projectElem); + } + + private void generateMembers(final BigDecimal projectId, + final Element projectElem) + throws SQLException { + + projectMembersQueryStatement.setBigDecimal(1, projectId); + + try (final ResultSet resultSet = projectMembersQueryStatement + .executeQuery()) { + + final Element membersElem = projectElem.newChildElement("members"); + + while (resultSet.next()) { + final Element memberElem = membersElem.newChildElement("member"); + memberElem.addAttribute("surname", resultSet + .getString("surname")); + memberElem.addAttribute("givenname", + resultSet.getString("givenname")); + memberElem.addAttribute("titlepre", resultSet.getString( + "titlepre")); + memberElem.addAttribute("titlepost", + resultSet.getString("titlepost")); + } + } + + } + +} diff --git a/ccm-sci-publications-navigation/src/com/arsdigita/cms/scipublications/navigation/PublicationList.java b/ccm-sci-publications-navigation/src/com/arsdigita/cms/scipublications/navigation/PublicationList.java index 12d290ffa..6d3b2df9b 100644 --- a/ccm-sci-publications-navigation/src/com/arsdigita/cms/scipublications/navigation/PublicationList.java +++ b/ccm-sci-publications-navigation/src/com/arsdigita/cms/scipublications/navigation/PublicationList.java @@ -34,7 +34,7 @@ import javax.servlet.http.HttpServletResponse; * * This component uses native SQL queries to create the list. * - * Note: This is only a temporary soluation which will be removed in Version + * Note: This is only a temporary solution which will be removed in Version * 7.0.0 when we completed the migration to JPA/Hibernate. * * @author Jens Pelzetter @@ -410,8 +410,7 @@ public class PublicationList extends AbstractComponent { count = 0; } - final int maxPages = (int) Math - .ceil(count / (double) limit); + final int maxPages = (int) Math.ceil(count / (double) limit); paginatorElem.addAttribute("maxPages", Integer.toString(maxPages)); paginatorElem.addAttribute("currentPage", Integer.toString(page));