gt:                 if (!rrdFile.canRead()) {
context: /*******************************************************************************
   * This file is part of OpenNMS(R).
   *
   * Copyright (C) 2006-2012 The OpenNMS Group, Inc.
   * OpenNMS(R) is Copyright (C) 1999-2012 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.netmgt.threshd;
  
  import java.io.File;
  import java.util.Collection;
  import java.util.Date;
  import java.util.HashMap;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Map;
  
  import org.opennms.core.utils.ThreadCategory;
  import org.opennms.netmgt.rrd.RrdException;
  import org.opennms.netmgt.rrd.RrdUtils;
  import org.opennms.netmgt.threshd.ThresholdEvaluatorState.Status;
  import org.opennms.netmgt.xml.event.Event;
  import org.opennms.netmgt.xml.event.Parm;
  import org.opennms.netmgt.xml.event.Value;
  
  /**
   * Wraps the castor created org.opennms.netmgt.config.threshd.Threshold class
   * and provides the ability to track threshold exceeded occurrences.
   *
   * @author ranger
   * @version $Id: $
   */
  public final class ThresholdEntity implements Cloneable {
      
      private static List<ThresholdEvaluator> s_thresholdEvaluators;
      
      //Contains a list of evaluators for each used "instance".  Is populated with the list for the "default" instance (the "null" key)
      // in the Constructor.  Note that this means we must use a null-key capable map like HashMap
      private Map<String,List<ThresholdEvaluatorState>> m_thresholdEvaluatorStates = new HashMap<String,List<ThresholdEvaluatorState>>();
  
      // the commands for these need to be listed in ThresholdController as well
      static {
          s_thresholdEvaluators = new LinkedList<ThresholdEvaluator>();
          s_thresholdEvaluators.add(new ThresholdEvaluatorHighLow());
          s_thresholdEvaluators.add(new ThresholdEvaluatorRelativeChange());
          s_thresholdEvaluators.add(new ThresholdEvaluatorAbsoluteChange());
          s_thresholdEvaluators.add(new ThresholdEvaluatorRearmingAbsoluteChange());
      }
  
      /**
       * Constructor.
       */
      public ThresholdEntity() {
          //Put in a default list for the "null" key (the default evaluators)
          m_thresholdEvaluatorStates.put(null, new LinkedList<ThresholdEvaluatorState>());
      }
  
      /**
       * <p>getThresholdConfig</p>
       *
       * @return a {@link org.opennms.netmgt.threshd.BaseThresholdDefConfigWrapper} object.
       */
      public BaseThresholdDefConfigWrapper getThresholdConfig() {
          return m_thresholdEvaluatorStates.get(null).get(0).getThresholdConfig();
      }
      
      private boolean hasThresholds() {
          return m_thresholdEvaluatorStates.get(null).size()!=0;
      }
      /**
       * Get datasource name
       *
       * @return a {@link java.lang.String} object.
       */
      public String getDataSourceExpression() {
          if (hasThresholds()) {
              return getThresholdConfig().getDatasourceExpression();
          } else {
              throw new IllegalStateException("No thresholds have been added.");
          }
      }
  
      /**
       * Get datasource type
       *
       * @return a {@link java.lang.String} object.
       */
      public String getDatasourceType() {
          if (hasThresholds()) {
              return getThresholdConfig().getDsType();
          } else {
              throw new IllegalStateException("No thresholds have been added.");
          }
      }
  
      /**
       * Get datasource Label
       *
       * @return a {@link java.lang.String} object.
       */
      public String getDatasourceLabel() {
          if (hasThresholds()) {
              return getThresholdConfig().getDsLabel();
          } else {
              return null;
          }
      }
  
      /**
       * Returns the names of the dataousrces required to evaluate this threshold entity
       *
       * @return Collection of the names of datasources
       */
      public Collection<String> getRequiredDatasources() {
          if (hasThresholds()) {
              return getThresholdConfig().getRequiredDatasources();
          } else {
              throw new IllegalStateException("No thresholds have been added.");
          }
      }
      /**
       * Returns a copy of this ThresholdEntity object.
       *
       * NOTE: The m_lowThreshold and m_highThreshold member variables are not
       * actually cloned...the returned ThresholdEntity object will simply contain
       * references to the same castor Threshold objects as the original
       * ThresholdEntity object.
       *
       * All state will be lost, particularly instances, so it's not a true clone by any stretch of the imagination
       *
       * @return a {@link org.opennms.netmgt.threshd.ThresholdEntity} object.
       */
      public ThresholdEntity clone() {
          ThresholdEntity clone = new ThresholdEntity();
          for (ThresholdEvaluatorState thresholdItem : getThresholdEvaluatorStates(null)) {
              clone.addThreshold(thresholdItem.getThresholdConfig());
          }
  
          return clone;
      }
  
      /**
       * This method is responsible for returning a String object which represents
       * the content of this ThresholdEntity. Primarily used for debugging
       * purposes.
       *
       * @return String which represents the content of this ThresholdEntity
       */
      public String toString() {
          if (!hasThresholds()) {
              return "";
          }
  
          StringBuffer buffer = new StringBuffer("{");
  
          buffer.append("evaluator=").append(this.getThresholdConfig().getType());
          buffer.append(", dsName=").append(this.getDataSourceExpression());
          buffer.append(", dsType=").append(this.getDatasourceType());
          buffer.append(", evaluators=[");
          for (ThresholdEvaluatorState item : getThresholdEvaluatorStates(null)) {
              buffer.append("{ds=").append(item.getThresholdConfig().getDatasourceExpression());
              buffer.append(", value=").append(item.getThresholdConfig().getValue());
              buffer.append(", rearm=").append(item.getThresholdConfig().getRearm());
              buffer.append(", trigger=").append(item.getThresholdConfig().getTrigger());
              buffer.append("}");
          }
          buffer.append("]}");
  
          return buffer.toString();
      }
  
      
      /**
       * Evaluates the threshold in light of the provided datasource value and
       * create any events for thresholds.
       *
       * Semi-deprecated method; only used for old Thresholding code (threshd and friends)
       * Implemented in terms of the other method with the same name and the extra param
       *
       * @param values
       *          map of values (by datasource name) to evaluate against the threshold (might be an expression)
       * @param date
       *          Date to use in created events
       * @return List of events
       */
      public  List<Event> evaluateAndCreateEvents(Map<String, Double> values, Date date) {
             return evaluateAndCreateEvents(null, values, date);
      }
  
      /**
       * Evaluates the threshold in light of the provided datasource value, for
       * the named instance (or the generic instance if instance is null) and
       * create any events for thresholds.
       *
       * @param values
       *          map of values (by datasource name) to evaluate against the threshold (might be an expression)
       * @param date
       *          Date to use in created events
       * @return List of events
       * @param resource a {@link org.opennms.netmgt.threshd.CollectionResourceWrapper} object.
       */
      public List<Event> evaluateAndCreateEvents(CollectionResourceWrapper resource, Map<String, Double> values, Date date) {
          List<Event> events = new LinkedList<Event>();
          double dsValue=0.0;
          String instance = resource != null ? resource.getInstance() : null;
          try {
              if (getThresholdEvaluatorStates(instance).size() > 0) {
                  dsValue=getThresholdConfig().evaluate(values);
              } else {
                  throw new IllegalStateException("No thresholds have been added.");
              }
          } catch (ThresholdExpressionException e) {
              log().warn("Failed to evaluate: ", e);
              return events; //No events to report
          }
          
          if (log().isDebugEnabled()) {
              log().debug("evaluate: value= " + dsValue + " against threshold: " + this);
          }        
  
          for (ThresholdEvaluatorState item : getThresholdEvaluatorStates(instance)) {
              Status status = item.evaluate(dsValue);
              Event event = item.getEventForState(status, date, dsValue, resource);
              if (event != null) {
                  events.add(event);
              }
          }
  
          return events;
      }
  
      private final ThreadCategory log() {
          return ThreadCategory.getInstance(ThresholdEntity.class);
      }
  
      /**
       * <p>fetchLastValue</p>
       *
       * @param latIface a {@link org.opennms.netmgt.threshd.LatencyInterface} object.
       * @param latParms a {@link org.opennms.netmgt.threshd.LatencyParameters} object.
       * @return a {@link java.lang.Double} object.
       * @throws org.opennms.netmgt.threshd.ThresholdingException if any.
       */
      public Double fetchLastValue(LatencyInterface latIface, LatencyParameters latParms) throws ThresholdingException {
          //Assume that this only happens on a simple "Threshold", not an "Expression"
          //If it is an Expression, then we don't yet know what to do - this will likely just fail with some sort of exception.
          //perhaps we should figure out how to expand it (or at least use code elsewhere to do so sensibly)
          String datasource=getDataSourceExpression();
    
  
          // Use RRD strategy to "fetch" value of the datasource from the RRD file
          Double dsValue = null;
          try {
              if (getDatasourceType().equals("if")) {
                  if (log().isDebugEnabled()) {
                      log().debug("Fetching last value from dataSource '" + datasource + "'");
                  }
  
                  File rrdFile = new  File(latIface.getLatencyDir(), datasource+RrdUtils.getExtension());
                  if (!rrdFile.exists()) {
                      log().info("rrd file "+rrdFile+" does not exist");
                      return null;
                  }
  
  