1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.helper;
17
18 import java.util.ArrayList;
19 import java.util.Calendar;
20 import java.util.List;
21
22 import org.codelibs.fess.exception.FessSystemException;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 public class IntervalControlHelper {
27 private static final Logger logger = LoggerFactory.getLogger(IntervalControlHelper.class);
28
29 private volatile boolean crawlerRunning = true;
30
31 public long crawlerWaitMillis = 10000;
32
33 protected List<IntervalRule> ruleList = new ArrayList<>();
34
35 public void checkCrawlerStatus() {
36 while (!crawlerRunning) {
37 try {
38 Thread.sleep(crawlerWaitMillis);
39 } catch (final InterruptedException e) {
40 if (logger.isDebugEnabled()) {
41 logger.debug("Interrupted.", e);
42 }
43 }
44 }
45 }
46
47 public void delayByRules() {
48 final long delay = getDelay();
49 if (delay > 0) {
50 try {
51 Thread.sleep(delay);
52 } catch (final InterruptedException e) {
53 if (logger.isDebugEnabled()) {
54 logger.debug("Interrupted.", e);
55 }
56 }
57 }
58 }
59
60 protected long getDelay() {
61 if (ruleList.isEmpty()) {
62 return 0;
63 }
64 final Calendar cal = getCurrentCal();
65 final int h = cal.get(Calendar.HOUR_OF_DAY);
66 final int m = cal.get(Calendar.MINUTE);
67 final int d = cal.get(Calendar.DAY_OF_WEEK);
68 for (final IntervalRule rule : ruleList) {
69 if (rule.isTarget(h, m, d)) {
70 return rule.getDelay();
71 }
72 }
73 return 0;
74 }
75
76 protected Calendar getCurrentCal() {
77 final Calendar cal = Calendar.getInstance();
78 cal.setTimeInMillis(System.currentTimeMillis());
79 return cal;
80 }
81
82 public void addIntervalRule(final String from, final String to, final String days, final long delay) {
83 ruleList.add(new IntervalRule(from, to, days, delay));
84 }
85
86 public boolean isCrawlerRunning() {
87 return crawlerRunning;
88 }
89
90 public void setCrawlerRunning(final boolean crawlerRunning) {
91 this.crawlerRunning = crawlerRunning;
92 }
93
94 public static class IntervalRule {
95 protected int fromHours;
96
97 protected int fromMinutes;
98
99 protected int toHours;
100
101 protected int toMinutes;
102
103 protected long delay;
104
105 protected int[] days;
106
107 protected boolean reverse;
108
109 public IntervalRule(final String from, final String to, final String days, final long delay) {
110 final int[] fints = parseTime(from);
111 fromHours = fints[0];
112 fromMinutes = fints[1];
113 final int[] tints = parseTime(to);
114 toHours = tints[0];
115 toMinutes = tints[1];
116 final String[] values = days.split(",");
117 final List<Integer> list = new ArrayList<>();
118 for (final String value : values) {
119 try {
120 list.add(Integer.parseInt(value.trim()));
121 } catch (final NumberFormatException e) {}
122 }
123 this.days = new int[list.size()];
124 for (int i = 0; i < list.size(); i++) {
125 this.days[i] = list.get(i);
126 }
127 this.delay = delay;
128 reverse = compareTime(fromHours, fromMinutes, toHours, toMinutes) < 0;
129 }
130
131 public long getDelay() {
132 return delay;
133 }
134
135 public boolean isTarget(final int hours, final int minutes, final int day) {
136 if (reverse) {
137 if (compareTime(hours, minutes, toHours, toMinutes) >= 0 && isInDays(day + 1)) {
138 return true;
139 } else if (compareTime(fromHours, fromMinutes, hours, minutes) >= 0 && isInDays(day)) {
140 return true;
141 }
142 return false;
143 } else {
144 return compareTime(fromHours, fromMinutes, hours, minutes) >= 0 && compareTime(hours, minutes, toHours, toMinutes) >= 0
145 && isInDays(day);
146 }
147 }
148
149 private boolean isInDays(final int day) {
150 if (days.length == 0) {
151 return true;
152 }
153 int value;
154 if (day == 8) {
155 value = 1;
156 } else {
157 value = day;
158 }
159 for (final int d : days) {
160 if (d == value) {
161 return true;
162 }
163 }
164 return false;
165 }
166
167 protected int compareTime(final int h1, final int m1, final int h2, final int m2) {
168 if (h1 < h2) {
169 return 1;
170 } else if (h1 == h2) {
171 if (m1 == m2) {
172 return 0;
173 } else if (m1 < m2) {
174 return 1;
175 }
176 }
177 return -1;
178 }
179 }
180
181 protected static int[] parseTime(final String time) {
182 final String[] froms = time.split(":");
183 if (froms.length != 2) {
184 throw new FessSystemException("Invalid format: " + time);
185 }
186 final int[] values = new int[2];
187 values[0] = Integer.parseInt(froms[0]);
188 if (values[0] < 0 || values[0] > 23) {
189 throw new FessSystemException("Invalid format: " + time);
190 }
191 values[1] = Integer.parseInt(froms[1]);
192 if (values[1] < 0 || values[1] > 59) {
193 throw new FessSystemException("Invalid format: " + time);
194 }
195 return values;
196 }
197
198 }