Source Code Cross Referenced for Recurrence.java in  » Portal » liferay-portal-4.4.2 » com » liferay » portal » kernel » cal » 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 » Portal » liferay portal 4.4.2 » com.liferay.portal.kernel.cal 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 2000, Columbia University.  All rights reserved.
0003:         *
0004:         * Redistribution and use in source and binary forms, with or without
0005:         * modification, are permitted provided that the following conditions are met:
0006:         *
0007:         * 1. Redistributions of source code must retain the above copyright
0008:         *    notice, this list of conditions and the following disclaimer.
0009:         *
0010:         * 2. Redistributions in binary form must reproduce the above copyright
0011:         *    notice, this list of conditions and the following disclaimer in the
0012:         *    documentation and/or other materials provided with the distribution.
0013:         *
0014:         * 3. Neither the name of the University nor the names of its contributors
0015:         *    may be used to endorse or promote products derived from this software
0016:         *    without specific prior written permission.
0017:         *
0018:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
0019:         * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
0020:         * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0021:         * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
0022:         * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0023:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0024:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
0025:         * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
0026:         * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
0027:         * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
0028:         * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0029:         */
0030:
0031:        package com.liferay.portal.kernel.cal;
0032:
0033:        import com.liferay.portal.kernel.util.CalendarFactoryUtil;
0034:        import com.liferay.portal.kernel.util.StringMaker;
0035:
0036:        import java.io.Serializable;
0037:
0038:        import java.util.Calendar;
0039:        import java.util.Date;
0040:        import java.util.TimeZone;
0041:
0042:        /**
0043:         * <a href="Recurrence.java.html"><b><i>View Source</i></b></a>
0044:         *
0045:         * @author Jonathan Lennox
0046:         *
0047:         */
0048:        public class Recurrence implements  Serializable {
0049:
0050:            /**
0051:             * Field DAILY
0052:             */
0053:            public final static int DAILY = 3;
0054:
0055:            /**
0056:             * Field WEEKLY
0057:             */
0058:            public final static int WEEKLY = 4;
0059:
0060:            /**
0061:             * Field MONTHLY
0062:             */
0063:            public final static int MONTHLY = 5;
0064:
0065:            /**
0066:             * Field YEARLY
0067:             */
0068:            public final static int YEARLY = 6;
0069:
0070:            /**
0071:             * Field NO_RECURRENCE
0072:             */
0073:            public final static int NO_RECURRENCE = 7;
0074:
0075:            /**
0076:             * Field dtStart
0077:             */
0078:            protected Calendar dtStart;
0079:
0080:            /**
0081:             * Field duration
0082:             */
0083:            protected Duration duration;
0084:
0085:            /**
0086:             * Field frequency
0087:             */
0088:            protected int frequency;
0089:
0090:            /**
0091:             * Field interval
0092:             */
0093:            protected int interval;
0094:
0095:            /**
0096:             * Field interval
0097:             */
0098:            protected int occurrence = 0;
0099:
0100:            /**
0101:             * Field until
0102:             */
0103:            protected Calendar until;
0104:
0105:            /**
0106:             * Field byDay
0107:             */
0108:            protected DayAndPosition[] byDay;
0109:
0110:            /**
0111:             * Field byMonthDay
0112:             */
0113:            protected int[] byMonthDay;
0114:
0115:            /**
0116:             * Field byYearDay
0117:             */
0118:            protected int[] byYearDay;
0119:
0120:            /**
0121:             * Field byWeekNo
0122:             */
0123:            protected int[] byWeekNo;
0124:
0125:            /**
0126:             * Field byMonth
0127:             */
0128:            protected int[] byMonth;
0129:
0130:            /**
0131:             * Constructor Recurrence
0132:             *
0133:             *
0134:             */
0135:            public Recurrence() {
0136:                this (null, new Duration(), NO_RECURRENCE);
0137:            }
0138:
0139:            /**
0140:             * Constructor Recurrence
0141:             *
0142:             *
0143:             * @param	start
0144:             * @param	dur
0145:             *
0146:             */
0147:            public Recurrence(Calendar start, Duration dur) {
0148:                this (start, dur, NO_RECURRENCE);
0149:            }
0150:
0151:            /**
0152:             * Constructor Recurrence
0153:             *
0154:             *
0155:             * @param	start
0156:             * @param	dur
0157:             * @param	freq
0158:             *
0159:             */
0160:            public Recurrence(Calendar start, Duration dur, int freq) {
0161:                setDtStart(start);
0162:
0163:                duration = (Duration) dur.clone();
0164:                frequency = freq;
0165:                interval = 1;
0166:            }
0167:
0168:            /* Accessors */
0169:
0170:            /**
0171:             * Method getDtStart
0172:             *
0173:             *
0174:             * @return	Calendar
0175:             *
0176:             */
0177:            public Calendar getDtStart() {
0178:                return (Calendar) dtStart.clone();
0179:            }
0180:
0181:            /**
0182:             * Method setDtStart
0183:             *
0184:             *
0185:             * @param	start
0186:             *
0187:             */
0188:            public void setDtStart(Calendar start) {
0189:                int oldStart;
0190:
0191:                if (dtStart != null) {
0192:                    oldStart = dtStart.getFirstDayOfWeek();
0193:                } else {
0194:                    oldStart = Calendar.MONDAY;
0195:                }
0196:
0197:                if (start == null) {
0198:                    dtStart = CalendarFactoryUtil.getCalendar(TimeZone
0199:                            .getTimeZone("GMT"));
0200:
0201:                    dtStart.setTime(new Date(0L));
0202:                } else {
0203:                    dtStart = (Calendar) start.clone();
0204:
0205:                    dtStart.clear(Calendar.ZONE_OFFSET);
0206:                    dtStart.clear(Calendar.DST_OFFSET);
0207:                    dtStart.setTimeZone(TimeZone.getTimeZone("GMT"));
0208:                }
0209:
0210:                dtStart.setMinimalDaysInFirstWeek(4);
0211:                dtStart.setFirstDayOfWeek(oldStart);
0212:            }
0213:
0214:            /**
0215:             * Method getDuration
0216:             *
0217:             *
0218:             * @return	Duration
0219:             *
0220:             */
0221:            public Duration getDuration() {
0222:                return (Duration) duration.clone();
0223:            }
0224:
0225:            /**
0226:             * Method setDuration
0227:             *
0228:             *
0229:             * @param	d
0230:             *
0231:             */
0232:            public void setDuration(Duration d) {
0233:                duration = (Duration) d.clone();
0234:            }
0235:
0236:            /**
0237:             * Method getDtEnd
0238:             *
0239:             *
0240:             * @return	Calendar
0241:             *
0242:             */
0243:            public Calendar getDtEnd() {
0244:
0245:                /*
0246:                 * Make dtEnd a cloned dtStart, so non-time fields of the Calendar
0247:                 * are accurate.
0248:                 */
0249:                Calendar tempEnd = (Calendar) dtStart.clone();
0250:
0251:                tempEnd.setTime(new Date(dtStart.getTime().getTime()
0252:                        + duration.getInterval()));
0253:
0254:                return tempEnd;
0255:            }
0256:
0257:            /**
0258:             * Method setDtEnd
0259:             *
0260:             *
0261:             * @param	end
0262:             *
0263:             */
0264:            public void setDtEnd(Calendar end) {
0265:                Calendar tempEnd = (Calendar) end.clone();
0266:
0267:                tempEnd.clear(Calendar.ZONE_OFFSET);
0268:                tempEnd.clear(Calendar.DST_OFFSET);
0269:                tempEnd.setTimeZone(TimeZone.getTimeZone("GMT"));
0270:                duration.setInterval(tempEnd.getTime().getTime()
0271:                        - dtStart.getTime().getTime());
0272:            }
0273:
0274:            /**
0275:             * Method getFrequency
0276:             *
0277:             *
0278:             * @return	int
0279:             *
0280:             */
0281:            public int getFrequency() {
0282:                return frequency;
0283:            }
0284:
0285:            /**
0286:             * Method setFrequency
0287:             *
0288:             *
0289:             * @param	freq
0290:             *
0291:             */
0292:            public void setFrequency(int freq) {
0293:                if ((frequency != DAILY) && (frequency != WEEKLY)
0294:                        && (frequency != MONTHLY) && (frequency != YEARLY)
0295:                        && (frequency != NO_RECURRENCE)) {
0296:                    throw new IllegalArgumentException("Invalid frequency");
0297:                }
0298:
0299:                frequency = freq;
0300:            }
0301:
0302:            /**
0303:             * Method getInterval
0304:             *
0305:             *
0306:             * @return	int
0307:             *
0308:             */
0309:            public int getInterval() {
0310:                return interval;
0311:            }
0312:
0313:            /**
0314:             * Method setInterval
0315:             *
0316:             *
0317:             * @param	intr
0318:             *
0319:             */
0320:            public void setInterval(int intr) {
0321:                interval = intr;
0322:            }
0323:
0324:            /**
0325:             * Method getOccurrence
0326:             *
0327:             *
0328:             * @return	int
0329:             *
0330:             */
0331:            public int getOccurrence() {
0332:                return occurrence;
0333:            }
0334:
0335:            /**
0336:             * Method setOccurrence
0337:             *
0338:             *
0339:             * @param	occur
0340:             *
0341:             */
0342:            public void setOccurrence(int occur) {
0343:                occurrence = occur;
0344:            }
0345:
0346:            /**
0347:             * Method getUntil
0348:             *
0349:             *
0350:             * @return	Calendar
0351:             *
0352:             */
0353:            public Calendar getUntil() {
0354:                return ((until != null) ? (Calendar) until.clone() : null);
0355:            }
0356:
0357:            /**
0358:             * Method setUntil
0359:             *
0360:             *
0361:             * @param	u
0362:             *
0363:             */
0364:            public void setUntil(Calendar u) {
0365:                if (u == null) {
0366:                    until = null;
0367:
0368:                    return;
0369:                }
0370:
0371:                until = (Calendar) u.clone();
0372:
0373:                until.clear(Calendar.ZONE_OFFSET);
0374:                until.clear(Calendar.DST_OFFSET);
0375:                until.setTimeZone(TimeZone.getTimeZone("GMT"));
0376:            }
0377:
0378:            /**
0379:             * Method getWeekStart
0380:             *
0381:             *
0382:             * @return	int
0383:             *
0384:             */
0385:            public int getWeekStart() {
0386:                return dtStart.getFirstDayOfWeek();
0387:            }
0388:
0389:            /**
0390:             * Method setWeekStart
0391:             *
0392:             *
0393:             * @param	weekstart
0394:             *
0395:             */
0396:            public void setWeekStart(int weekstart) {
0397:                dtStart.setFirstDayOfWeek(weekstart);
0398:            }
0399:
0400:            /**
0401:             * Method getByDay
0402:             *
0403:             *
0404:             * @return	DayAndPosition[]
0405:             *
0406:             */
0407:            public DayAndPosition[] getByDay() {
0408:                if (byDay == null) {
0409:                    return null;
0410:                }
0411:
0412:                DayAndPosition[] b = new DayAndPosition[byDay.length];
0413:
0414:                /*
0415:                 * System.arraycopy isn't good enough -- we want to clone each
0416:                 * individual element.
0417:                 */
0418:                for (int i = 0; i < byDay.length; i++) {
0419:                    b[i] = (DayAndPosition) byDay[i].clone();
0420:                }
0421:
0422:                return b;
0423:            }
0424:
0425:            /**
0426:             * Method setByDay
0427:             *
0428:             *
0429:             * @param	b
0430:             *
0431:             */
0432:            public void setByDay(DayAndPosition[] b) {
0433:                if (b == null) {
0434:                    byDay = null;
0435:
0436:                    return;
0437:                }
0438:
0439:                byDay = new DayAndPosition[b.length];
0440:
0441:                /*
0442:                 * System.arraycopy isn't good enough -- we want to clone each
0443:                 * individual element.
0444:                 */
0445:                for (int i = 0; i < b.length; i++) {
0446:                    byDay[i] = (DayAndPosition) b[i].clone();
0447:                }
0448:            }
0449:
0450:            /**
0451:             * Method getByMonthDay
0452:             *
0453:             *
0454:             * @return	int[]
0455:             *
0456:             */
0457:            public int[] getByMonthDay() {
0458:                if (byMonthDay == null) {
0459:                    return null;
0460:                }
0461:
0462:                int[] b = new int[byMonthDay.length];
0463:
0464:                System.arraycopy(byMonthDay, 0, b, 0, byMonthDay.length);
0465:
0466:                return b;
0467:            }
0468:
0469:            /**
0470:             * Method setByMonthDay
0471:             *
0472:             *
0473:             * @param	b
0474:             *
0475:             */
0476:            public void setByMonthDay(int[] b) {
0477:                if (b == null) {
0478:                    byMonthDay = null;
0479:
0480:                    return;
0481:                }
0482:
0483:                byMonthDay = new int[b.length];
0484:
0485:                System.arraycopy(b, 0, byMonthDay, 0, b.length);
0486:            }
0487:
0488:            /**
0489:             * Method getByYearDay
0490:             *
0491:             *
0492:             * @return	int[]
0493:             *
0494:             */
0495:            public int[] getByYearDay() {
0496:                if (byYearDay == null) {
0497:                    return null;
0498:                }
0499:
0500:                int[] b = new int[byYearDay.length];
0501:
0502:                System.arraycopy(byYearDay, 0, b, 0, byYearDay.length);
0503:
0504:                return b;
0505:            }
0506:
0507:            /**
0508:             * Method setByYearDay
0509:             *
0510:             *
0511:             * @param	b
0512:             *
0513:             */
0514:            public void setByYearDay(int[] b) {
0515:                if (b == null) {
0516:                    byYearDay = null;
0517:
0518:                    return;
0519:                }
0520:
0521:                byYearDay = new int[b.length];
0522:
0523:                System.arraycopy(b, 0, byYearDay, 0, b.length);
0524:            }
0525:
0526:            /**
0527:             * Method getByWeekNo
0528:             *
0529:             *
0530:             * @return	int[]
0531:             *
0532:             */
0533:            public int[] getByWeekNo() {
0534:                if (byWeekNo == null) {
0535:                    return null;
0536:                }
0537:
0538:                int[] b = new int[byWeekNo.length];
0539:
0540:                System.arraycopy(byWeekNo, 0, b, 0, byWeekNo.length);
0541:
0542:                return b;
0543:            }
0544:
0545:            /**
0546:             * Method setByWeekNo
0547:             *
0548:             *
0549:             * @param	b
0550:             *
0551:             */
0552:            public void setByWeekNo(int[] b) {
0553:                if (b == null) {
0554:                    byWeekNo = null;
0555:
0556:                    return;
0557:                }
0558:
0559:                byWeekNo = new int[b.length];
0560:
0561:                System.arraycopy(b, 0, byWeekNo, 0, b.length);
0562:            }
0563:
0564:            /**
0565:             * Method getByMonth
0566:             *
0567:             *
0568:             * @return	int[]
0569:             *
0570:             */
0571:            public int[] getByMonth() {
0572:                if (byMonth == null) {
0573:                    return null;
0574:                }
0575:
0576:                int[] b = new int[byMonth.length];
0577:
0578:                System.arraycopy(byMonth, 0, b, 0, byMonth.length);
0579:
0580:                return b;
0581:            }
0582:
0583:            /**
0584:             * Method setByMonth
0585:             *
0586:             *
0587:             * @param	b
0588:             *
0589:             */
0590:            public void setByMonth(int[] b) {
0591:                if (b == null) {
0592:                    byMonth = null;
0593:
0594:                    return;
0595:                }
0596:
0597:                byMonth = new int[b.length];
0598:
0599:                System.arraycopy(b, 0, byMonth, 0, b.length);
0600:            }
0601:
0602:            /**
0603:             * Method isInRecurrence
0604:             *
0605:             *
0606:             * @param	current
0607:             *
0608:             * @return	boolean
0609:             *
0610:             */
0611:            public boolean isInRecurrence(Calendar current) {
0612:                return isInRecurrence(current, false);
0613:            }
0614:
0615:            /**
0616:             * Method isInRecurrence
0617:             *
0618:             *
0619:             * @param	current
0620:             * @param	debug
0621:             *
0622:             * @return	boolean
0623:             *
0624:             */
0625:            public boolean isInRecurrence(Calendar current, boolean debug) {
0626:                Calendar myCurrent = (Calendar) current.clone();
0627:
0628:                // Do all calculations in GMT.  Keep other parameters consistent.
0629:
0630:                myCurrent.clear(Calendar.ZONE_OFFSET);
0631:                myCurrent.clear(Calendar.DST_OFFSET);
0632:                myCurrent.setTimeZone(TimeZone.getTimeZone("GMT"));
0633:                myCurrent.setMinimalDaysInFirstWeek(4);
0634:                myCurrent.setFirstDayOfWeek(dtStart.getFirstDayOfWeek());
0635:
0636:                if (myCurrent.getTime().getTime() < dtStart.getTime().getTime()) {
0637:
0638:                    // The current time is earlier than the start time.
0639:
0640:                    if (debug) {
0641:                        System.err.println("current < start");
0642:                    }
0643:
0644:                    return false;
0645:                }
0646:
0647:                if (myCurrent.getTime().getTime() < dtStart.getTime().getTime()
0648:                        + duration.getInterval()) {
0649:
0650:                    // We are within "duration" of dtStart.
0651:
0652:                    if (debug) {
0653:                        System.err.println("within duration of start");
0654:                    }
0655:
0656:                    return true;
0657:                }
0658:
0659:                Calendar candidate = getCandidateStartTime(myCurrent);
0660:
0661:                /* Loop over ranges for the duration. */
0662:
0663:                while (candidate.getTime().getTime() + duration.getInterval() > myCurrent
0664:                        .getTime().getTime()) {
0665:                    if (candidateIsInRecurrence(candidate, debug)) {
0666:                        return true;
0667:                    }
0668:
0669:                    /* Roll back to one second previous, and try again. */
0670:
0671:                    candidate.add(Calendar.SECOND, -1);
0672:
0673:                    /* Make sure we haven't rolled back to before dtStart. */
0674:
0675:                    if (candidate.getTime().getTime() < dtStart.getTime()
0676:                            .getTime()) {
0677:                        if (debug) {
0678:                            System.err.println("No candidates after dtStart");
0679:                        }
0680:
0681:                        return false;
0682:                    }
0683:
0684:                    candidate = getCandidateStartTime(candidate);
0685:                }
0686:
0687:                if (debug) {
0688:                    System.err.println("No matching candidates");
0689:                }
0690:
0691:                return false;
0692:            }
0693:
0694:            /**
0695:             * Method candidateIsInRecurrence
0696:             *
0697:             *
0698:             * @param	candidate
0699:             * @param	debug
0700:             *
0701:             * @return	boolean
0702:             *
0703:             */
0704:            protected boolean candidateIsInRecurrence(Calendar candidate,
0705:                    boolean debug) {
0706:                if ((until != null)
0707:                        && (candidate.getTime().getTime() > until.getTime()
0708:                                .getTime())) {
0709:
0710:                    // After "until"
0711:
0712:                    if (debug) {
0713:                        System.err.println("after until");
0714:                    }
0715:
0716:                    return false;
0717:                }
0718:
0719:                if (getRecurrenceCount(candidate) % interval != 0) {
0720:
0721:                    // Not a repetition of the interval
0722:
0723:                    if (debug) {
0724:                        System.err.println("not an interval rep");
0725:                    }
0726:
0727:                    return false;
0728:                } else if ((occurrence > 0)
0729:                        && (getRecurrenceCount(candidate) >= occurrence)) {
0730:
0731:                    return false;
0732:                }
0733:
0734:                if (!matchesByDay(candidate) || !matchesByMonthDay(candidate)
0735:                        || !matchesByYearDay(candidate)
0736:                        || !matchesByWeekNo(candidate)
0737:                        || !matchesByMonth(candidate)) {
0738:
0739:                    // Doesn't match a by* rule
0740:
0741:                    if (debug) {
0742:                        System.err.println("doesn't match a by*");
0743:                    }
0744:
0745:                    return false;
0746:                }
0747:
0748:                if (debug) {
0749:                    System.err.println("All checks succeeded");
0750:                }
0751:
0752:                return true;
0753:            }
0754:
0755:            /**
0756:             * Method getMinimumInterval
0757:             *
0758:             *
0759:             * @return	int
0760:             *
0761:             */
0762:            protected int getMinimumInterval() {
0763:                if ((frequency == DAILY) || (byDay != null)
0764:                        || (byMonthDay != null) || (byYearDay != null)) {
0765:                    return DAILY;
0766:                } else if ((frequency == WEEKLY) || (byWeekNo != null)) {
0767:                    return WEEKLY;
0768:                } else if ((frequency == MONTHLY) || (byMonth != null)) {
0769:                    return MONTHLY;
0770:                } else if (frequency == YEARLY) {
0771:                    return YEARLY;
0772:                } else if (frequency == NO_RECURRENCE) {
0773:                    return NO_RECURRENCE;
0774:                } else {
0775:
0776:                    // Shouldn't happen
0777:
0778:                    throw new IllegalStateException(
0779:                            "Internal error: Unknown frequency value");
0780:                }
0781:            }
0782:
0783:            /**
0784:             * Method getCandidateStartTime
0785:             *
0786:             *
0787:             * @param	current
0788:             *
0789:             * @return	Calendar
0790:             *
0791:             */
0792:            public Calendar getCandidateStartTime(Calendar current) {
0793:                if (dtStart.getTime().getTime() > current.getTime().getTime()) {
0794:                    throw new IllegalArgumentException(
0795:                            "Current time before DtStart");
0796:                }
0797:
0798:                int minInterval = getMinimumInterval();
0799:                Calendar candidate = (Calendar) current.clone();
0800:
0801:                if (true) {
0802:
0803:                    // This block is only needed while this function is public...
0804:
0805:                    candidate.clear(Calendar.ZONE_OFFSET);
0806:                    candidate.clear(Calendar.DST_OFFSET);
0807:                    candidate.setTimeZone(TimeZone.getTimeZone("GMT"));
0808:                    candidate.setMinimalDaysInFirstWeek(4);
0809:                    candidate.setFirstDayOfWeek(dtStart.getFirstDayOfWeek());
0810:                }
0811:
0812:                if (frequency == NO_RECURRENCE) {
0813:                    candidate.setTime(dtStart.getTime());
0814:
0815:                    return candidate;
0816:                }
0817:
0818:                reduce_constant_length_field(Calendar.SECOND, dtStart,
0819:                        candidate);
0820:                reduce_constant_length_field(Calendar.MINUTE, dtStart,
0821:                        candidate);
0822:                reduce_constant_length_field(Calendar.HOUR_OF_DAY, dtStart,
0823:                        candidate);
0824:
0825:                switch (minInterval) {
0826:
0827:                case DAILY:
0828:
0829:                    /* No more adjustments needed */
0830:
0831:                    break;
0832:
0833:                case WEEKLY:
0834:                    reduce_constant_length_field(Calendar.DAY_OF_WEEK, dtStart,
0835:                            candidate);
0836:                    break;
0837:
0838:                case MONTHLY:
0839:                    reduce_day_of_month(dtStart, candidate);
0840:                    break;
0841:
0842:                case YEARLY:
0843:                    reduce_day_of_year(dtStart, candidate);
0844:                    break;
0845:                }
0846:
0847:                return candidate;
0848:            }
0849:
0850:            /**
0851:             * Method reduce_constant_length_field
0852:             *
0853:             *
0854:             * @param	field
0855:             * @param	start
0856:             * @param	candidate
0857:             *
0858:             */
0859:            protected static void reduce_constant_length_field(int field,
0860:                    Calendar start, Calendar candidate) {
0861:                if ((start.getMaximum(field) != start.getLeastMaximum(field))
0862:                        || (start.getMinimum(field) != start
0863:                                .getGreatestMinimum(field))) {
0864:                    throw new IllegalArgumentException(
0865:                            "Not a constant length field");
0866:                }
0867:
0868:                int fieldLength = (start.getMaximum(field)
0869:                        - start.getMinimum(field) + 1);
0870:                int delta = start.get(field) - candidate.get(field);
0871:
0872:                if (delta > 0) {
0873:                    delta -= fieldLength;
0874:                }
0875:
0876:                candidate.add(field, delta);
0877:            }
0878:
0879:            /**
0880:             * Method reduce_day_of_month
0881:             *
0882:             *
0883:             * @param	start
0884:             * @param	candidate
0885:             *
0886:             */
0887:            protected static void reduce_day_of_month(Calendar start,
0888:                    Calendar candidate) {
0889:                Calendar tempCal = (Calendar) candidate.clone();
0890:
0891:                tempCal.add(Calendar.MONTH, -1);
0892:
0893:                int delta = start.get(Calendar.DATE)
0894:                        - candidate.get(Calendar.DATE);
0895:
0896:                if (delta > 0) {
0897:                    delta -= tempCal.getActualMaximum(Calendar.DATE);
0898:                }
0899:
0900:                candidate.add(Calendar.DATE, delta);
0901:
0902:                while (start.get(Calendar.DATE) != candidate.get(Calendar.DATE)) {
0903:                    tempCal.add(Calendar.MONTH, -1);
0904:                    candidate.add(Calendar.DATE, -tempCal
0905:                            .getActualMaximum(Calendar.DATE));
0906:                }
0907:            }
0908:
0909:            /**
0910:             * Method reduce_day_of_year
0911:             *
0912:             *
0913:             * @param	start
0914:             * @param	candidate
0915:             *
0916:             */
0917:            protected static void reduce_day_of_year(Calendar start,
0918:                    Calendar candidate) {
0919:                if ((start.get(Calendar.MONTH) > candidate.get(Calendar.MONTH))
0920:                        || ((start.get(Calendar.MONTH) == candidate
0921:                                .get(Calendar.MONTH)) && (start
0922:                                .get(Calendar.DATE) > candidate
0923:                                .get(Calendar.DATE)))) {
0924:                    candidate.add(Calendar.YEAR, -1);
0925:                }
0926:
0927:                /* Set the candidate date to the start date. */
0928:
0929:                candidate.set(Calendar.MONTH, start.get(Calendar.MONTH));
0930:                candidate.set(Calendar.DATE, start.get(Calendar.DATE));
0931:
0932:                while ((start.get(Calendar.MONTH) != candidate
0933:                        .get(Calendar.MONTH))
0934:                        || (start.get(Calendar.DATE) != candidate
0935:                                .get(Calendar.DATE))) {
0936:                    candidate.add(Calendar.YEAR, -1);
0937:                    candidate.set(Calendar.MONTH, start.get(Calendar.MONTH));
0938:                    candidate.set(Calendar.DATE, start.get(Calendar.DATE));
0939:                }
0940:            }
0941:
0942:            /**
0943:             * Method getRecurrenceCount
0944:             *
0945:             *
0946:             * @param	candidate
0947:             *
0948:             * @return	int
0949:             *
0950:             */
0951:            protected int getRecurrenceCount(Calendar candidate) {
0952:                switch (frequency) {
0953:
0954:                case NO_RECURRENCE:
0955:                    return 0;
0956:
0957:                case DAILY:
0958:                    return (int) (getDayNumber(candidate) - getDayNumber(dtStart));
0959:
0960:                case WEEKLY:
0961:                    Calendar tempCand = (Calendar) candidate.clone();
0962:
0963:                    tempCand.setFirstDayOfWeek(dtStart.getFirstDayOfWeek());
0964:
0965:                    return (int) (getWeekNumber(tempCand) - getWeekNumber(dtStart));
0966:
0967:                case MONTHLY:
0968:                    return (int) (getMonthNumber(candidate) - getMonthNumber(dtStart));
0969:
0970:                case YEARLY:
0971:                    return candidate.get(Calendar.YEAR)
0972:                            - dtStart.get(Calendar.YEAR);
0973:
0974:                default:
0975:                    throw new IllegalStateException(
0976:                            "bad frequency internally...");
0977:                }
0978:            }
0979:
0980:            /**
0981:             * Method getDayNumber
0982:             *
0983:             *
0984:             * @param	cal
0985:             *
0986:             * @return	long
0987:             *
0988:             */
0989:            protected static long getDayNumber(Calendar cal) {
0990:                Calendar tempCal = (Calendar) cal.clone();
0991:
0992:                // Set to midnight, GMT
0993:
0994:                tempCal.set(Calendar.MILLISECOND, 0);
0995:                tempCal.set(Calendar.SECOND, 0);
0996:                tempCal.set(Calendar.MINUTE, 0);
0997:                tempCal.set(Calendar.HOUR_OF_DAY, 0);
0998:
0999:                return tempCal.getTime().getTime() / (24 * 60 * 60 * 1000);
1000:            }
1001:
1002:            /**
1003:             * Method getWeekNumber
1004:             *
1005:             *
1006:             * @param	cal
1007:             *
1008:             * @return	long
1009:             *
1010:             */
1011:            protected static long getWeekNumber(Calendar cal) {
1012:                Calendar tempCal = (Calendar) cal.clone();
1013:
1014:                // Set to midnight, GMT
1015:
1016:                tempCal.set(Calendar.MILLISECOND, 0);
1017:                tempCal.set(Calendar.SECOND, 0);
1018:                tempCal.set(Calendar.MINUTE, 0);
1019:                tempCal.set(Calendar.HOUR_OF_DAY, 0);
1020:
1021:                // Roll back to the first day of the week
1022:
1023:                int delta = tempCal.getFirstDayOfWeek()
1024:                        - tempCal.get(Calendar.DAY_OF_WEEK);
1025:
1026:                if (delta > 0) {
1027:                    delta -= 7;
1028:                }
1029:
1030:                // tempCal now points to the first instant of this week.
1031:
1032:                // Calculate the "week epoch" -- the weekstart day closest to January 1,
1033:                // 1970 (which was a Thursday)
1034:
1035:                long weekEpoch = (tempCal.getFirstDayOfWeek() - Calendar.THURSDAY)
1036:                        * 24 * 60 * 60 * 1000L;
1037:
1038:                return (tempCal.getTime().getTime() - weekEpoch)
1039:                        / (7 * 24 * 60 * 60 * 1000);
1040:            }
1041:
1042:            /**
1043:             * Method getMonthNumber
1044:             *
1045:             *
1046:             * @param	cal
1047:             *
1048:             * @return	long
1049:             *
1050:             */
1051:            protected static long getMonthNumber(Calendar cal) {
1052:                return (cal.get(Calendar.YEAR) - 1970) * 12
1053:                        + (cal.get(Calendar.MONTH) - Calendar.JANUARY);
1054:            }
1055:
1056:            /**
1057:             * Method matchesByDay
1058:             *
1059:             *
1060:             * @param	candidate
1061:             *
1062:             * @return	boolean
1063:             *
1064:             */
1065:            protected boolean matchesByDay(Calendar candidate) {
1066:                if ((byDay == null) || (byDay.length == 0)) {
1067:
1068:                    /* No byDay rules, so it matches trivially */
1069:
1070:                    return true;
1071:                }
1072:
1073:                int i;
1074:
1075:                for (i = 0; i < byDay.length; i++) {
1076:                    if (matchesIndividualByDay(candidate, byDay[i])) {
1077:                        return true;
1078:                    }
1079:                }
1080:
1081:                return false;
1082:            }
1083:
1084:            /**
1085:             * Method matchesIndividualByDay
1086:             *
1087:             *
1088:             * @param	candidate
1089:             * @param	pos
1090:             *
1091:             * @return	boolean
1092:             *
1093:             */
1094:            protected boolean matchesIndividualByDay(Calendar candidate,
1095:                    DayAndPosition pos) {
1096:                if (pos.getDayOfWeek() != candidate.get(Calendar.DAY_OF_WEEK)) {
1097:                    return false;
1098:                }
1099:
1100:                int position = pos.getDayPosition();
1101:
1102:                if (position == 0) {
1103:                    return true;
1104:                }
1105:
1106:                int field;
1107:
1108:                switch (frequency) {
1109:
1110:                case MONTHLY:
1111:                    field = Calendar.DAY_OF_MONTH;
1112:                    break;
1113:
1114:                case YEARLY:
1115:                    field = Calendar.DAY_OF_YEAR;
1116:                    break;
1117:
1118:                default:
1119:                    throw new IllegalStateException("byday has a day position "
1120:                            + "in non-MONTHLY or YEARLY recurrence");
1121:                }
1122:
1123:                if (position > 0) {
1124:                    int day_of_week_in_field = ((candidate.get(field) - 1) / 7) + 1;
1125:
1126:                    return (position == day_of_week_in_field);
1127:                } else {
1128:
1129:                    /* position < 0 */
1130:
1131:                    int negative_day_of_week_in_field = ((candidate
1132:                            .getActualMaximum(field) - candidate.get(field)) / 7) + 1;
1133:
1134:                    return (-position == negative_day_of_week_in_field);
1135:                }
1136:            }
1137:
1138:            /**
1139:             * Method matchesByField
1140:             *
1141:             *
1142:             * @param	array
1143:             * @param	field
1144:             * @param	candidate
1145:             * @param	allowNegative
1146:             *
1147:             * @return	boolean
1148:             *
1149:             */
1150:            protected static boolean matchesByField(int[] array, int field,
1151:                    Calendar candidate, boolean allowNegative) {
1152:                if ((array == null) || (array.length == 0)) {
1153:
1154:                    /* No rules, so it matches trivially */
1155:
1156:                    return true;
1157:                }
1158:
1159:                int i;
1160:
1161:                for (i = 0; i < array.length; i++) {
1162:                    int val;
1163:
1164:                    if (allowNegative && (array[i] < 0)) {
1165:
1166:                        // byMonthDay = -1, in a 31-day month, means 31
1167:
1168:                        int max = candidate.getActualMaximum(field);
1169:
1170:                        val = (max + 1) + array[i];
1171:                    } else {
1172:                        val = array[i];
1173:                    }
1174:
1175:                    if (val == candidate.get(field)) {
1176:                        return true;
1177:                    }
1178:                }
1179:
1180:                return false;
1181:            }
1182:
1183:            /**
1184:             * Method matchesByMonthDay
1185:             *
1186:             *
1187:             * @param	candidate
1188:             *
1189:             * @return	boolean
1190:             *
1191:             */
1192:            protected boolean matchesByMonthDay(Calendar candidate) {
1193:                return matchesByField(byMonthDay, Calendar.DATE, candidate,
1194:                        true);
1195:            }
1196:
1197:            /**
1198:             * Method matchesByYearDay
1199:             *
1200:             *
1201:             * @param	candidate
1202:             *
1203:             * @return	boolean
1204:             *
1205:             */
1206:            protected boolean matchesByYearDay(Calendar candidate) {
1207:                return matchesByField(byYearDay, Calendar.DAY_OF_YEAR,
1208:                        candidate, true);
1209:            }
1210:
1211:            /**
1212:             * Method matchesByWeekNo
1213:             *
1214:             *
1215:             * @param	candidate
1216:             *
1217:             * @return	boolean
1218:             *
1219:             */
1220:            protected boolean matchesByWeekNo(Calendar candidate) {
1221:                return matchesByField(byWeekNo, Calendar.WEEK_OF_YEAR,
1222:                        candidate, true);
1223:            }
1224:
1225:            /**
1226:             * Method matchesByMonth
1227:             *
1228:             *
1229:             * @param	candidate
1230:             *
1231:             * @return	boolean
1232:             *
1233:             */
1234:            protected boolean matchesByMonth(Calendar candidate) {
1235:                return matchesByField(byMonth, Calendar.MONTH, candidate, false);
1236:            }
1237:
1238:            /**
1239:             * Method toString
1240:             *
1241:             *
1242:             * @return	String
1243:             *
1244:             */
1245:            public String toString() {
1246:                StringMaker sm = new StringMaker();
1247:
1248:                sm.append(getClass().getName());
1249:                sm.append("[dtStart=");
1250:                sm.append((dtStart != null) ? dtStart.toString() : "null");
1251:                sm.append(",duration=");
1252:                sm.append((duration != null) ? duration.toString() : "null");
1253:                sm.append(",frequency=");
1254:                sm.append(frequency);
1255:                sm.append(",interval=");
1256:                sm.append(interval);
1257:                sm.append(",until=");
1258:                sm.append((until != null) ? until.toString() : "null");
1259:                sm.append(",byDay=");
1260:
1261:                if (byDay == null) {
1262:                    sm.append("null");
1263:                } else {
1264:                    sm.append("[");
1265:
1266:                    for (int i = 0; i < byDay.length; i++) {
1267:                        if (i != 0) {
1268:                            sm.append(",");
1269:                        }
1270:
1271:                        if (byDay[i] != null) {
1272:                            sm.append(byDay[i].toString());
1273:                        } else {
1274:                            sm.append("null");
1275:                        }
1276:                    }
1277:
1278:                    sm.append("]");
1279:                }
1280:
1281:                sm.append(",byMonthDay=");
1282:                sm.append(stringizeIntArray(byMonthDay));
1283:                sm.append(",byYearDay=");
1284:                sm.append(stringizeIntArray(byYearDay));
1285:                sm.append(",byWeekNo=");
1286:                sm.append(stringizeIntArray(byWeekNo));
1287:                sm.append(",byMonth=");
1288:                sm.append(stringizeIntArray(byMonth));
1289:                sm.append(']');
1290:
1291:                return sm.toString();
1292:            }
1293:
1294:            /**
1295:             * Method stringizeIntArray
1296:             *
1297:             *
1298:             * @param	a
1299:             *
1300:             * @return	String
1301:             *
1302:             */
1303:            private String stringizeIntArray(int[] a) {
1304:                if (a == null) {
1305:                    return "null";
1306:                }
1307:
1308:                StringMaker sm = new StringMaker();
1309:
1310:                sm.append("[");
1311:
1312:                for (int i = 0; i < a.length; i++) {
1313:                    if (i != 0) {
1314:                        sm.append(",");
1315:                    }
1316:
1317:                    sm.append(a[i]);
1318:                }
1319:
1320:                sm.append("]");
1321:
1322:                return sm.toString();
1323:            }
1324:
1325:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.