/* * This is eMonocot, a global online biodiversity information resource. * * Copyright © 2011–2015 The Board of Trustees of the Royal Botanic Gardens, Kew and The University of Oxford * * eMonocot is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * eMonocot 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 Affero General Public License for more details. * * The complete text of the GNU Affero General Public License is in the source repository as the file * ‘COPYING’. It is also available from <http://www.gnu.org/licenses/>. */ package org.emonocot.pager; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.HashMap; import java.util.Collections; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.response.FacetField; import org.apache.solr.client.solrj.response.PivotField; import org.apache.solr.client.solrj.response.QueryResponse; public class CellSet { public static Level count = null; static { CellSet.count = new Level("count",null, false); CellSet.count.addMember(0, "count", "count"); } private Cube cube; private Level rows; private Level columns; private Integer nRows = 0; private Integer nCols = 0; private Integer firstRow; private Integer maxRows; private Integer firstCol; private Integer maxCols; private Integer totalRowsCount; private Integer totalColsCount; private Number[][] cells = new Number[0][0]; private Map<String,String> selectedFacets; private QueryResponse queryResponse; private FacetField totalRows; private FacetField totalCols; public CellSet(QueryResponse response, Map<String,String> selectedFacets, SolrQuery query, String rows, String columns, Integer firstRow, Integer maxRows, Integer firstCol, Integer maxCols,FacetField totalRows, FacetField totalCols, Cube cube) { this.cube = cube; this.totalRows = totalRows; this.totalCols = totalCols; this.firstCol = firstCol; this.maxCols = maxCols; this.firstRow = firstRow; this.maxRows = maxRows; this.queryResponse = response; this.selectedFacets = selectedFacets; this.rows = cube.getLevel(rows); if(columns != null) { this.columns = cube.getLevel(columns); FacetField rowField = response.getFacetField(rows); nRows = rowField.getValues().size(); for(int i = 0; i < nRows; i++) { this.rows.addMember(i, rows, rowField.getValues().get(i).getName()); } FacetField colField = response.getFacetField(columns); if(colField.getValueCount() < firstCol) { nCols = 0; } else if(colField.getValueCount() < firstCol + maxCols) { nCols = colField.getValueCount() - firstCol; } else { nCols = maxCols; } for(int i = 0; i < nCols; i++) { this.columns.addMember(i, columns, colField.getValues().get(firstCol + i).getName()); } cells = new Number[nRows][nCols]; for(PivotField rField : response.getFacetPivot().get(rows + "," + columns)) { Member rMember = null; if(rField.getValue() != null) { rMember = this.rows.getMember(rField.getValue().toString()); } else { rMember = this.rows.getMember((String)rField.getValue()); } int i = rMember.getOrdinal(); for(PivotField cField : rField.getPivot()) { Member cMember = null; if(cField.getValue() != null) { cMember = this.columns.getMember(cField.getValue().toString()); } else { cMember = this.columns.getMember((String)cField.getValue()); } if(cMember != null) { int j = cMember.getOrdinal(); cells[i][j] = cField.getCount(); } } } } else if(rows != null) { this.columns = CellSet.count; this.totalColsCount = 1; // no cols, rows calculated through standard facet FacetField rowField = response.getFacetField(rows); nRows = rowField.getValues().size(); nCols = 1; cells = new Number[nRows][nCols]; for(int i = 0; i < nRows; i++) { this.rows.addMember(i, rows, rowField.getValues().get(i).getName()); cells[i][0] = rowField.getValues().get(i).getCount(); } } else { this.columns = CellSet.count; this.totalColsCount = 1; this.rows = cube.getLevel(cube.getDefaultLevel()); // no cols or rows rows calculated through default facet FacetField rowField = response.getFacetField(cube.getDefaultLevel()); nRows = rowField.getValues().size(); nCols = 1; cells = new Number[nRows][nCols]; for(int i = 0; i < nRows; i++) { this.rows.addMember(i, rows, rowField.getValues().get(i).getName()); cells[i][0] = rowField.getValues().get(i).getCount(); } } } /** * The member which represents the columns */ public Level getColumns() { return columns; } /** * The member which represents the rows */ public Level getRows() { return rows; } /** * The cell value at ordinal i,j where i is the row and j is the column */ public Number getCellValue(int row, int col) { return cells[row][col]; } /** * The list of ${member.facet}:${member.value} filters to apply to the data - slices */ public List<String> getFilters() { List<String> filters = new ArrayList<String>(); if (selectedFacets != null && !selectedFacets.isEmpty()) { for (String facetName : selectedFacets.keySet()) { filters.add(facetName + ":" + selectedFacets.get(facetName)); } } return filters; } public List<String> getEmptyFilters() { return new ArrayList<String>(); } public String getValue(Level level) { for(String filter : getFilters()) { if(filter.startsWith(level.getFacet())) { return filter.substring(level.getFacet().length() + 1); } } return null; } public Cube getCube() { return cube; } public Integer getFirstRow() { return firstRow; } public Integer getMaxRows() { return maxRows; } public Integer getFirstCol() { return firstCol; } public Integer getMaxCols() { return maxCols; } public FacetField getTotalCols() { return totalCols; } public FacetField getTotalRows() { return totalRows; } public Level getCount() { return CellSet.count; } public FacetField getFacetField(String facetName) { return queryResponse.getFacetField(facetName); } public List<String> getFacetNames() { List<String> facetNames = new ArrayList<String>(); for(FacetField facetField : queryResponse.getFacetFields()) { if(columns.isRelatedFacet(facetField.getName())) { } else if(rows.isRelatedFacet(facetField.getName())) { } else { facetNames.add(facetField.getName()); } } Collections.sort(facetNames, new FacetNameComparator()); return facetNames; } public Map<String, String> getSelectedFacets() { if(selectedFacets == null) { return new HashMap<String,String>(); } return selectedFacets; } public boolean isFacetSelected(String facetName) { if(selectedFacets != null && selectedFacets.containsKey(facetName)) { return true; } else if(columns.getFacet().equals(facetName)) { return true; } else if(rows.getFacet().equals(facetName)) { return true; } else { return false; } } public void setSelectedFacets(Map<String,String> selectedFacets) { this.selectedFacets = selectedFacets; } public void setSelectedFacet(String facetName, String selected) { selectedFacets.put(facetName, selected); } public Long getRowTotal(Member row) { FacetField.Count count = null; for(FacetField.Count c : totalRows.getValues()) { if(c.getName() == null) { if(row.getValue() == null){ count = c; break; } } else if(c.getName().equals(row.getValue())) { count = c; break; } } if(count == null) { return null; } else { return count.getCount(); } } public Long getColumnTotal(Member col) { FacetField.Count count = null; for(FacetField.Count c : totalCols.getValues()) { if(c.getName() == null) { if(col.getValue() == null) { count = c; break; } } else if(c.getName().equals(col.getValue())) { count = c; break; } } if(count == null) { return null; } else { return count.getCount(); } } public Long getRemainingCols(int from) { if((totalCols.getValueCount() -1) < from) { return 0L; } else { long remainder = 0; for(int i = from; i < totalCols.getValueCount(); i++) { remainder += totalCols.getValues().get(i).getCount(); } return remainder; } } public Long getRemainingRows(int from) { if((totalRows.getValueCount() -1) < from) { return 0L; } else { long remainder = 0; for(int i = from; i < totalRows.getValueCount(); i++) { remainder += totalRows.getValues().get(i).getCount(); } return remainder; } } }