1 10 package org.mmbase.module.builders; 11 12 import java.util.*; 13 import java.text.DateFormat ; 14 import org.mmbase.module.core.*; 15 import org.mmbase.storage.search.implementation.*; 16 import org.mmbase.storage.search.*; 17 import org.mmbase.util.*; 18 19 import org.mmbase.util.logging.*; 20 21 31 public class DayMarkers extends MMObjectBuilder { 32 33 public static final String FIELD_DAYCOUNT = "daycount"; 34 public static final String FIELD_MARK = "mark"; 35 public static final long SECONDS_IN_A_DAY = 24*3600; 36 public static final long MILLISECONDS_IN_A_DAY = SECONDS_IN_A_DAY*1000; 37 38 private static final Logger log = Logging.getLoggerInstance(DayMarkers.class); 39 40 private int day = 0; private Map daycache = new TreeMap(); 43 private int smallestDay; 45 49 private void cachePut(int day, int mark) { 50 synchronized(daycache) { 51 daycache.put(new Integer (day), new Integer (mark)); 52 } 53 } 54 55 58 public DayMarkers() { 59 day = currentDay(); 60 } 61 62 67 public boolean init() { 68 log.debug("Init of DayMarkers"); 69 boolean result; 70 result = super.init(); 71 smallestDay = 0; 72 73 try { 74 NodeSearchQuery query = new NodeSearchQuery(this); 75 StepField field = query.getField(getField(FIELD_NUMBER)); 76 query.addSortOrder(field); 77 query.setMaxNumber(1); 78 List resultList = getNodes(query); 79 if (resultList.size() > 0) { 80 MMObjectNode mark = (MMObjectNode) resultList.get(0); 81 smallestDay = mark.getIntValue(FIELD_DAYCOUNT); 82 } 83 if (smallestDay < day) { 84 smallestDay = day; createMarker(); 86 } 87 } catch (SearchQueryException e) { 88 log.error("SQL Exception " + e + ". Could not find smallestMarker, smallestDay"); 89 result = false; 90 } 91 92 return result; 93 } 94 95 98 private int currentDay() { 99 return (int)(System.currentTimeMillis()/MILLISECONDS_IN_A_DAY); 100 } 101 102 103 106 private void createMarker() { 107 NodeSearchQuery query = new NodeSearchQuery(this); 109 query.setMaxNumber(1); 110 StepField daycountField = query.getField(getField(FIELD_DAYCOUNT)); 111 BasicFieldValueConstraint constraint = new BasicFieldValueConstraint(daycountField, new Integer (day)); 112 query.setConstraint(constraint); 113 try { 114 List resultList = getNodes(query); 115 if (resultList.size() == 0) { 116 MMObjectBuilder root = mmb.getRootBuilder(); 118 query = new NodeSearchQuery(root); 119 ModifiableQuery modifiedQuery = new ModifiableQuery(query); 120 Step step = (Step) query.getSteps().get(0); 121 AggregatedField field = new BasicAggregatedField( 122 step, root.getField(FIELD_NUMBER), AggregatedField.AGGREGATION_TYPE_MAX); 123 List newFields = new ArrayList(1); 124 newFields.add(field); 125 modifiedQuery.setFields(newFields); 126 List results = mmb.getSearchQueryHandler().getNodes(modifiedQuery, new ResultBuilder(mmb, modifiedQuery)); 127 ResultNode result = (ResultNode) results.get(0); 128 int max = result.getIntValue(FIELD_NUMBER); 129 MMObjectNode node = getNewNode(SYSTEM_OWNER); 131 node.setValue(FIELD_DAYCOUNT,day); 132 node.setValue(FIELD_MARK,max); 133 insert(SYSTEM_OWNER,node); 134 } 135 } catch (SearchQueryException e) { 136 log.error(Logging.stackTrace(e)); 137 } 138 139 } 140 141 144 public void probe() { 145 int newday; 146 newday=currentDay(); 147 if (newday>day) { 149 day = newday; 150 createMarker(); 151 } 152 } 153 154 155 159 public int getAge(int nodeNumber) { 160 Set days = daycache.entrySet(); 162 Iterator i = days.iterator(); 163 if (i.hasNext()) { Map.Entry current = (Map.Entry)i.next(); 165 Map.Entry previous = null; 166 while (i.hasNext() && ((Integer )current.getValue()).intValue() < nodeNumber) { previous = current; 168 current = (Map.Entry)i.next(); 169 } 170 if ((previous != null) && ((Integer )current.getValue()).intValue() >= nodeNumber) { if (((Integer )current.getKey()).intValue() - ((Integer )previous.getKey()).intValue() == 1) { 173 return day - ((Integer )previous.getKey()).intValue(); 174 } 175 } 176 177 } 178 log.debug("Could not find with daycache " + nodeNumber + ", searching in database now"); 179 180 try { 181 NodeSearchQuery query = new NodeSearchQuery(this); 182 StepField dayCount = query.getField(getField(FIELD_DAYCOUNT)); 183 BasicSortOrder sortOrder = query.addSortOrder(dayCount); 184 sortOrder.setDirection(SortOrder.ORDER_DESCENDING); 185 StepField markField = query.getField(getField(FIELD_MARK)); 186 BasicFieldValueConstraint cons = new BasicFieldValueConstraint(markField, new Integer (nodeNumber)); 187 cons.setOperator(FieldCompareConstraint.LESS); 188 query.setConstraint(cons); 189 query.setMaxNumber(1); 190 191 List resultList = getNodes(query); 192 if (log.isDebugEnabled()) { 195 log.debug(query); 196 } 197 198 if (resultList.size() > 0) { 200 MMObjectNode markNode = (MMObjectNode) resultList.get(0); 203 int mark = markNode.getIntValue(FIELD_MARK); 204 int daycount = markNode.getIntValue(FIELD_DAYCOUNT); 205 cachePut(daycount, mark); getDayCount(daycount + 1); return day - daycount; 208 } else { 209 log.service("daycount could not be found for node " + nodeNumber); 211 query = new NodeSearchQuery(this); 213 StepField number = query.getField(getField(FIELD_NUMBER)); 214 sortOrder = query.addSortOrder(number); 215 sortOrder.setDirection(SortOrder.ORDER_ASCENDING); 216 query.setMaxNumber(1); 217 resultList = getNodes(query); 218 219 if (resultList.size() > 0) { 220 MMObjectNode markNode = (MMObjectNode) resultList.get(0); 221 int mark = markNode.getIntValue(FIELD_MARK); 222 int daycount = markNode.getIntValue(FIELD_DAYCOUNT); 223 cachePut(daycount, mark); getDayCount(daycount + 1); return day - daycount; 226 } else { 227 return 0; } 230 231 } 232 } catch(SearchQueryException e) { 233 log.error(Logging.stackTrace(e)); 234 return -1; 235 } 236 237 } 238 239 243 public int getDayCount() { 244 return day; 245 } 246 247 252 public int getDayCountAge(int daysold) { 253 int wday = day - daysold; 254 return getDayCount(wday); 255 } 256 257 262 private int getDayCount(int wday) { 263 log.debug("finding mark of day " + wday); 264 Integer result = (Integer )daycache.get(new Integer (wday)); 265 if (result!=null) { return result.intValue(); 267 } 268 log.debug("could not be found in cache"); 269 270 if (wday < smallestDay) { if (log.isDebugEnabled() ) { 272 log.debug("Day " + wday + " is smaller than smallest in database"); 273 } 274 return 0; 275 } 276 if (wday <= day) { 277 NodeSearchQuery query = new NodeSearchQuery(this); 278 query.setMaxNumber(1); 279 StepField daycountField = query.getField(getField(FIELD_DAYCOUNT)); 280 BasicFieldValueConstraint constraint = new BasicFieldValueConstraint(daycountField, new Integer (wday)); 281 constraint.setOperator(FieldCompareConstraint.GREATER_EQUAL); 282 query.setConstraint(constraint); 283 int mark = 0; 284 try { 285 List resultList = getNodes(query); 286 if (resultList.size() != 0) { 287 MMObjectNode resultNode = (MMObjectNode) resultList.get(0); 288 mark = resultNode.getIntValue(FIELD_MARK); 289 int daycount = resultNode.getIntValue(FIELD_DAYCOUNT); 290 if (daycount != wday) { 291 log.error("Could not find day " + wday + ", surrogated with " + daycount); 292 } else { 293 log.debug("Found in db, will be inserted in cache"); 294 } 295 cachePut(wday, mark); 296 } 297 } catch (SearchQueryException e) { 298 log.error(Logging.stackTrace(e)); 299 } 300 return mark; 301 } else { 302 return Integer.MAX_VALUE; 303 } 304 } 305 306 317 public String replace(PageInfo sp, StringTokenizer command) { 318 String rtn=""; 319 int ival; 320 if (command.hasMoreTokens()) { 321 String token=command.nextToken(); 322 if (token.equals("COUNT")) { 323 ival=fetchIntValue(command); 324 rtn=""+getDayCount(ival); 325 } else if (token.equals("COUNTAGE")) { 326 ival=fetchIntValue(command); 327 rtn=""+getDayCountAge(ival); 328 } else if (token.equals("COUNTMONTH")) { 329 ival=fetchIntValue(command); 330 rtn=""+getDayCount(getDayCountMonth(ival)); 331 } else if (token.equals("COUNTNEXTMONTH")) { 332 ival=fetchIntValue(command); 333 rtn=""+getDayCount(getDayCountNextMonth(ival)); 334 } else if (token.equals("COUNTPREVMONTH")) { 335 ival=fetchIntValue(command); 336 rtn=""+getDayCount(getDayCountPreviousMonth(ival)); 337 } else if (token.equals("COUNTPREVDELTAMONTH")) { 338 ival=fetchIntValue(command); 339 int delta=0-fetchIntValue(command); 340 rtn=""+getDayCount(getDayCountDeltaMonth(ival,delta)); 341 } else if (token.equals("COUNTNEXTDELTAMONTH")) { 342 ival=fetchIntValue(command); 343 int delta=fetchIntValue(command); 344 rtn=""+getDayCount(getDayCountDeltaMonth(ival,delta)); 345 } else if (token.equals("TIMETOOBJECTNUMBER")){ 346 ival=fetchIntValue(command); 347 rtn=""+getDayCount((int)(ival/SECONDS_IN_A_DAY)); 348 } else { 349 rtn="UnknownCommand"; 350 } 351 } 352 return rtn; 353 } 354 355 358 private int fetchIntValue(StringTokenizer command) { 359 String val; 360 int ival; 361 if (command.hasMoreTokens()) { 362 val=command.nextToken(); 363 } else { 364 val="0"; 365 } 366 try { 367 ival=Integer.parseInt(val); 368 } catch (NumberFormatException e) { 369 ival=0; 370 } 371 return ival; 372 } 373 374 379 private Calendar getCalendarMonths(int months) { 380 int year,month; 381 year=months/12; 382 month=months%12; 383 GregorianCalendar cal=new GregorianCalendar(); 384 cal.set(year+1970,month,1,0,0,0); 385 return cal; 386 } 387 388 391 private Calendar getCalendarDays(int days) { 392 GregorianCalendar cal = new GregorianCalendar(); 393 java.util.Date d = new java.util.Date ((days)*MILLISECONDS_IN_A_DAY); 394 cal.setTime(d); 395 return cal; 396 } 397 398 401 private int getDayCountMonth(int months) { 402 Calendar cal = getCalendarMonths(months); 403 return (int)(cal.getTime().getTime()/MILLISECONDS_IN_A_DAY); 404 } 405 406 409 private int getDayCountPreviousMonth(int months) { 410 Calendar cal = getCalendarMonths(months); 411 cal.add(Calendar.MONTH,-1); 412 return (int)(cal.getTime().getTime()/MILLISECONDS_IN_A_DAY); 413 } 414 415 418 private int getDayCountNextMonth(int months) { 419 Calendar cal = getCalendarMonths(months); 420 cal.add(Calendar.MONTH,1); 421 return (int)(cal.getTime().getTime()/MILLISECONDS_IN_A_DAY); 422 } 423 424 427 private int getDayCountDeltaMonth(int months,int delta) { 428 Calendar cal = getCalendarMonths(months); 429 cal.add(Calendar.MONTH,delta); 430 return (int)(cal.getTime().getTime()/MILLISECONDS_IN_A_DAY); 431 } 432 433 436 public int getDayCountByObject(int number) { 437 NodeSearchQuery query = new NodeSearchQuery(this); 438 query.setMaxNumber(1); 439 StepField markField = query.getField(getField(FIELD_MARK)); 440 BasicFieldValueConstraint constraint = new BasicFieldValueConstraint(markField, new Integer (number)); 441 constraint.setOperator(FieldCompareConstraint.LESS); 442 query.setConstraint(constraint); 443 ModifiableQuery modifiedQuery = new ModifiableQuery(query); 444 Step step = (Step) query.getSteps().get(0); 445 AggregatedField field = new BasicAggregatedField( 446 step, getField(FIELD_DAYCOUNT), AggregatedField.AGGREGATION_TYPE_MAX); 447 List newFields = new ArrayList(1); 448 newFields.add(field); 449 modifiedQuery.setFields(newFields); 450 try { 451 List results = mmb.getSearchQueryHandler().getNodes(modifiedQuery, new ResultBuilder(mmb, modifiedQuery)); 452 ResultNode result = (ResultNode) results.get(0); 453 return result.getIntValue(FIELD_DAYCOUNT); 454 } catch (SearchQueryException e) { 455 log.error(Logging.stackTrace(e)); 456 return 0; 457 } 458 459 } 460 461 464 public int getMonthsByDayCount(int daycount) { 465 int year,month; 466 Calendar calendar; 467 468 calendar = getCalendarDays(daycount); 469 year = calendar.get(Calendar.YEAR)-1970; 470 month = calendar.get(Calendar.MONTH); 471 return month + year * 12; 472 } 473 474 475 480 public java.util.Date getDate(MMObjectNode node) { 481 int dayCount = node.getIntValue(FIELD_DAYCOUNT); 482 return new java.util.Date (dayCount*MILLISECONDS_IN_A_DAY); 483 } 484 485 490 public String getLocaleGUIIndicator(Locale locale, MMObjectNode node) { 491 return DateFormat.getDateInstance(DateFormat.LONG, locale).format(getDate(node)); 492 493 } 494 495 } 496
| Popular Tags
|