View Javadoc

1   /***
2    *  Copyright 2003-2010 Terracotta, Inc.
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  
17  package net.sf.ehcache.search.aggregator;
18  
19  import net.sf.ehcache.search.Attribute;
20  
21  /***
22   * Sums the results
23   * <p/>
24   * Sum can be used with most numeric types
25   *
26   * @author Greg Luck
27   */
28  public class Sum implements AggregatorInstance<Long> {
29  
30      private final Attribute<?> attribute;
31  
32      private Engine engine;
33  
34      /***
35       * @param attribute
36       */
37      public Sum(Attribute<?> attribute) {
38          this.attribute = attribute;
39      }
40  
41      /***
42       * {@inheritDoc}
43       * <p/>
44       * NOTE: null inputs are ignored
45       */
46      public void accept(Object input) throws AggregatorException {
47          if (input == null) {
48              return;
49          }
50  
51          if (input instanceof Number) {
52              if (engine == null) {
53                  engine = Engine.create((Number) input);
54              } else {
55                  engine.accept((Number) input);
56              }
57          } else {
58              throw new AggregatorException("Non-number type encounted: " + input.getClass());
59          }
60      }
61  
62      /***
63       * {@inheritDoc}
64       * <p/>
65       * NOTE: May return null if no input supplied
66       */
67      public Number aggregateResult() {
68          if (engine == null) {
69              return null;
70          } else {
71              return engine.result();
72          }
73      }
74  
75      /***
76       * {@inheritDoc}
77       */
78      public Attribute getAttribute() {
79          return attribute;
80      }
81  
82      /***
83       * Abstract super-class for all sum calculating engines.
84       */
85      abstract static class Engine {
86  
87          /***
88           * Create a type specific engine using the given initial value.
89           *
90           * @param value initial value
91           * @return type specific engine
92           */
93          static Engine create(Number value) {
94              if (value instanceof Float) {
95                  return new FloatEngine(value.floatValue());
96              } else if (value instanceof Double) {
97                  return new DoubleEngine(value.doubleValue());
98              } else {
99                  return new LongEngine(value.longValue());
100             }
101         }
102 
103         /***
104          * Update the engine with the given value.
105          *
106          * @param input data value
107          */
108         abstract void accept(Number input) throws AggregatorException;
109 
110         /***
111          * Get the (current) result of this engine.
112          *
113          * @return engine result
114          */
115         abstract Number result();
116 
117         /***
118          * A long based summing engine.
119          */
120         static class LongEngine extends Engine {
121 
122             private long sum;
123 
124             /***
125              * Creates a new instance starting with an initial value
126              *
127              * @param value initial value
128              */
129             LongEngine(long value) {
130                 this.sum = value;
131             }
132 
133             @Override
134             void accept(Number input) throws AggregatorException {
135                 sum += input.longValue();
136             }
137 
138             @Override
139             Number result() {
140                 return Long.valueOf(sum);
141             }
142         }
143 
144         /***
145          * A float based summing engine.
146          */
147         static class FloatEngine extends Engine {
148 
149             private float sum;
150 
151             /***
152              * Creates a new instance starting with an initial value
153              *
154              * @param value initial value
155              */
156             FloatEngine(float value) {
157                 this.sum = value;
158             }
159 
160             @Override
161             void accept(Number input) throws AggregatorException {
162                 sum += input.floatValue();
163             }
164 
165             @Override
166             Number result() {
167                 return Float.valueOf(sum);
168             }
169         }
170 
171         /***
172          * A double based summing engine.
173          */
174         static class DoubleEngine extends Engine {
175 
176             private double sum;
177 
178             /***
179              * Creates a new instance starting with an initial value
180              *
181              * @param value initial value
182              */
183             DoubleEngine(double value) {
184                 this.sum = value;
185             }
186 
187             @Override
188             void accept(Number input) throws AggregatorException {
189                 sum += input.doubleValue();
190             }
191 
192             @Override
193             Number result() {
194                 return Double.valueOf(sum);
195             }
196         }
197     }
198 }