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