KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > drftpd > event > listeners > Trial


1 /*
2  * This file is part of DrFTPD, Distributed FTP Daemon.
3  *
4  * DrFTPD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * DrFTPD is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with DrFTPD; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18 package net.sf.drftpd.event.listeners;
19
20 import java.io.FileInputStream JavaDoc;
21 import java.io.FileNotFoundException JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.Calendar JavaDoc;
25 import java.util.Date JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.Properties JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29
30 import net.sf.drftpd.Bytes;
31 import net.sf.drftpd.ObjectNotFoundException;
32 import net.sf.drftpd.event.Event;
33 import net.sf.drftpd.event.FtpListener;
34 import net.sf.drftpd.event.UserEvent;
35 import net.sf.drftpd.master.ConnectionManager;
36 import net.sf.drftpd.master.config.FtpConfig;
37 import net.sf.drftpd.master.config.Permission;
38 import net.sf.drftpd.master.usermanager.User;
39 import net.sf.drftpd.util.CalendarUtils;
40
41 import org.apache.log4j.Logger;
42 import org.drftpd.plugins.SiteBot;
43
44 /**
45  * @author mog
46  * @version $Id: Trial.java,v 1.26.2.1 2004/06/27 22:22:48 mog Exp $
47  */

48 public class Trial implements FtpListener {
49     public static class Limit {
50         private String JavaDoc _actionFailed;
51         private String JavaDoc _actionPassed;
52         private long _bytes;
53         private String JavaDoc _name;
54         private int _period;
55         private Permission _perm;
56         public Limit() {
57         }
58
59         public void doFailed(User user) {
60             Trial.doAction(getActionFailed(), user);
61         }
62
63         public void doPassed(User user) {
64             Trial.doAction(getActionPassed(), user);
65         }
66
67         public String JavaDoc getActionFailed() {
68             return _actionFailed;
69         }
70
71         public String JavaDoc getActionPassed() {
72             return _actionPassed;
73         }
74
75         public long getBytes() {
76             return _bytes;
77         }
78
79         public String JavaDoc getName() {
80             return _name;
81         }
82
83         public int getPeriod() {
84             return _period;
85         }
86
87         public Permission getPerm() {
88             return _perm;
89         }
90
91         public void setActionFailed(String JavaDoc action) {
92             validateAction(action);
93             _actionFailed = action;
94         }
95
96         public void setActionPassed(String JavaDoc action) {
97             validateAction(action);
98             _actionPassed = action;
99         }
100
101         public void setBytes(long bytes) {
102             _bytes = bytes;
103         }
104
105         public void setName(String JavaDoc name) {
106             _name = name;
107         }
108
109         public void setPeriod(int period) {
110             _period = period;
111         }
112
113         public void setPerm(Permission perm) {
114             _perm = perm;
115         }
116
117         public String JavaDoc toString() {
118             return "Limit[name="
119                 + _name
120                 + ",bytes="
121                 + Bytes.formatBytes(_bytes)
122                 + ",period="
123                 + Trial.getPeriodName(_period)
124                 + "]";
125         }
126
127         private void validateAction(String JavaDoc action) {
128             if (action == null)
129                 return;
130             //action = action.toLowerCase();
131
StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(action);
132             if (!st.hasMoreTokens())
133                 return;
134             String JavaDoc cmd = st.nextToken();
135             if (!("delete".equals(action)
136                 || "purge".equals(action)
137                 || "chgrp".equals(cmd)
138                 || "setgrp".equals(cmd))) {
139                 throw new IllegalArgumentException JavaDoc(
140                     cmd + " is not a valid action");
141             }
142             if ("setgrp".equals(cmd)) {
143                 st.nextToken();
144                 if (st.hasMoreTokens())
145                     throw new IllegalArgumentException JavaDoc(
146                         "extra tokens in \"" + action + "\"");
147             }
148         }
149     }
150     private static final Logger logger = Logger.getLogger(Trial.class);
151     
152     public static final int PERIOD_ALL = 0;
153
154     public static final int PERIOD_DAILY = Calendar.DAY_OF_MONTH; // = 5
155
public static final short PERIOD_MONTHLY = Calendar.MONTH; // = 2
156
public static final short PERIOD_WEEKLY = Calendar.WEEK_OF_YEAR; // = 3
157
public static void doAction(String JavaDoc action, User user) {
158         try {
159             if (action == null)
160                 return;
161             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(action);
162             if (!st.hasMoreTokens()) {
163                 logger.info(user.getUsername() + " no action specified");
164                 return;
165             }
166             String JavaDoc cmd = st.nextToken().toLowerCase();
167             if ("chgrp".equals(cmd)) {
168                 while (st.hasMoreTokens()) {
169                     user.toggleGroup(st.nextToken());
170                 }
171             } else if ("setgrp".equals(cmd)) {
172                 user.setGroup(st.nextToken(""));
173                 logger.info(
174                     user.getUsername()
175                         + " primary group set to "
176                         + user.getGroupName());
177             } else if ("delete".equals(cmd)) {
178                 user.setDeleted(true);
179                 logger.info(user.getUsername() + " deleted");
180             } else if ("purge".equals(cmd)) {
181                 user.setDeleted(true);
182                 user.purge();
183                 logger.info(user.getUsername() + " purged");
184             }
185         } catch (java.util.NoSuchElementException JavaDoc e) {
186             logger.info("Error parsing \"" + action + "\"", e);
187         }
188     }
189
190     public static Calendar JavaDoc getCalendarForEndOfBonus(User user, int period) {
191         Calendar JavaDoc cal = Calendar.getInstance();
192         cal.setTimeInMillis(user.getCreated());
193         moveCalendarToEndOfPeriod(cal, period);
194         return cal;
195     }
196
197     /**
198      * Returns last day of the first, unique, period.
199      */

200     public static Calendar JavaDoc getCalendarForEndOfFirstPeriod(
201         User user,
202         int period) {
203         Calendar JavaDoc cal = Calendar.getInstance();
204         cal.setTime(new Date JavaDoc(user.getCreated()));
205         CalendarUtils.ceilAllLessThanDay(cal);
206
207         switch (period) {
208             case PERIOD_DAILY :
209                 //user added on monday @ 15:00, trial ends on tuesday with reset at 23:59
210
//bonus ends at tuesday 23:59
211
CalendarUtils.incrementDay(cal);
212                 return cal;
213             case PERIOD_WEEKLY :
214                 //user added on week 1, wednsday @ 15:00, trial
215
//trial ends with a reset at week 2, wednsday 24:00
216
//bonus ends on week 3, monday 00:00
217
CalendarUtils.incrementWeek(cal);
218                 return cal;
219             case PERIOD_MONTHLY :
220                 //user added on january 31 15:00
221
//trial ends on feb 28 24:00
222
//bonus ends on mar 1 00:00
223
CalendarUtils.incrementMonth(cal);
224                 return cal;
225             default :
226                 throw new IllegalArgumentException JavaDoc(
227                     "Don't know how to handle " + period);
228         }
229     }
230     public static Calendar JavaDoc getCalendarForEndOfPeriod(int period) {
231         Calendar JavaDoc cal = Calendar.getInstance();
232         CalendarUtils.ceilAllLessThanDay(cal);
233         switch (period) {
234             case PERIOD_DAILY :
235                 break;
236             case PERIOD_WEEKLY :
237                 int dow = CalendarUtils.getLastDayOfWeek(cal);
238                 //dow is less than current day of week, increment week
239
if (dow < cal.get(Calendar.DAY_OF_WEEK)) {
240                     cal.add(Calendar.WEEK_OF_YEAR, 1);
241                 }
242                 cal.set(Calendar.DAY_OF_WEEK, dow);
243                 return cal;
244             case PERIOD_MONTHLY :
245                 cal.set(
246                     Calendar.DAY_OF_MONTH,
247                     cal.getActualMaximum(Calendar.DAY_OF_MONTH));
248                 return cal;
249             default :
250                 throw new IllegalArgumentException JavaDoc("" + period);
251         }
252         //moveCalendarToEndOfPeriod(cal, period);
253
return cal;
254     }
255
256     public static String JavaDoc getPeriodName(int s) {
257         switch (s) {
258             case PERIOD_DAILY :
259                 return "day";
260             case PERIOD_MONTHLY :
261                 return "month";
262             case PERIOD_WEEKLY :
263                 return "week";
264             default :
265                 throw new IllegalArgumentException JavaDoc("" + s);
266         }
267     }
268
269     public static String JavaDoc getPeriodName2(int s) {
270         switch (s) {
271             case PERIOD_DAILY :
272                 return "daily";
273             case PERIOD_MONTHLY :
274                 return "monthly";
275             case PERIOD_WEEKLY :
276                 return "weekly";
277             default :
278                 throw new IllegalArgumentException JavaDoc("" + s);
279         }
280     }
281
282     public static long getUploadedBytesForPeriod(User user, int period) {
283         if (isInFirstPeriod(user, period))
284             return user.getDownloadedBytes();
285         switch (period) {
286             case PERIOD_DAILY :
287                 return user.getUploadedBytesDay();
288             case PERIOD_WEEKLY :
289                 return user.getUploadedBytesWeek();
290             case PERIOD_MONTHLY :
291                 return user.getUploadedBytesMonth();
292             default :
293                 throw new IllegalArgumentException JavaDoc();
294         }
295     }
296
297     public static boolean isInFirstPeriod(User user, int period) {
298         return isInFirstPeriod(user, period, System.currentTimeMillis());
299     }
300
301     public static boolean isInFirstPeriod(User user, int period, long time) {
302         return time <= getCalendarForEndOfBonus(user, period).getTimeInMillis();
303     }
304
305     public static Calendar JavaDoc moveCalendarToEndOfPeriod(
306         Calendar JavaDoc cal,
307         int period) {
308         CalendarUtils.ceilAllLessThanDay(cal);
309         switch (period) {
310             case PERIOD_DAILY :
311                 //CalendarUtils.incrementDay(cal);
312
return cal;
313             case PERIOD_WEEKLY :
314                 CalendarUtils.incrementWeek(cal);
315                 return cal;
316             case PERIOD_MONTHLY :
317                 CalendarUtils.incrementMonth(cal);
318                 return cal;
319             default :
320                 throw new IllegalArgumentException JavaDoc("" + period);
321         }
322     }
323
324     private ConnectionManager _cm;
325
326     private ArrayList JavaDoc _limits;
327     private TrialSiteBot _siteBot;
328
329     public Trial() throws FileNotFoundException JavaDoc, IOException JavaDoc {
330         super();
331     }
332
333     public void actionPerformed(Event event) {
334         if (!(event instanceof UserEvent))
335             return;
336         UserEvent uevent = (UserEvent) event;
337         String JavaDoc cmd = event.getCommand();
338
339         if ("RELOAD".equals(cmd)) {
340             reload();
341             return;
342         }
343
344         //logger.debug("event.getTime(): " + new Date(event.getTime()));
345
//logger.debug(
346
// "uevent.getUser().getLastReset(): "
347
// + new Date(uevent.getUser().getLastReset()));
348

349         if ("RESETDAY".equals(cmd)) {
350
351             Calendar JavaDoc cal;
352
353             //MONTH UNIQUE //
354
cal =
355                 getCalendarForEndOfFirstPeriod(
356                     uevent.getUser(),
357                     PERIOD_MONTHLY);
358             //logger.debug("end of first, montly, period: " + cal.getTime());
359
//last reset before unique period and event time equals or bigger than unique period
360
if (uevent.getUser().getLastReset() <= cal.getTimeInMillis()
361                 && uevent.getTime() >= cal.getTimeInMillis()) {
362                 checkPassed(
363                     uevent.getUser(),
364                     uevent.getUser().getUploadedBytes(),
365                     PERIOD_MONTHLY);
366             }
367
368             // WEEK UNIQUE //
369
// if less than month unique period
370
if (uevent.getTime() < cal.getTimeInMillis()) {
371                 cal =
372                     getCalendarForEndOfFirstPeriod(
373                         uevent.getUser(),
374                         PERIOD_WEEKLY);
375                 //logger.debug("end of first, weekly, period: " + cal.getTime());
376
//last reset before unique period and event time equals or bigger than unique period
377
if (uevent.getUser().getLastReset() <= cal.getTimeInMillis()
378                     && uevent.getTime() >= cal.getTimeInMillis()) {
379                     checkPassed(
380                         uevent.getUser(),
381                         uevent.getUser().getUploadedBytes(),
382                         PERIOD_WEEKLY);
383                 }
384             }
385
386             // DAY UNIQUE //
387
//if event lesss than week unique period (cal)
388
if (uevent.getTime() < cal.getTimeInMillis()) {
389                 cal =
390                     getCalendarForEndOfFirstPeriod(
391                         uevent.getUser(),
392                         PERIOD_DAILY);
393                 //logger.debug("end of first day period: " + cal.getTime());
394
//is day unique period
395
if (uevent.getUser().getLastReset() <= cal.getTimeInMillis()
396                     && uevent.getTime() >= cal.getTimeInMillis()) {
397                     checkPassed(
398                         uevent.getUser(),
399                         uevent.getUser().getUploadedBytes(),
400                         PERIOD_DAILY);
401                     //after day unique period
402
} else if (uevent.getTime() > cal.getTimeInMillis()) {
403                     checkPassed(
404                         uevent.getUser(),
405                         uevent.getUser().getUploadedBytesDay(),
406                         PERIOD_DAILY);
407                 }
408             } else {
409                 //always check if after
410
checkPassed(
411                     uevent.getUser(),
412                     uevent.getUser().getUploadedBytesDay(),
413                     PERIOD_DAILY);
414             }
415         }
416         if ("RESETWEEK".equals(cmd)) {
417             if (!isInFirstPeriod(uevent.getUser(),
418                 PERIOD_WEEKLY,
419                 uevent.getTime())) {
420                 checkPassed(
421                     uevent.getUser(),
422                     uevent.getUser().getUploadedBytesWeek(),
423                     PERIOD_WEEKLY);
424             }
425         }
426         if ("RESETMONTH".equals(cmd)) {
427             if (!isInFirstPeriod(uevent.getUser(),
428                 PERIOD_MONTHLY,
429                 uevent.getTime())) {
430                 checkPassed(
431                     uevent.getUser(),
432                     uevent.getUser().getUploadedBytesMonth(),
433                     PERIOD_MONTHLY);
434             }
435         }
436     }
437
438     private void checkPassed(User user, long bytes, int period) {
439         for (Iterator JavaDoc iter = _limits.iterator(); iter.hasNext();) {
440             Limit limit = (Limit) iter.next();
441             if (limit.getPeriod() == period && limit.getPerm().check(user)) {
442                 long bytesleft = limit.getBytes() - bytes;
443                 if (bytesleft > 0) {
444                     logger.info(
445                         user.getUsername()
446                             + " failed "
447                             + limit.getName()
448                             + " by "
449                             + Bytes.formatBytes(bytesleft));
450                     limit.doFailed(user);
451                 } else {
452                     logger.info(
453                         user.getUsername()
454                             + " passed "
455                             + limit.getName()
456                             + " with "
457                             + Bytes.formatBytes(-bytesleft)
458                             + " extra");
459                     limit.doPassed(user);
460                 }
461             }
462         }
463     }
464
465     ConnectionManager getConnectionManager() {
466         return _cm;
467     }
468
469     public ArrayList JavaDoc getLimits() {
470         return _limits;
471     }
472     public void init(ConnectionManager mgr) {
473         _cm = mgr;
474         reload();
475     }
476
477     private void reload() {
478         Properties JavaDoc props = new Properties JavaDoc();
479         try {
480             props.load(new FileInputStream JavaDoc("conf/trial.conf"));
481         } catch (IOException JavaDoc e) {
482             throw new RuntimeException JavaDoc(e);
483         }
484         reload(props);
485     }
486
487     public void reload(ArrayList JavaDoc limits) {
488         _limits = limits;
489
490         if (_siteBot != null) {
491             _siteBot.disable();
492         }
493         if (_cm != null) {
494             try {
495                 SiteBot _irc =
496                     (SiteBot) _cm.getFtpListener(SiteBot.class);
497                 _siteBot = new TrialSiteBot(this, _irc);
498             } catch (ObjectNotFoundException e1) {
499                 logger.warn("Error loading sitebot component, sitebot announcements disabled.", e1);
500             }
501         }
502     }
503
504     protected void reload(Properties JavaDoc props) {
505         ArrayList JavaDoc limits = new ArrayList JavaDoc();
506         for (int i = 1;; i++) {
507             if (props.getProperty(i + ".quota") == null)
508                 break;
509             Limit limit = new Limit();
510             limit.setName(FtpConfig.getProperty(props, i + ".name"));
511             limit.setActionPassed(
512                 props.getProperty(
513                     i + ".pass",
514                     props.getProperty(i + ".passed", "")));
515             limit.setActionFailed(
516                 props.getProperty(i + ".fail", ""));
517             if (limit.getActionFailed().equals("")
518                 && limit.getActionPassed().equals(""))
519                 throw new IllegalArgumentException JavaDoc(
520                     "Both .passed and .fail cannot be empty for "
521                         + i
522                         + " ("
523                         + limit.getName()
524                         + ")");
525             String JavaDoc period =
526                 FtpConfig.getProperty(props, i + ".period").toLowerCase();
527             if ("monthly".equals(period)) {
528                 limit.setPeriod(PERIOD_MONTHLY);
529             } else if ("weekly".equals(period)) {
530                 limit.setPeriod(PERIOD_WEEKLY);
531             } else if ("daily".equals(period)) {
532                 limit.setPeriod(PERIOD_DAILY);
533             } else {
534                 throw new RuntimeException JavaDoc(
535                     new IOException JavaDoc(period + " is not a recognized period"));
536             }
537             String JavaDoc perm = props.getProperty(i + ".perm");
538             if (perm == null)
539                 perm = "*";
540             limit.setPerm(
541                 new Permission(FtpConfig.makeUsers(new StringTokenizer JavaDoc(perm))));
542             limit.setBytes(
543                 Bytes.parseBytes(FtpConfig.getProperty(props, i + ".quota")));
544             limits.add(limit);
545             logger.debug("Limit: " + limit);
546         }
547         reload(limits);
548     }
549
550     public void unload() {
551         if(_siteBot != null) {
552             _siteBot.disable();
553         }
554     }
555 }
556
Popular Tags