View Javadoc

1   /*******************************************************************************
2    * Copyright (c) 2007, 2014 Massimiliano Ziccardi
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *******************************************************************************/
16  package it.jnrpe.utils.thresholds;
17  
18  import java.math.BigDecimal;
19  
20  /**
21   * Base class for the number parsing stages.
22   *
23   * @author Massimiliano Ziccardi
24   */
25  abstract class NumberBoundaryStage extends Stage {
26  
27      /**
28       * @param stageName
29       *            The name of this stage
30       */
31      protected NumberBoundaryStage(final String stageName) {
32          super(stageName);
33      }
34  
35      /**
36       * Parses the threshold to remove the matched number string.
37       *
38       * No checks are performed against the passed in string: the object
39       * assumes that the string is correct since the {@link #canParse(String)}
40       * method <b>must</b> be called <b>before</b> this method.
41       *
42       * @param threshold
43       *            The threshold chunk to be parsed
44       * @param tc
45       *            The threshold config object. This object will be populated
46       *            according to the passed in threshold.
47       * @return the remaining part of the threshold
48       * @throws RangeException if the threshold can't be parsed
49       */
50      @Override
51      public String parse(final String threshold, final RangeConfig tc)
52              throws RangeException {
53          StringBuffer numberString = new StringBuffer();
54          for (int i = 0; i < threshold.length(); i++) {
55              if (Character.isDigit(threshold.charAt(i))) {
56                  numberString.append(threshold.charAt(i));
57                  continue;
58              }
59              if (threshold.charAt(i) == '.') {
60                  if (numberString.toString().endsWith(".")) {
61                      numberString.deleteCharAt(numberString.length() - 1);
62                      break;
63                  } else {
64                      numberString.append(threshold.charAt(i));
65                      continue;
66                  }
67              }
68              if (threshold.charAt(i) == '+' || threshold.charAt(i) == '-') {
69                  if (numberString.length() == 0) {
70                      numberString.append(threshold.charAt(i));
71                      continue;
72                  } else {
73                      throw new RangeException("Unexpected '"
74                              + threshold.charAt(i)
75                              + "' sign parsing boundary");
76                  }
77              }
78              // throw new InvalidRangeSyntaxException(this,
79              // threshold.substring(numberString.length()));
80              break;
81          }
82          if (numberString.length() != 0
83                  && !justSign(numberString.toString())) {
84              BigDecimal bd = new BigDecimal(numberString.toString());
85              setBoundary(tc, bd);
86              return threshold.substring(numberString.length());
87          } else {
88              throw new InvalidRangeSyntaxException(this, threshold);
89          }
90      }
91  
92      /**
93       * @param string The string to be evaluated
94       * @return <code>true</code> if the string is just a sign.
95       */
96      private boolean justSign(final String string) {
97          return string.equals("+") || string.equals("-");
98      }
99  
100     @Override
101     public boolean canParse(final String threshold) {
102         if (threshold == null || threshold.isEmpty()) {
103             return false;
104         }
105         switch (threshold.charAt(0)) {
106         case '+':
107         case '-':
108             return !(threshold.startsWith("-inf") || threshold
109                     .startsWith("+inf"));
110         default:
111             return Character.isDigit(threshold.charAt(0));
112         }
113     }
114 
115     @Override
116     public String expects() {
117         return "+-[0-9]";
118     }
119 
120     /**
121      * This object can be used to set both left or right boundary of a range. It
122      * is left to the implementing class to set the right boundary inside the
123      * {@link RangeConfig} object;
124      *
125      * @param tc
126      *            The threshold configuration
127      * @param boundary
128      *            The boundary value
129      */
130     public abstract void setBoundary(final RangeConfig tc,
131             final BigDecimal boundary);
132 
133     /**
134      * This class represent a left numeric boundary of a range.
135      *
136      * In the -10..+inf range it represent the '-10' value.
137      *
138      * @author Massimiliano Ziccardi
139      *
140      */
141     public static class LeftBoundaryStage extends NumberBoundaryStage {
142 
143         /**
144          *
145          */
146         protected LeftBoundaryStage() {
147             super("startboundary");
148         }
149 
150         @Override
151         public void setBoundary(final RangeConfig tc,
152                 final BigDecimal boundary) {
153             tc.setLeftBoundary(boundary);
154         }
155     }
156 
157     /**
158      * This class represent a right numeric boundary of a range.
159      *
160      * In the range -10..+100.34 it represent the '100.34' value.
161      *
162      * @author Massimiliano Ziccardi
163      *
164      */
165     public static class RightBoundaryStage extends NumberBoundaryStage {
166 
167         /**
168          *
169          */
170         protected RightBoundaryStage() {
171             super("rightboundary");
172         }
173 
174         @Override
175         public void setBoundary(final RangeConfig tc,
176                 final BigDecimal boundary) {
177             tc.setRightBoundary(boundary);
178         }
179 
180         /**
181          * Right boundary can be the end of the range.
182          *
183          * @return <code>true</code>
184          */
185         public final boolean isLeaf() {
186             return true;
187         }
188     }
189 }