View Javadoc
1   /*
2    * Copyright 2012-2017 CodeLibs Project and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
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); // SUN(1) - SAT(7)
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 }