Java tutorial
/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2007-2014 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2014 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 Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero 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.DetachedCriteria; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.Subqueries; 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.api.CategoryDao; import org.opennms.netmgt.model.OnmsCriteria; import org.opennms.netmgt.model.OnmsMonitoredService; import org.opennms.netmgt.model.OnmsNode; import org.opennms.netmgt.model.OnmsOutage; 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> */ 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> */ @Override public void visitAll() { addCriteriaForCategories(m_criteria, m_survView.getColumnCategories()); addCriteriaForCategories(m_criteria, m_survView.getRowCategories()); } /** {@inheritDoc} */ @Override 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} */ @Override 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) { if (criteria.resultsOfType(OnmsMonitoredService.class) || criteria.resultsOfType(OnmsOutage.class)) { // Make a detached criteria to subselect the node IDs that are in the // specified surveillance categories DetachedCriteria categoryNodeCriteria = DetachedCriteria.forClass(OnmsNode.class, "categoryNodes"); // HACK: Hibernate 3.6 aliases 'categoryNodes' as 'categoryNodes_' so use that for the raw SQL statement. // Also note that the database field that we use here is 'nodeId' but the bean property for node ID // in OnmsNode is 'id'. String sql = "categoryNodes_.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) + "))"; categoryNodeCriteria.add( Restrictions.sqlRestriction(sql, categories, arrayOfType(categories.length, new StringType()))); // Join the categoryNodes IDs found by the subselect with the outer 'node' alias. // This requires that the criteria already has a 'node' alias to the node table. // // @see org.opennms.web.svclayer.support.DefaultRtcService#createOutageCriteria() // @see org.opennms.web.svclayer.support.DefaultRtcService#createServiceCriteria() // categoryNodeCriteria.add(Restrictions.eqProperty("categoryNodes.id", "node.id")); // Add a projection for 'id' so that the categoryNodes.id can be joined to // node.id in the outer criteria categoryNodeCriteria.setProjection(Projections.property("id")); // Use an exists subquery to evaluate the subselect criteria.add(Subqueries.exists(categoryNodeCriteria)); } else { // TODO: This case assumes that the OnmsCriteria is querying an object with a 'nodeId' property. // I'm not sure this is ever used... I think this visitor is just for OnmsMonitoredService and // OnmsOutage queries. 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.api.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)); } } }