Source Code Cross Referenced for DayMarkers.java in  » Database-ORM » MMBase » org » mmbase » module » builders » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » MMBase » org.mmbase.module.builders 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:        This software is OSI Certified Open Source Software.
004:        OSI Certified is a certification mark of the Open Source Initiative.
005:
006:        The license (Mozilla version 1.0) can be read at the MMBase site.
007:        See http://www.MMBase.org/license
008:
009:         */
010:        package org.mmbase.module.builders;
011:
012:        import java.util.*;
013:        import java.text.DateFormat;
014:        import org.mmbase.module.core.*;
015:        import org.mmbase.storage.search.implementation.*;
016:        import org.mmbase.storage.search.*;
017:        import org.mmbase.util.*;
018:
019:        import org.mmbase.util.logging.*;
020:
021:        /**
022:         * Daymarkers are used to calculate the age of MMBase objects.
023:         * Every day a daymarker is added to the daymarks table. Such an entry
024:         * consists of a daycount (number of days from 1970), and a count
025:         * (current object number of that day).
026:         *
027:         * @author Daniel Ockeloen,Rico Jansen
028:         * @author Michiel Meeuwissen
029:         * @version $Id: DayMarkers.java,v 1.46 2007/11/09 10:38:29 michiel Exp $
030:         */
031:        public class DayMarkers extends MMObjectBuilder {
032:
033:            public static final String FIELD_DAYCOUNT = "daycount";
034:            public static final String FIELD_MARK = "mark";
035:            public static final long SECONDS_IN_A_DAY = 24 * 3600;
036:            public static final long MILLISECONDS_IN_A_DAY = SECONDS_IN_A_DAY * 1000;
037:
038:            private static final Logger log = Logging
039:                    .getLoggerInstance(DayMarkers.class);
040:
041:            private int day = 0; // current day number/count
042:            private Map<Integer, Integer> daycache = new TreeMap<Integer, Integer>(); // day -> mark, but ordered
043:
044:            private int smallestDay; // will be queried when this builder is started
045:
046:            /**
047:             * Put in cache. This function essentially does the casting to
048:             * Integer and wrapping in 'synchronized' for you.
049:             */
050:            private void cachePut(int day, int mark) {
051:                synchronized (daycache) {
052:                    daycache.put(day, mark);
053:                }
054:            }
055:
056:            /**
057:             * set the current day. This is the number of days from 1970.
058:             */
059:            public DayMarkers() {
060:                day = currentDay();
061:            }
062:
063:            /**
064:             * Calculate smallestMark, and smallestDay.
065:             * smallestMark is the smallest object number for which a daymark exists.
066:             * smallestDay is the first daymarker that was set.
067:             */
068:            public boolean init() {
069:                log.debug("Init of DayMarkers");
070:                boolean result;
071:                result = super .init();
072:                smallestDay = 0;
073:
074:                try {
075:                    NodeSearchQuery query = new NodeSearchQuery(this );
076:                    StepField field = query.getField(getField(FIELD_NUMBER));
077:                    query.addSortOrder(field);
078:                    query.setMaxNumber(1);
079:                    List<MMObjectNode> resultList = getNodes(query);
080:                    if (resultList.size() > 0) {
081:                        MMObjectNode mark = resultList.get(0);
082:                        smallestDay = mark.getIntValue(FIELD_DAYCOUNT);
083:                    }
084:                    if (smallestDay == 0) {
085:                        smallestDay = currentDay();
086:                        createMarker();
087:                    }
088:                } catch (SearchQueryException e) {
089:                    log.error("SQL Exception " + e
090:                            + ". Could not find smallestMarker, smallestDay");
091:                    result = false;
092:                }
093:
094:                return result;
095:            }
096:
097:            /**
098:             * The current time in days since 1-1-1970
099:             */
100:            private int currentDay() {
101:                return (int) (System.currentTimeMillis() / MILLISECONDS_IN_A_DAY);
102:            }
103:
104:            /**
105:             * Creates a mark in the database, if necessary.
106:             */
107:            private void createMarker() {
108:                // test if the node for today exists
109:                NodeSearchQuery query = new NodeSearchQuery(this );
110:                query.setMaxNumber(1);
111:                StepField daycountField = query
112:                        .getField(getField(FIELD_DAYCOUNT));
113:                BasicFieldValueConstraint constraint = new BasicFieldValueConstraint(
114:                        daycountField, day);
115:                query.setConstraint(constraint);
116:                try {
117:                    List<MMObjectNode> resultList = getNodes(query);
118:                    if (resultList.size() == 0) {
119:                        // if not, retrieve the mark (highest node number) for today
120:                        MMObjectBuilder root = mmb.getRootBuilder();
121:                        query = new NodeSearchQuery(root);
122:                        ModifiableQuery modifiedQuery = new ModifiableQuery(
123:                                query);
124:                        Step step = query.getSteps().get(0);
125:                        AggregatedField field = new BasicAggregatedField(step,
126:                                root.getField(FIELD_NUMBER),
127:                                AggregatedField.AGGREGATION_TYPE_MAX);
128:                        List<StepField> newFields = new ArrayList<StepField>(1);
129:                        newFields.add(field);
130:                        modifiedQuery.setFields(newFields);
131:                        List<MMObjectNode> results = mmb
132:                                .getSearchQueryHandler().getNodes(
133:                                        modifiedQuery,
134:                                        new ResultBuilder(mmb, modifiedQuery));
135:                        MMObjectNode result = results.get(0);
136:                        int max = result.getIntValue(FIELD_NUMBER);
137:                        // add a new daymarker node
138:                        MMObjectNode node = getNewNode(SYSTEM_OWNER);
139:                        node.setValue(FIELD_DAYCOUNT, day);
140:                        node.setValue(FIELD_MARK, max);
141:                        insert(SYSTEM_OWNER, node);
142:                    }
143:                } catch (SearchQueryException e) {
144:                    log.error(Logging.stackTrace(e));
145:                }
146:
147:            }
148:
149:            /**
150:             * This gets called every hour to see if the day has past.
151:             */
152:            public void probe() {
153:                int newday;
154:                newday = currentDay();
155:                //debug("Days "+newday+" current "+day);
156:                if (newday > day) {
157:                    day = newday;
158:                    createMarker();
159:                }
160:            }
161:
162:            /**
163:             * Returns the age, in days, of a node. So, this does the inverse of most methods in this
164:             * class. It converts a node number (which is like a mark) to a day.
165:             */
166:            public int getAge(int nodeNumber) {
167:                // first, check if it accidentily can be found with the cache:
168:                Set<Map.Entry<Integer, Integer>> days = daycache.entrySet();
169:                Iterator<Map.Entry<Integer, Integer>> i = days.iterator();
170:                if (i.hasNext()) { // cache not empty
171:                    Map.Entry<Integer, Integer> current = i.next();
172:                    Map.Entry<Integer, Integer> previous = null;
173:                    while (i.hasNext()
174:                            && current.getValue().intValue() < nodeNumber) { // search until current > nodeNumber
175:                        previous = current;
176:                        current = i.next();
177:                    }
178:                    if ((previous != null)
179:                            && current.getValue().intValue() >= nodeNumber) { // found in cache
180:                        // if we found a lower and a higher mark on two consecutive days, return the lower.
181:                        if (current.getKey().intValue()
182:                                - previous.getKey().intValue() == 1) {
183:                            return day - previous.getKey().intValue();
184:                        }
185:                    }
186:
187:                }
188:                log.debug("Could not find with daycache " + nodeNumber
189:                        + ", searching in database now");
190:
191:                try {
192:                    NodeSearchQuery query = new NodeSearchQuery(this );
193:                    StepField dayCount = query
194:                            .getField(getField(FIELD_DAYCOUNT));
195:                    BasicSortOrder sortOrder = query.addSortOrder(dayCount);
196:                    sortOrder.setDirection(SortOrder.ORDER_DESCENDING);
197:                    StepField markField = query.getField(getField(FIELD_MARK));
198:                    BasicFieldValueConstraint cons = new BasicFieldValueConstraint(
199:                            markField, nodeNumber);
200:                    cons.setOperator(FieldCompareConstraint.LESS);
201:                    query.setConstraint(cons);
202:                    query.setMaxNumber(1);
203:
204:                    List<MMObjectNode> resultList = getNodes(query);
205:                    // mark < in stead of mark = will of course only be used in database with are not on line always, such
206:                    // that some days do not have a mark.
207:                    if (log.isDebugEnabled()) {
208:                        log.debug(query);
209:                    }
210:
211:                    // String query = "select mark, daycount from " + mmb.baseName + "_" + tableName + " where mark < "+ nodeNumber + " order by daycount desc";
212:                    if (resultList.size() > 0) {
213:                        // search the first daycount of which' mark is lower.
214:                        // that must be the day which we were searching (at least a good estimate)
215:                        MMObjectNode markNode = resultList.get(0);
216:                        int mark = markNode.getIntValue(FIELD_MARK);
217:                        int daycount = markNode.getIntValue(FIELD_DAYCOUNT);
218:                        cachePut(daycount, mark); // found one, could as well cache it
219:                        getDayCount(daycount + 1); // next time, this can be count with the cache as well
220:                        return day - daycount;
221:                    } else {
222:                        // hmm, strange, perhaps we have to seek the oldest daycount, but for the moment:
223:                        log.service("daycount could not be found for node "
224:                                + nodeNumber);
225:                        // determining the oldest daycount:
226:                        query = new NodeSearchQuery(this );
227:                        StepField number = query
228:                                .getField(getField(FIELD_NUMBER));
229:                        sortOrder = query.addSortOrder(number);
230:                        sortOrder.setDirection(SortOrder.ORDER_ASCENDING);
231:                        query.setMaxNumber(1);
232:                        resultList = getNodes(query);
233:
234:                        if (resultList.size() > 0) {
235:                            MMObjectNode markNode = resultList.get(0);
236:                            int mark = markNode.getIntValue(FIELD_MARK);
237:                            int daycount = markNode.getIntValue(FIELD_DAYCOUNT);
238:                            cachePut(daycount, mark); // found one, could as well cache it
239:                            getDayCount(daycount + 1); // next time, this can be count with the cache as well
240:                            return day - daycount;
241:                        } else {
242:                            // no daymarks found at all.
243:                            return 0; // everything from today.
244:                        }
245:
246:                    }
247:                } catch (SearchQueryException e) {
248:                    log.error(Logging.stackTrace(e));
249:                    return -1;
250:                }
251:
252:            }
253:
254:            /**
255:             * The current day count.
256:             * @return the number of days from 1970 of today.
257:             **/
258:            public int getDayCount() {
259:                return day;
260:            }
261:
262:            /**
263:             * Given an age, this function returns a mark, _not a day count_, and also _not an age_!
264:             * @param daysold a time in days ago.
265:             * @return the smallest object number of all objects that are younger than given parameter daysold.
266:             **/
267:            public int getDayCountAge(int daysold) {
268:                int wday = day - daysold;
269:                return getDayCount(wday);
270:            }
271:
272:            /**
273:             * Calculates the smallest object number of all objects that are younger than the specified age.
274:             * @param wday teh age in number of days from 1970
275:             * @return the smallest object number, 0 if it can't be found
276:             */
277:            private int getDayCount(int wday) {
278:                log.debug("finding mark of day " + wday);
279:                Integer result = daycache.get(wday);
280:                if (result != null) { // already in cache
281:                    return result.intValue();
282:                }
283:                log.debug("could not be found in cache");
284:
285:                if (wday < smallestDay) { // will not be possible to find in database
286:                    if (log.isDebugEnabled()) {
287:                        log.debug("Day " + wday
288:                                + " is smaller than smallest in database");
289:                    }
290:                    return 0;
291:                }
292:                if (wday <= day) {
293:                    NodeSearchQuery query = new NodeSearchQuery(this );
294:                    query.setMaxNumber(1);
295:                    StepField daycountField = query
296:                            .getField(getField(FIELD_DAYCOUNT));
297:                    BasicFieldValueConstraint constraint = new BasicFieldValueConstraint(
298:                            daycountField, wday);
299:                    constraint
300:                            .setOperator(FieldCompareConstraint.GREATER_EQUAL);
301:                    query.setConstraint(constraint);
302:                    int mark = 0;
303:                    try {
304:                        List<MMObjectNode> resultList = getNodes(query);
305:                        if (resultList.size() != 0) {
306:                            MMObjectNode resultNode = resultList.get(0);
307:                            mark = resultNode.getIntValue(FIELD_MARK);
308:                            int daycount = resultNode
309:                                    .getIntValue(FIELD_DAYCOUNT);
310:                            if (daycount != wday) {
311:                                log.error("Could not find day " + wday
312:                                        + ", surrogated with " + daycount);
313:                            } else {
314:                                log
315:                                        .debug("Found in db, will be inserted in cache");
316:                            }
317:                            cachePut(wday, mark);
318:                        }
319:                    } catch (SearchQueryException e) {
320:                        log.error(Logging.stackTrace(e));
321:                    }
322:                    return mark;
323:                } else {
324:                    return Integer.MAX_VALUE;
325:                }
326:            }
327:
328:            /**
329:             * Scan. Known tokens are:
330:             * COUNT-X gets an object number of X days after 1970
331:             * COUNTAGE-X gets an object number of X days old
332:             * COUNTMONTH-X gets an object number of X months after 1970
333:             * COUNTNEXTMONTH-X gets an object number of X+1 months after 1970
334:             * COUNTPREVMONTH-X gets an object number of X-1 months after 1970
335:             * COUNTPREVDELTAMONTH-X-Y gets an object number of X-Y months after 1970
336:             * COUNTNEXTDELTAMONTH-X-Y gets an object number of X+Y months after 1970
337:             * TIMETOOBJECTNUMBER gets an object number of X seconds after 1970
338:             **/
339:            public String replace(PageInfo sp, StringTokenizer command) {
340:                String rtn = "";
341:                int ival;
342:                if (command.hasMoreTokens()) {
343:                    String token = command.nextToken();
344:                    if (token.equals("COUNT")) {
345:                        ival = fetchIntValue(command);
346:                        rtn = "" + getDayCount(ival);
347:                    } else if (token.equals("COUNTAGE")) {
348:                        ival = fetchIntValue(command);
349:                        rtn = "" + getDayCountAge(ival);
350:                    } else if (token.equals("COUNTMONTH")) {
351:                        ival = fetchIntValue(command);
352:                        rtn = "" + getDayCount(getDayCountMonth(ival));
353:                    } else if (token.equals("COUNTNEXTMONTH")) {
354:                        ival = fetchIntValue(command);
355:                        rtn = "" + getDayCount(getDayCountNextMonth(ival));
356:                    } else if (token.equals("COUNTPREVMONTH")) {
357:                        ival = fetchIntValue(command);
358:                        rtn = "" + getDayCount(getDayCountPreviousMonth(ival));
359:                    } else if (token.equals("COUNTPREVDELTAMONTH")) {
360:                        ival = fetchIntValue(command);
361:                        int delta = 0 - fetchIntValue(command);
362:                        rtn = ""
363:                                + getDayCount(getDayCountDeltaMonth(ival, delta));
364:                    } else if (token.equals("COUNTNEXTDELTAMONTH")) {
365:                        ival = fetchIntValue(command);
366:                        int delta = fetchIntValue(command);
367:                        rtn = ""
368:                                + getDayCount(getDayCountDeltaMonth(ival, delta));
369:                    } else if (token.equals("TIMETOOBJECTNUMBER")) {
370:                        ival = fetchIntValue(command);
371:                        rtn = "" + getDayCount((int) (ival / SECONDS_IN_A_DAY));
372:                    } else {
373:                        rtn = "UnknownCommand";
374:                    }
375:                }
376:                return rtn;
377:            }
378:
379:            /**
380:             * @javadoc
381:             */
382:            private int fetchIntValue(StringTokenizer command) {
383:                String val;
384:                int ival;
385:                if (command.hasMoreTokens()) {
386:                    val = command.nextToken();
387:                } else {
388:                    val = "0";
389:                }
390:                try {
391:                    ival = Integer.parseInt(val);
392:                } catch (NumberFormatException e) {
393:                    ival = 0;
394:                }
395:                return ival;
396:            }
397:
398:            /**
399:             * get a Calendar
400:             * @param months number of months from 1970
401:             * @return calendar with date specified in months from 1970
402:             */
403:            private Calendar getCalendarMonths(int months) {
404:                int year, month;
405:                year = months / 12;
406:                month = months % 12;
407:                GregorianCalendar cal = new GregorianCalendar();
408:                cal.set(year + 1970, month, 1, 0, 0, 0);
409:                return cal;
410:            }
411:
412:            /**
413:             * @javadoc
414:             */
415:            private Calendar getCalendarDays(int days) {
416:                GregorianCalendar cal = new GregorianCalendar();
417:                java.util.Date d = new java.util.Date((days)
418:                        * MILLISECONDS_IN_A_DAY);
419:                cal.setTime(d);
420:                return cal;
421:            }
422:
423:            /**
424:             * @javadoc
425:             */
426:            private int getDayCountMonth(int months) {
427:                Calendar cal = getCalendarMonths(months);
428:                return (int) (cal.getTime().getTime() / MILLISECONDS_IN_A_DAY);
429:            }
430:
431:            /**
432:             * @javadoc
433:             */
434:            private int getDayCountPreviousMonth(int months) {
435:                Calendar cal = getCalendarMonths(months);
436:                cal.add(Calendar.MONTH, -1);
437:                return (int) (cal.getTime().getTime() / MILLISECONDS_IN_A_DAY);
438:            }
439:
440:            /**
441:             * @javadoc
442:             */
443:            private int getDayCountNextMonth(int months) {
444:                Calendar cal = getCalendarMonths(months);
445:                cal.add(Calendar.MONTH, 1);
446:                return (int) (cal.getTime().getTime() / MILLISECONDS_IN_A_DAY);
447:            }
448:
449:            /**
450:             * @javadoc
451:             */
452:            private int getDayCountDeltaMonth(int months, int delta) {
453:                Calendar cal = getCalendarMonths(months);
454:                cal.add(Calendar.MONTH, delta);
455:                return (int) (cal.getTime().getTime() / MILLISECONDS_IN_A_DAY);
456:            }
457:
458:            /**
459:             * @javadoc
460:             */
461:            public int getDayCountByObject(int number) {
462:                NodeSearchQuery query = new NodeSearchQuery(this );
463:                query.setMaxNumber(1);
464:                StepField markField = query.getField(getField(FIELD_MARK));
465:                BasicFieldValueConstraint constraint = new BasicFieldValueConstraint(
466:                        markField, number);
467:                constraint.setOperator(FieldCompareConstraint.LESS);
468:                query.setConstraint(constraint);
469:                ModifiableQuery modifiedQuery = new ModifiableQuery(query);
470:                Step step = query.getSteps().get(0);
471:                AggregatedField field = new BasicAggregatedField(step,
472:                        getField(FIELD_DAYCOUNT),
473:                        AggregatedField.AGGREGATION_TYPE_MAX);
474:                List<StepField> newFields = new ArrayList<StepField>(1);
475:                newFields.add(field);
476:                modifiedQuery.setFields(newFields);
477:                try {
478:                    List<MMObjectNode> results = mmb.getSearchQueryHandler()
479:                            .getNodes(modifiedQuery,
480:                                    new ResultBuilder(mmb, modifiedQuery));
481:                    MMObjectNode result = results.get(0);
482:                    return result.getIntValue(FIELD_DAYCOUNT);
483:                } catch (SearchQueryException e) {
484:                    log.error(Logging.stackTrace(e));
485:                    return 0;
486:                }
487:
488:            }
489:
490:            /**
491:             * @javadoc
492:             */
493:            public int getMonthsByDayCount(int daycount) {
494:                int year, month;
495:                Calendar calendar;
496:
497:                calendar = getCalendarDays(daycount);
498:                year = calendar.get(Calendar.YEAR) - 1970;
499:                month = calendar.get(Calendar.MONTH);
500:                return month + year * 12;
501:            }
502:
503:            /**
504:             *  Returns the date of a daymarker
505:             *  @param node The node of which the date is wanted
506:             *  @return a <code>Date</code> which is the date
507:             */
508:            public java.util.Date getDate(MMObjectNode node) {
509:                int dayCount = node.getIntValue(FIELD_DAYCOUNT);
510:                return new java.util.Date(dayCount * MILLISECONDS_IN_A_DAY);
511:            }
512:
513:            /**
514:             *  Returns gui information for a specific node. This value is retrieved by retrieving the field 'gui()' of the node (node.getStringValue("gui()") )
515:             *  @param node The node of which the gui information is wanted
516:             *  @return a <code>String</code> in which the current date is shown
517:             */
518:            public String getLocaleGUIIndicator(Locale locale, MMObjectNode node) {
519:                return DateFormat.getDateInstance(DateFormat.LONG, locale)
520:                        .format(getDate(node));
521:
522:            }
523:
524:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.