/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2007-2011 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * OpenNMS(R) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * OpenNMS(R) 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenNMS(R). If not, see: * http://www.gnu.org/licenses/ * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.dashboard.server; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import org.hibernate.criterion.Restrictions; import org.hibernate.type.StringType; import org.hibernate.type.Type; import org.opennms.dashboard.client.SurveillanceGroup; import org.opennms.dashboard.client.Visitor; import org.opennms.netmgt.config.surveillanceViews.Category; import org.opennms.netmgt.config.surveillanceViews.ColumnDef; import org.opennms.netmgt.config.surveillanceViews.RowDef; import org.opennms.netmgt.config.surveillanceViews.View; import org.opennms.netmgt.dao.CategoryDao; import org.opennms.netmgt.model.OnmsCriteria; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; /** * <p>CriteriaAddingVisitor class.</p> * * @author <a href="mailto:brozow@opennms.org">Mathew Brozowski</a> * @author <a href="mailto:dj@opennms.org">DJ Gregor</a> * @author <a href="mailto:jeffg@opennms.org">Jeff Gehlbach</a> * @author <a href="mailto:brozow@opennms.org">Mathew Brozowski</a> * @author <a href="mailto:dj@opennms.org">DJ Gregor</a> * @author <a href="mailto:jeffg@opennms.org">Jeff Gehlbach</a> * @author <a href="mailto:brozow@opennms.org">Mathew Brozowski</a> * @author <a href="mailto:dj@opennms.org">DJ Gregor</a> * @author <a href="mailto:jeffg@opennms.org">Jeff Gehlbach</a> * @version $Id: $ * @since 1.8.1 */ public class CriteriaAddingVisitor implements Visitor, InitializingBean { private OnmsCriteria m_criteria; private CategoryDao m_categoryDao; private View m_view; private SurveillanceView m_survView; /** * <p>Constructor for CriteriaAddingVisitor.</p> * * @param criteria a {@link org.opennms.netmgt.model.OnmsCriteria} object. */ public CriteriaAddingVisitor(OnmsCriteria criteria) { m_criteria = criteria; } /** * <p>visitAll</p> */ public void visitAll() { addCriteriaForCategories(m_criteria, m_survView.getColumnCategories()); addCriteriaForCategories(m_criteria, m_survView.getRowCategories()); } /** {@inheritDoc} */ public void visitGroup(SurveillanceGroup group) { if (group.isColumn()) { addCriteriaForCategories(m_criteria, m_survView.getRowCategories()); addCriteriaForCategories(m_criteria, m_survView.getCategoriesForColumn(group.getId())); } else { addCriteriaForCategories(m_criteria, m_survView.getColumnCategories()); addCriteriaForCategories(m_criteria, m_survView.getCategoriesForRow(group.getId())); } } /** {@inheritDoc} */ public void visitIntersection(SurveillanceGroup row, SurveillanceGroup column) { addCriteriaForCategories(m_criteria, m_survView.getCategoriesForRow(row.getId())); addCriteriaForCategories(m_criteria, m_survView.getCategoriesForColumn(column.getId())); } /** * <p>addCriteriaForCategories</p> * * @param criteria a {@link org.opennms.netmgt.model.OnmsCriteria} object. * @param categories a {@link java.util.Set} object. */ public void addCriteriaForCategories(OnmsCriteria criteria, Set<String> categories) { String[] categoryNames = categories.toArray(new String[categories.size()]); addCriteriaForCategories(criteria, categoryNames); } /** * <p>addCriteriaForCategories</p> * * @param criteria a {@link org.opennms.netmgt.model.OnmsCriteria} object. * @param categories a {@link java.lang.String} object. */ public void addCriteriaForCategories(OnmsCriteria criteria, String... categories) { String sql = "{alias}.nodeId in (select distinct cn.nodeId from category_node cn join categories c on cn.categoryId = c.categoryId where c.categoryName in (" + commaDelimitedQuestionMarks(categories.length) + "))"; criteria.add(Restrictions.sqlRestriction(sql, categories, arrayOfType(categories.length, new StringType()))); } /** * <p>getView</p> * * @return a {@link org.opennms.netmgt.config.surveillanceViews.View} object. */ public View getView() { return m_view; } /** * <p>setView</p> * * @param view a {@link org.opennms.netmgt.config.surveillanceViews.View} object. */ public void setView(View view) { m_view = view; } /** * <p>setCategoryDao</p> * * @param categoryDao a {@link org.opennms.netmgt.dao.CategoryDao} object. */ public void setCategoryDao(CategoryDao categoryDao) { m_categoryDao = categoryDao; } /** * <p>afterPropertiesSet</p> */ @Override public void afterPropertiesSet() { Assert.state(m_view != null, "view property must be set"); Assert.state(m_categoryDao != null, "categoryDao property must be set"); // construct a surveillance view object that makes it easier to build queries m_survView = new SurveillanceView(); m_survView.setName(m_view.getName()); for (ColumnDef colDef : m_view.getColumns().getColumnDef()) { for (Category category : colDef.getCategory()) { m_survView.addColumnCategory(colDef.getLabel(), category.getName()); } } for (RowDef rowDef : m_view.getRows().getRowDef()) { for (Category category : rowDef.getCategory()) { m_survView.addRowCategory(rowDef.getLabel(), category.getName()); } } } private Type[] arrayOfType(int length, Type initialVal) { Type[] array = new Type[length]; for(int i = 0; i < length; i++) { array[i] = initialVal; } return array; } /** * <p>commaDelimitedQuestionMarks</p> * * @param count a int. * @return a {@link java.lang.String} object. */ public String commaDelimitedQuestionMarks(int count) { StringBuilder buf = new StringBuilder(); for(int i = 0; i < count; i++) { if (i != 0) { buf.append(','); } buf.append('?'); } return buf.toString(); } private static class SurveillanceView { private String m_name; private MapToSetOf<String, String> m_columns = new MapToSetOf<String, String>(); private MapToSetOf<String, String> m_rows = new MapToSetOf<String, String>(); public void setName(String name) { m_name = name; } public String getName() { return m_name; } public void addColumnCategory(String column, String category) { m_columns.addValue(column, category); } public void addRowCategory(String row, String category) { m_rows.addValue(row, category); } public Set<String> getCategoriesForRow(String row) { return m_rows.getValueForKey(row); } public Set<String> getCategoriesForColumn(String column) { return m_columns.getValueForKey(column); } public Set<String> getRowCategories() { return m_rows.getAllValues(); } public Set<String> getColumnCategories() { return m_columns.getAllValues(); } public Set<String> getCategoriesForColumns(Collection<? extends String> columns) { return m_columns.getValuesForKeys(columns); } public Set<String> getCategoriesForRows(Collection<? extends String> rows) { return m_rows.getValuesForKeys(rows); } } private static class MapToSetOf<K, V> { private Map<K, Set<V>> m_map = new LinkedHashMap<K, Set<V>>(); public void addValue(K key, V value) { if (!m_map.containsKey(key)) { m_map.put(key, new LinkedHashSet<V>()); } m_map.get(key).add(value); } public Set<V> getValuesForKeys(Collection<? extends K> keys) { LinkedHashSet<V> values = new LinkedHashSet<V>(); for (K key : keys) { values.addAll(m_map.get(key)); } return values; } public Set<V> getAllValues() { return getValuesForKeys(m_map.keySet()); } public Set<V> getValueForKey(K key) { return getValuesForKeys(Collections.singleton(key)); } } }