1 /* 2 * Copyright 2009 :torweg free software group 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * 17 */ 18 package org.torweg.pulse.component.statistics.model.aggregation; 19 20 import javax.persistence.Basic; 21 import javax.persistence.ManyToOne; 22 import javax.persistence.MappedSuperclass; 23 import javax.xml.bind.annotation.XmlAccessOrder; 24 import javax.xml.bind.annotation.XmlAccessType; 25 import javax.xml.bind.annotation.XmlAccessorOrder; 26 import javax.xml.bind.annotation.XmlAccessorType; 27 import javax.xml.bind.annotation.XmlAttribute; 28 import javax.xml.bind.annotation.XmlElement; 29 import javax.xml.bind.annotation.XmlRootElement; 30 import javax.xml.bind.annotation.XmlTransient; 31 32 import org.hibernate.LazyInitializationException; 33 import org.hibernate.Session; 34 import org.slf4j.Logger; 35 import org.slf4j.LoggerFactory; 36 import org.torweg.pulse.component.statistics.model.StatisticsServer; 37 import org.torweg.pulse.component.statistics.model.Visit; 38 import org.torweg.pulse.util.entity.AbstractBasicEntity; 39 import org.torweg.pulse.util.time.Duration; 40 import org.torweg.pulse.util.time.IHasDuration; 41 import org.torweg.pulse.util.time.Period; 42 43 /** 44 * Abstract bass class representing a basic aggregation of statistical data (by 45 * aggregating {@code Visit}s) as being produced by an {@code 46 * AbstractBaseAggregator}. 47 * 48 * @author Daniel Dietz 49 * @version $Revision: 1579 $ 50 * 51 */ 52 @XmlRootElement(name = "abstract-aggregation") 53 @XmlAccessorOrder(XmlAccessOrder.UNDEFINED) 54 @XmlAccessorType(XmlAccessType.FIELD) 55 @MappedSuperclass 56 public abstract class AbstractAggregation extends AbstractBasicEntity implements 57 IHasDuration { 58 59 /** 60 * The serialVersionUID. 61 */ 62 private static final long serialVersionUID = 8961277121778921282L; 63 64 /** 65 * the logger. 66 */ 67 protected static final Logger LOGGER = LoggerFactory 68 .getLogger(AbstractAggregation.class); 69 70 /** 71 * The start time(-stamp) of the {@code AbstractAggregation}. 72 */ 73 @Basic(optional = false) 74 @XmlAttribute(name = "start-time") 75 private long startTime; 76 77 /** 78 * The end time(-stamp) of the {@code AbstractAggregation}. 79 */ 80 @Basic(optional = false) 81 @XmlAttribute(name = "end-time") 82 private long endTime; 83 84 /** 85 * The {@code StatisticsServer} this aggregation is related to. 86 */ 87 @ManyToOne(optional = false) 88 @XmlTransient 89 // getter JAXB-annotated 90 private StatisticsServer statisticsServer; 91 92 /** 93 * Sets the start time-stamp. 94 * 95 * @param start 96 * the start time to set 97 */ 98 protected final void setStartMillis(final long start) { 99 this.startTime = start; 100 } 101 102 /** 103 * Returns the start time-stamp. 104 * 105 * @return the <tt>startTime</tt> 106 */ 107 public final long getStartMillis() { 108 return this.startTime; 109 } 110 111 /** 112 * Sets the end time-stamp. 113 * 114 * @param end 115 * the end time to set 116 */ 117 protected final void setEndMillis(final long end) { 118 this.endTime = end; 119 } 120 121 /** 122 * Returns the end time-stamp. 123 * 124 * @return the <tt>endTime</tt> 125 */ 126 public final long getEndMillis() { 127 return this.endTime; 128 } 129 130 /** 131 * Sets the start/end of the {@code AbstractAggregation} from the given 132 * {@code Duration}. 133 * 134 * @param duration 135 * the {@code Duration} to apply 136 * 137 * @throws NullPointerException 138 * if the given {@code Duration} is {@code null} 139 * @throws IllegalArgumentException 140 * if the given {@code Duration} does not match a valid {@code 141 * Period} 142 */ 143 protected final void setDuration(final Duration duration) { 144 if (duration == null) { 145 throw new NullPointerException("Given duration must not be null"); 146 } 147 if (Period.valueof(duration).equals(Period.UNDEFINED)) { 148 throw new IllegalArgumentException( 149 "Given duration must not be Period.UNDEFINED but match a valid " 150 + "Period [SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, YEAR]."); 151 } 152 setStartMillis(duration.getStartMillis()); 153 setEndMillis(duration.getEndMillis()); 154 } 155 156 /** 157 * Returns a {@code Duration} representing the start/end of the {@code 158 * AbstractAggregation}. 159 * 160 * @return a {@code Duration} 161 */ 162 @XmlElement(name = "duration") 163 public final Duration getDuration() { 164 return new Duration(getStartMillis(), getEndMillis()); 165 } 166 167 /** 168 * Returns the data resolution as {@code Period}. 169 * 170 * @return the data resolution as {@code Period} 171 */ 172 @XmlElement(name = "data-resolution") 173 public final Period getDataResolution() { 174 return Period.valueof(getDuration()); 175 } 176 177 /** 178 * Returns the {@code StatisticsServer} the aggregation is related to. 179 * 180 * @return the {@code StatisticsServer} 181 */ 182 @XmlTransient 183 public final StatisticsServer getStatisticsServer() { 184 return this.statisticsServer; 185 } 186 187 /** 188 * For JAXB only. 189 * 190 * @return this.getStatisticsServer() 191 */ 192 @XmlElement(name = "statistics-server") 193 @SuppressWarnings("unused") 194 @Deprecated 195 private StatisticsServer getStatisticsServerJAXB() { // NOPMD 196 try { 197 return getStatisticsServer(); 198 } catch (LazyInitializationException e) { 199 LOGGER.debug("ignored: {}", e.getLocalizedMessage()); 200 return null; 201 } 202 } 203 204 /** 205 * Sets the {@code StatisticsServer}. 206 * 207 * @param server 208 * the {@code StatisticsServer} 209 * 210 * @throws NullPointerException 211 * if the given server is {@code null} 212 */ 213 protected final void setStatisticsServer(final StatisticsServer server) { 214 if (server == null) { 215 throw new NullPointerException("Given server must not be null."); 216 } 217 this.statisticsServer = server; 218 } 219 220 /** 221 * Checks if the given {@code Visit} can be aggregated by the {@code 222 * AbstractRegexVersionedCounterAggregation}. 223 * 224 * @param visit 225 * the {@code Visit} 226 * @return {@code true} if and only if the {@code Visit} can be processed, 227 * {@code false} otherwise 228 */ 229 public abstract boolean isAggregateable(final Visit visit); 230 231 /** 232 * Aggregates the given {@code Visit}. 233 * 234 * @param visit 235 * the {@code Visit} 236 * @param s 237 * a Hibernate<sup>TM</sup>-{@code Session} 238 * 239 * @return {@code true} if and only if the {@code Visit} could be processed, 240 * {@code false} otherwise 241 */ 242 public abstract boolean aggregate(final Visit visit, final Session s); 243 244 /** 245 * @return a string-representation of the {@code AbstractAggregation} 246 */ 247 @Override 248 public String toString() { 249 return "{" + super.toString() + "@[" + getId() + "], duration: " 250 + getDuration() + ", statisticsServer: " 251 + getStatisticsServer() + "}"; 252 } 253 254 /** 255 * The known hours for the {@code PIRecordCountAggregation.HitCounter}. 256 * 257 * @author Daniel Dietz 258 * @version $Revision: 1579 $ 259 * 260 */ 261 public static enum Hour { 262 /** 263 * Zero [00:00:00:000 - 00:59:59:999]. 264 */ 265 ZERO(0), 266 /** 267 * One [01:00:00:000 - 01:59:59:999]. 268 */ 269 ONE(1), 270 /** 271 * Two [02:00:00:000 - 02:59:59:999]. 272 */ 273 TWO(2), 274 /** 275 * Three [03:00:00:000 - 03:59:59:999]. 276 */ 277 THREE(3), 278 /** 279 * Four [04:00:00:000 - 04:59:59:999]. 280 */ 281 FOUR(4), 282 /** 283 * Five [05:00:00:000 - 05:59:59:999]. 284 */ 285 FIVE(5), 286 /** 287 * Six [06:00:00:000 - 06:59:59:999]. 288 */ 289 SIX(6), 290 /** 291 * Seven [07:00:00:000 - 07:59:59:999]. 292 */ 293 SEVEN(7), 294 /** 295 * Eight [08:00:00:000 - 08:59:59:999]. 296 */ 297 EIGHT(8), 298 /** 299 * Nine [09:00:00:000 - 09:59:59:999]. 300 */ 301 NINE(9), 302 /** 303 * Ten [10:00:00:000 - 10:59:59:999]. 304 */ 305 TEN(10), 306 /** 307 * Eleven [11:00:00:000 - 11:59:59:999]. 308 */ 309 ELEVEN(11), 310 /** 311 * Twelve [12:00:00:000 - 12:59:59:999]. 312 */ 313 TWELVE(12), 314 /** 315 * Thirteen [13:00:00:000 - 13:59:59:999]. 316 */ 317 THIRTEEN(13), 318 /** 319 * Fourteen [14:00:00:000 - 14:59:59:999]. 320 */ 321 FOURTEEN(14), 322 /** 323 * Fifteen [15:00:00:000 - 15:59:59:999]. 324 */ 325 FIFTEEN(15), 326 /** 327 * Sixteen [16:00:00:000 - 16:59:59:999]. 328 */ 329 SIXTEEN(16), 330 /** 331 * Seventeen [17:00:00:000 - 17:59:59:999]. 332 */ 333 SEVENTEEN(17), 334 /** 335 * Eighteen [18:00:00:000 - 18:59:59:999]. 336 */ 337 EIGHTEEN(18), 338 /** 339 * Nineteen [19:00:00:000 - 19:59:59:999]. 340 */ 341 NINETEEN(19), 342 /** 343 * Twenty [20:00:00:000 - 20:59:59:999]. 344 */ 345 TWENTY(20), 346 /** 347 * Twenty-one [21:00:00:000 - 21:59:59:999]. 348 */ 349 TWENTY_ONE(21), 350 /** 351 * Twenty-two [22:00:00:000 - 22:59:59:999]. 352 */ 353 TWENTY_TWO(22), 354 /** 355 * Twenty-three [23:00:00:000 - 23:59:59:999]. 356 */ 357 TWENTY_THREE(23); 358 359 /** 360 * The integer value of the constant. 361 */ 362 private int value; 363 364 /** 365 * Private constructor. 366 * 367 * @param v 368 * the value 369 */ 370 private Hour(final int v) { 371 this.value = v; 372 } 373 374 /** 375 * Returns the value. 376 * 377 * @return the <tt>value</tt> 378 */ 379 public int getValue() { 380 return this.value; 381 } 382 383 /** 384 * Returns the matching {@code Hour} for the given integer i if (-1 < i 385 * < 24), {@code null} otherwise. 386 * 387 * @param i 388 * the integer value 389 * 390 * @return the matching {@code Hour} for the given integer, or {@code 391 * null} if no matching {@code Hour} was found 392 */ 393 public static Hour valueOf(final int i) { 394 if (i < 0 || i > 23) { 395 return null; 396 } 397 for (Hour h : values()) { 398 if (h.getValue() == i) { 399 return h; 400 } 401 } 402 return null; 403 } 404 405 } 406 407 } 408