1 /* 2 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 import java.util.ArrayList; 27 import java.util.HashMap; 28 import java.util.List; 29 import java.util.Map; 30 31 /** 32 * RuleDay class represents the value of the "ON" field. The day of 33 * week values start from 1 following the {@link java.util.Calendar} 34 * convention. 35 * 36 * @since 1.4 37 */ 38 class RuleDay { 39 private static final Map<String,DayOfWeek> abbreviations = new HashMap<String,DayOfWeek>(7); 40 static { 41 for (DayOfWeek day : DayOfWeek.values()) { 42 abbreviations.put(day.getAbbr(), day); 43 } 44 } 45 46 private String dayName = null; 47 private DayOfWeek dow; 48 private boolean lastOne = false; 49 private int soonerOrLater = 0; 50 private int thanDayOfMonth; // day of month (e.g., 8 for "Sun>=8") 51 52 RuleDay() { 53 } 54 55 RuleDay(int day) { 56 thanDayOfMonth = day; 57 } 58 59 int getDay() { 60 return thanDayOfMonth; 61 } 62 63 /** 64 * @return the day of week value (1-based) 65 */ 66 int getDayOfWeekNum() { 67 return dow.value(); 68 } 69 70 /** 71 * @return true if this rule day represents the last day of 72 * week. (e.g., lastSun). 73 */ 74 boolean isLast() { 75 return lastOne; 76 } 77 78 /** 79 * @return true if this rule day represents the day of week on or 80 * later than (after) the {@link #getDay}. (e.g., Sun>=1) 81 */ 82 boolean isLater() { 83 return soonerOrLater > 0; 84 } 85 86 /** 87 * @return true if this rule day represents the day of week on or 88 * earlier than (before) the {@link #getDay}. (e.g., Sun<=15) 89 */ 90 boolean isEarlier() { 91 return soonerOrLater < 0; 92 } 93 94 /** 95 * @return true if this rule day represents an exact day. 96 */ 97 boolean isExact() { 98 return soonerOrLater == 0; 99 } 100 101 /** 102 * Parses the "ON" field and constructs a RuleDay. 103 * @param day an "ON" field string (e.g., "Sun>=1") 104 * @return a RuleDay representing the given "ON" field 105 */ 106 static RuleDay parse(String day) { 107 RuleDay d = new RuleDay(); 108 if (day.startsWith("last")) { 109 d.lastOne = true; 110 d.dayName = day.substring(4); 111 d.dow = getDOW(d.dayName); 112 } else { 113 int index; 114 if ((index = day.indexOf(">=")) != -1) { 115 d.dayName = day.substring(0, index); 116 d.dow = getDOW(d.dayName); 117 d.soonerOrLater = 1; // greater or equal 118 d.thanDayOfMonth = Integer.parseInt(day.substring(index+2)); 119 } else if ((index = day.indexOf("<=")) != -1) { 120 d.dayName = day.substring(0, index); 121 d.dow = getDOW(d.dayName); 122 d.soonerOrLater = -1; // less or equal 123 d.thanDayOfMonth = Integer.parseInt(day.substring(index+2)); 124 } else { 125 // it should be an integer value. 126 d.thanDayOfMonth = Integer.parseInt(day); 127 } 128 } 129 return d; 130 } 131 132 /** 133 * Converts this RuleDay to the SimpleTimeZone day rule. 134 * @return the converted SimpleTimeZone day rule 135 */ 136 int getDayForSimpleTimeZone() { 137 if (isLast()) { 138 return -1; 139 } 140 return isEarlier() ? -getDay() : getDay(); 141 } 142 143 /** 144 * Converts this RuleDay to the SimpleTimeZone day-of-week rule. 145 * @return the SimpleTimeZone day-of-week rule value 146 */ 147 int getDayOfWeekForSimpleTimeZoneInt() { 148 if (isEarlier() || isLater()) { 149 return -getDayOfWeekNum(); 150 } 151 return isLast() ? getDayOfWeekNum() : 0; 152 } 153 154 /** 155 * @return the string representation of the {@link 156 * #getDayOfWeekForSimpleTimeZoneInt} value 157 */ 158 String getDayOfWeekForSimpleTimeZone() { 159 int d = getDayOfWeekForSimpleTimeZoneInt(); 160 if (d == 0) { 161 return "0"; 162 } 163 String sign = ""; 164 if (d < 0) { 165 sign = "-"; 166 d = -d; 167 } 168 return sign + toString(d); 169 } 170 171 private static DayOfWeek getDOW(String abbr) { 172 return abbreviations.get(abbr); 173 } 174 175 /** 176 * Converts the specified day of week value to the day-of-week 177 * name defined in {@link java.util.Calenda}. 178 * @param dow 1-based day of week value 179 * @return the Calendar day of week name with "Calendar." prefix. 180 * @throws IllegalArgumentException if the specified dow value is out of range. 181 */ 182 static String toString(int dow) { 183 if (dow >= DayOfWeek.SUNDAY.value() && dow <= DayOfWeek.SATURDAY.value()) { 184 return "Calendar." + DayOfWeek.values()[dow - 1]; 185 } 186 throw new IllegalArgumentException("wrong Day_of_Week number: " + dow); 187 } 188 }