KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > killingar > forum > internal > managers > AreaManager


1 /* Copyright 2000-2005 Anders Hovmöller
2  *
3  * The person or persons who have associated their work with
4  * this document (the "Dedicator") hereby dedicate the entire
5  * copyright in the work of authorship identified below (the
6  * "Work") to the public domain.
7  *
8  * Dedicator makes this dedication for the benefit of the
9  * public at large and to the detriment of Dedicator's heirs
10  * and successors. Dedicator intends this dedication to be an
11  * overt act of relinquishment in perpetuity of all present
12  * and future rights under copyright law, whether vested or
13  * contingent, in the Work. Dedicator understands that such
14  * relinquishment of all rights includes the relinquishment of
15  * all rights to enforce (by lawsuit or otherwise) those
16  * copyrights in the Work.
17  *
18  * Dedicator recognizes that, once placed in the public
19  * domain, the Work may be freely reproduced, distributed,
20  * transmitted, used, modified, built upon, or otherwise
21  * exploited by anyone for any purpose, commercial or non-
22  * commercial, and in any way, including by methods that have
23  * not yet been invented or conceived.
24  */

25
26 /**
27  * Manager for the areas.
28  */

29 package net.killingar.forum.internal.managers;
30
31 import it.unimi.dsi.fastutil.longs.Long2ObjectAVLTreeMap;
32 import it.unimi.dsi.fastutil.longs.LongArrayList;
33 import net.killingar.forum.internal.*;
34 import net.killingar.forum.internal.caches.MessageCache;
35
36 import java.sql.*;
37 import java.util.ArrayList JavaDoc;
38 import java.util.List JavaDoc;
39
40 public final class AreaManager extends AbstractManager implements java.io.Serializable JavaDoc
41 {
42     // caching data (only for the current user)
43
private int messagesPerPage = 32;
44     //private static transient Long2ObjectAVLTreeMap accessLevels = new Long2ObjectAVLTreeMap();
45
private static transient Long2ObjectAVLTreeMap messageCaches = new Long2ObjectAVLTreeMap(); // list of MessageCache objects
46

47     /**
48      * Set how many messages should be displayed per page.
49      */

50     public void setMessagesPerPage(int no)
51     {
52         messagesPerPage = no;
53     }
54
55     /**
56      * Get how many messages should be displayed per page.
57      */

58     public int getMessagesPerPage()
59     {
60         return messagesPerPage;
61     }
62
63     /**
64      * Get area group info.
65      */

66     public AreaGroup getAreaGroup(long areaGroupID) throws SQLException
67     {
68         Connection c = null;
69         Statement statement = null;
70         ResultSet result = null;
71
72         try
73         {
74             c = getNewConnection();
75             statement = c.createStatement();
76
77             result = statement.executeQuery("select AreaGroup, User, Name from AreaGroups where ID = "+areaGroupID);
78             AreaGroup r = null;
79             if (result.next())
80             {
81                 r = new AreaGroup(
82                     areaGroupID,
83                     result.getLong(1),
84                     result.getLong(2),
85                     result.getString(3));
86             }
87
88             return r;
89         }
90         finally { closeAll(c, statement, result); }
91     }
92
93     /**
94      * Add an area group.
95      */

96     public long addAreaGroup(AreaGroup areaGroup) throws SQLException, AccessDeniedException
97     {
98         // check access
99
checkMyAccess(areaGroup.parentID, AccessLevel.addAreaGroup);
100
101         Connection c = null;
102         PreparedStatement statement = null;
103         ResultSet result = null;
104
105         try
106         {
107             c = getNewConnection();
108             statement = c.prepareStatement("select ID from AreaGroups where AreaGroup = ? AND Name = ?");
109             statement.setLong(1, areaGroup.getParentID());
110             statement.setString(2, areaGroup.getName());
111
112             // create
113
result = statement.executeQuery();
114             if (result.next())
115             {
116                 throw new AccessDeniedException("an area group with this name already exists");
117             }
118
119             statement = c.prepareStatement("insert into AreaGroups (AreaGroup, User, Name, LastChanged, LastChangedUser) values (?, ?, ?, NOW(), ?)");
120             statement.setLong(1, areaGroup.getParentID());
121             statement.setLong(2, manager.getUserID());
122             statement.setString(3, areaGroup.getName());
123             statement.setLong(4, manager.getUserID());
124             statement.executeUpdate();
125
126             result = statement.getGeneratedKeys();
127             result.next();
128             return result.getLong(1);
129         }
130         finally { closeAll(c, statement, result); }
131     }
132
133     /**
134      * Remove an area group.
135      */

136     public void removeAreaGroup(long areaGroupID) throws SQLException, AccessDeniedException
137     {
138         AreaGroup areaGroup = getAreaGroup(areaGroupID);
139         // check access
140
if (areaGroup.ownerID != manager.getUserID())
141             checkMyAccess(areaGroup.ID, AccessLevel.removeAreaGroup);
142
143         // remove
144
Connection c = null;
145         Statement statement = null;
146         ResultSet result = null;
147
148         try
149         {
150             c = getNewConnection();
151             statement = c.createStatement();
152
153             statement.executeUpdate("remove from AreaGroups where ID = "+areaGroupID);
154         }
155         finally { closeAll(c, statement, result); }
156     }
157
158     /**
159      * Change an area group.
160      */

161     public void changeAreaGroup(AreaGroup areaGroup) throws SQLException, AccessDeniedException
162     {
163         AreaGroup _areaGroup = getAreaGroup(areaGroup.ID);
164         // check access
165
if (_areaGroup.ownerID != manager.getUserID())
166             checkMyAccess(areaGroup.ID, AccessLevel.changeAreaGroup);
167
168         if (_areaGroup.parentID != areaGroup.parentID) // moving area group
169
{
170             // check access on areagroup we're moving to
171
_areaGroup = getAreaGroup(areaGroup.parentID);
172             if (_areaGroup.ownerID != manager.getUserID())
173                 checkMyAccess(_areaGroup.ID, AccessLevel.addAreaGroup);
174         }
175
176         if (areaGroup.parentID == areaGroup.ID)
177             throw new AccessDeniedException("attempt to move an areagroup into itself");
178
179         Connection c = null;
180         PreparedStatement statement = null;
181         ResultSet result = null;
182
183         try
184         {
185             c = getNewConnection();
186             statement = c.prepareStatement("select ID from AreaGroups where AreaGroup = ? AND Name = ? AND ID != ?");
187             statement.setLong(1, areaGroup.getParentID());
188             statement.setString(2, areaGroup.getName());
189             statement.setLong(3, areaGroup.getId());
190
191             result = statement.executeQuery();
192             if (result.next())
193                 throw new AccessDeniedException("an area group with this name already exists");
194
195             // change
196
statement = c.prepareStatement("update AreaGroups set User = ?, AreaGroup = ?, Name = ?, LastChanged = NOW(), LastChangedUser = ? where ID = ?");
197             statement.setLong(1, areaGroup.ownerID);
198             statement.setLong(2, areaGroup.parentID);
199             statement.setString(3, areaGroup.getName());
200             statement.setLong(4, manager.getUserID());
201             statement.setLong(5, areaGroup.getId());
202             statement.executeUpdate();
203         }
204         finally { closeAll(c, statement, result); }
205     }
206
207     private AreaGroup getAreaGroup(ResultSet result) throws SQLException
208     {
209         return new AreaGroup(
210             result.getLong("ID"),
211             result.getLong("AreaGroup"),
212             result.getLong("User"),
213             result.getString("Name"));
214     }
215
216     /**
217      * Get area group children. If areaGroupID == -1 returns a list of top level area groups.
218      */

219     public AreaGroup[] getAreaGroups(long areaGroupID) throws SQLException
220     {
221         Connection c = null;
222         Statement statement = null;
223         ResultSet result = null;
224
225         try
226         {
227             c = getNewConnection();
228             statement = c.createStatement();
229
230             if (areaGroupID == -1)
231                 result = statement.executeQuery("select * from AreaGroups where AreaGroup is NULL OR AreaGroup = -1");
232             else
233              result = statement.executeQuery("select * from AreaGroups where AreaGroup = "+areaGroupID);
234             List v = new ArrayList();
235             while (result.next())
236             {
237                 v.add(getAreaGroup(result));
238             }
239
240             AreaGroup r[] = new AreaGroup[v.size()];
241             v.toArray(r);
242             return r;
243         }
244         finally { closeAll(c, statement, result); }
245     }
246
247     /**
248      * Get all area groups.
249      */

250     public AreaGroup[] getAreaGroups() throws SQLException
251     {
252         Connection c = null;
253         Statement statement = null;
254         ResultSet result = null;
255
256         try
257         {
258             c = getNewConnection();
259             statement = c.createStatement();
260
261             result = statement.executeQuery("select * from AreaGroups");
262             List v = new ArrayList();
263             while (result.next())
264             {
265                 v.add(getAreaGroup(result));
266             }
267
268             AreaGroup r[] = new AreaGroup[v.size()];
269             v.toArray(r);
270             return r;
271         }
272         finally { closeAll(c, statement, result); }
273     }
274
275     private Area getArea(ResultSet r) throws SQLException
276     {
277         return new Area(r.getLong("ID"), r.getLong("AreaGroup"), r.getString("Name"), r.getString("Mode"), r.getString("Description"), r.getString("Custom"));
278     }
279
280     /**
281      * Get Areas in an area group.
282      */

283     public Area[] getAreasInGroup(long areaGroupID) throws SQLException
284     {
285         Connection c = null;
286         Statement statement = null;
287         ResultSet result = null;
288
289         try
290         {
291             c = getNewConnection();
292             statement = c.createStatement();
293
294             result = statement.executeQuery("select * from Areas where AreaGroup = "+areaGroupID);
295             List v = new ArrayList();
296             while (result.next())
297             {
298                 v.add(getArea(result));
299             }
300
301             Area r[] = new Area[v.size()];
302             v.toArray(r);
303             return r;
304         }
305         finally { closeAll(c, statement, result); }
306     }
307
308     /**
309      * Add an area.
310      */

311     public long addArea(Area area) throws SQLException, AccessDeniedException
312     {
313         AreaGroup areaGroup = getAreaGroup(area.areaGroupID);
314         if (areaGroup == null)
315             throw new AccessDeniedException("create top-level areas forbidden");
316
317         checkMyAccess(areaGroup.ID, AccessLevel.addArea);
318
319         Connection c = null;
320         PreparedStatement statement = null;
321         ResultSet result = null;
322
323         try
324         {
325             c = getNewConnection();
326             statement = c.prepareStatement("select ID from Areas where Name = ? AND AreaGroup = ?");
327             statement.setString(1, area.name);
328             statement.setLong(2, area.areaGroupID);
329
330             result = statement.executeQuery();
331             if (result.next())
332             {
333                 throw new AccessDeniedException("an area with this name already exists in the specified area group");
334             }
335
336             statement = c.prepareStatement("insert into Areas (AreaGroup, Name, Mode, Description, LastChanged, LastChangedUser, Custom) values(?, ?, ?, ?, NOW(), ?, ?)");
337             statement.setLong(1, area.areaGroupID);
338             statement.setString(2, area.name);
339             statement.setString(3, area.description);
340             statement.setString(4, area.mode);
341             statement.setLong(5, manager.getUserID());
342             statement.setString(6, area.custom);
343             statement.executeUpdate();
344
345             result = statement.getGeneratedKeys();
346             result.next();
347             return result.getLong(1);
348         }
349         finally { closeAll(c, statement, result); }
350     }
351
352     /**
353      * Remove an area.
354      */

355     public void removeArea(long areaID) throws SQLException, AccessDeniedException
356     {
357         Area area = getArea(areaID);
358         AreaGroup areaGroup = getAreaGroup(area.areaGroupID);
359         // check access
360
if (areaGroup.ownerID != manager.getUserID())
361             checkMyAccess(areaGroup.ID, AccessLevel.removeArea);
362
363         Connection c = null;
364         Statement statement = null;
365         ResultSet result = null;
366
367         try
368         {
369             c = getNewConnection();
370             statement = c.createStatement();
371
372             // remove
373
statement.executeUpdate("remove from Areas where ID = "+area.ID);
374         }
375         finally { closeAll(c, statement, result); }
376     }
377
378     /**
379      * Change an area.
380      */

381     public void changeArea(Area area) throws SQLException, AccessDeniedException
382     {
383         long oldAreaGroupID = getArea(area.ID).areaGroupID; // don't trust the value given
384
AreaGroup areaGroup = getAreaGroup(oldAreaGroupID);
385         // check access
386
if (areaGroup.ownerID != manager.getUserID())
387             checkMyAccess(areaGroup.ID, AccessLevel.changeArea);
388         if (oldAreaGroupID != area.areaGroupID) // moving area
389
{
390             // check access on areagroup we're moving to
391
areaGroup = getAreaGroup(area.areaGroupID);
392             if (areaGroup == null)
393                 throw new RuntimeException JavaDoc("areagroup "+area.areaGroupID+" not found");
394
395             if (areaGroup.ownerID != manager.getUserID())
396                 checkMyAccess(areaGroup.ID, AccessLevel.addArea);
397         }
398
399         Connection c = null;
400         PreparedStatement statement = null;
401         ResultSet result = null;
402
403         try
404         {
405             c = getNewConnection();
406             statement = c.prepareStatement("select ID from Areas where Name = ? AND AreaGroup = ?");
407             statement.setString(1, area.name);
408             statement.setLong(2, area.areaGroupID);
409
410             result = statement.executeQuery();
411             if (result.next() && result.getLong(1) != area.ID)
412             {
413                 throw new AccessDeniedException("an area with this name already exists in the specified area group");
414             }
415
416             if ("".equals(area.description))
417                 area.description = null;
418
419             if ("".equals(area.custom))
420                 area.custom = null;
421
422             // change
423
statement = c.prepareStatement("update Areas set AreaGroup = ?, Name = ?, Mode = ?, Description = ?, LastChanged = NOW(), LastChangedUser = ?, Custom = ? where ID = ?");
424             statement.setLong(1, area.areaGroupID);
425             statement.setString(2, area.name);
426             statement.setString(3, area.mode);
427             statement.setString(4, area.description);
428             statement.setLong(5, manager.getUserID());
429             statement.setString(6, area.custom);
430             statement.setLong(7, area.ID);
431             System.err.println("areamanager: "+area.custom);
432             statement.executeUpdate();
433         }
434         finally { closeAll(c, statement, result); }
435     }
436
437
438     /**
439      * Get the last time the user read the area.
440      */

441     public Timestamp getTimeOnArea(long areaID) throws Exception JavaDoc
442     {
443         return ((TimeManager)manager.getManager(TimeManager.class.getName())).getUserDataTime(TimeManager.systemAreas, areaID);
444     }
445
446     /**
447      * Returns true if the specied area is not read.
448      */

449     public boolean isUnreadArea(long areaID) throws Exception JavaDoc
450     {
451         TimeManager times = ((TimeManager)manager.getManager(TimeManager.class.getName()));
452         return times.getUserDataTime(TimeManager.systemAreas, areaID).before(times.getTime(TimeManager.systemAreas, areaID));
453     }
454
455     /**
456      * Get a list of areas.
457      */

458   public Area[] getAreas() throws SQLException
459   {
460         Connection c = null;
461         Statement statement = null;
462         ResultSet result = null;
463
464         try
465         {
466             c = getNewConnection();
467             statement = c.createStatement();
468
469             result = statement.executeQuery("select * from Areas");
470             List v = new ArrayList();
471             while (result.next())
472             {
473                 v.add(getArea(result));
474             }
475
476             Area r[] = new Area[v.size()];
477             v.toArray(r);
478             return r;
479         }
480         finally { closeAll(c, statement, result); }
481     }
482
483     /**
484      * Get area data.
485      */

486     public Area getArea(long areaID) throws SQLException
487     {
488         Connection c = null;
489         Statement statement = null;
490         ResultSet result = null;
491
492         try
493         {
494             c = getNewConnection();
495             statement = c.createStatement();
496
497             result = statement.executeQuery("select * from Areas where ID = "+areaID);
498             if (result.next())
499                 return getArea(result);
500
501             return null;
502         }
503         finally { closeAll(c, statement, result); }
504     }
505
506     /**
507      * Set the specified area to unread status for the current user.
508      */

509     public void setRead(long areaID, Timestamp timestamp) throws SQLException, AccessDeniedException, ClassNotFoundException JavaDoc, InstantiationException JavaDoc, IllegalAccessException JavaDoc
510     {
511         TimeManager times = ((TimeManager)manager.getManager(TimeManager.class.getName()));
512         times.setUserTime(TimeManager.systemWelcome);
513         times.setUserDataTime(TimeManager.systemAreas, areaID, timestamp);
514     }
515
516     public void setRead(long areaID) throws SQLException, AccessDeniedException, ClassNotFoundException JavaDoc, InstantiationException JavaDoc, IllegalAccessException JavaDoc {setRead(areaID, new Timestamp(System.currentTimeMillis()));}
517
518     /**
519      * Add a message.
520      */

521   public void addMessage(Message message) throws Exception JavaDoc
522     {
523         AreaGroup areaGroup = getAreaGroup(getArea(message.areaID).areaGroupID);
524         checkMyAccess(areaGroup.ID, AccessLevel.addMessage);
525         // post new msg:
526
// subject, message, area
527
long userID = manager.getUserID();
528         if (userID == -1)
529           throw new RuntimeException JavaDoc("not logged in");
530
531         Connection c = null;
532         PreparedStatement statement = null;
533         ResultSet result = null;
534
535         try
536         {
537             c = getNewConnection();
538
539             if (message.body == null)message.body = "";
540             if (message.subject == null)message.subject = "";
541
542             message.subject = message.subject.trim();
543             message.body = message.body.trim();
544
545             if (message.getParentID() != -1 && getMessage(message.getParentID()).visible == false)
546             {
547                 throw new AccessDeniedException("attempt to reply to a deleted message denied");
548                 // if parent message is hidden, this message must also be hidden
549
//visible = getMessage(message.getParentID()).visible? 1 : 0;
550
}
551
552             statement = c.prepareStatement("insert into Messages (ID, Parent, Area, Subject, User, Timecreated, Body, Words, Visible, LastChanged, LastChangedUser) values(null, ?, ?, ?, ?, NOW(), ?, ?, ?, NOW(), ?)");
553             if (message.getParentID() == -1)
554                 statement.setObject(1, null);
555             else
556                 statement.setLong(1, message.getParentID());
557             statement.setLong(2, message.getAreaID());
558             statement.setString(3, message.getSubject());
559             statement.setLong(4, userID);
560             statement.setString(5, message.getBody());
561             statement.setInt(6, Utils.nrWords(message.getBody()));
562             statement.setInt(7, 1);
563             statement.setLong(8, manager.getUserID());
564             statement.executeUpdate();
565
566             ((TimeManager)manager.getManager(TimeManager.class.getName())).setTime(TimeManager.systemAreas, message.areaID);
567         }
568         finally { closeAll(c, statement, result); }
569     }
570
571     public void changeMessage(Message message) throws Exception JavaDoc
572     {
573         Message m = getMessage(message.getId());
574
575         checkMyAccess(getAreaGroup(getArea(m.areaID).areaGroupID).getId(), AccessLevel.addMessage);
576
577         if (manager.getUserID() != message.getOwnerID())
578           throw new AccessDeniedException("attempt to edit another users messages");
579
580         Connection c = null;
581         PreparedStatement statement = null;
582         ResultSet result = null;
583
584         try
585         {
586             c = getNewConnection();
587             statement = c.prepareStatement("select count(*) from Messages where Parent = ?");
588             statement.setLong(1, message.getId());
589
590             result = statement.executeQuery();
591             result.next();
592             if (result.getInt(1) != 0)
593                 throw new AccessDeniedException("message cannot be edited, it has already been replied to");
594
595             if (message.body == null)message.body = "";
596             if (message.subject == null)message.subject = "";
597
598             message.subject = message.subject.trim();
599             message.body = message.body.trim();
600
601             statement = c.prepareStatement("update messages set Subject = ?, Body = ?, LastChanged = NOW(), LastChangedUser = ? where ID = ?");
602             statement.setString(1, message.getSubject());
603             statement.setString(2, message.getBody());
604             statement.setLong(3, manager.getUserID());
605             statement.setLong(4, message.getId());
606
607             statement.executeUpdate();
608
609             ((TimeManager)manager.getManager(TimeManager.class.getName())).setTime(TimeManager.systemAreas, message.areaID);
610         }
611         finally { closeAll(c, statement, result); }
612     }
613
614     /**
615      * Remove a message.
616      */

617   public void removeMessage(long messageID) throws SQLException, AccessDeniedException
618   {
619         Message message = getMessage(messageID);
620         if (message.ownerID != manager.getUserID())
621         {
622             AreaGroup areaGroup = getAreaGroup(getArea(message.areaID).areaGroupID);
623             checkMyAccess(areaGroup.ID, AccessLevel.removeMessage);
624         }
625
626         removeMessageImpl(messageID);
627     }
628
629     // for recursive support
630
protected void removeMessageImpl(long messageID) throws SQLException, AccessDeniedException
631     {
632         Connection c = null;
633         Statement statement = null;
634         ResultSet result = null;
635
636         LongArrayList l = new LongArrayList();
637
638         try
639         {
640             c = getNewConnection();
641             statement = c.createStatement();
642
643             result = statement.executeQuery("select ID from Messages where Parent = "+messageID);
644
645             // execute deletion of submessages later, to keep the number of connections low
646
while (result.next())
647                 l.add(result.getLong(1));
648
649             statement.executeUpdate("update Messages set Visible = 0, LastChangedUser = "+manager.getUserID()+", LastChanged = NOW() where ID = " + messageID);
650         }
651         finally { closeAll(c, statement, result); }
652
653         for (int i = 0; i < l.size(); i++)
654         {
655             removeMessageImpl(l.getLong(i));
656         }
657     }
658
659     /**
660      * Get a page.
661      */

662     public Message[] getPage(long areaID, int page, boolean getHidden) throws SQLException, AccessDeniedException
663     {
664         Connection c = null;
665         Statement statement = null;
666         ResultSet result = null;
667
668         try
669         {
670             c = getNewConnection();
671             statement = c.createStatement();
672
673             result = statement.executeQuery("select AreaGroups.ID from Areas, AreaGroups where Areas.AreaGroup = AreaGroups.ID AND Areas.ID = "+areaID);
674
675             if (!result.next())return new Message[0];
676
677             checkMyAccess(result.getLong(1), AccessLevel.readArea);
678
679             result = statement.executeQuery("select ID, Parent, User, Timecreated, LastChanged, LastChangedUser, Subject, Body, Words, Visible from Messages where Area = " + areaID + (getHidden?"": " AND Visible = 1") +" order by ID desc limit " + (page*messagesPerPage) + ", " + messagesPerPage);
680             List v = new ArrayList();
681             while (result.next())
682             {
683                 v.add(new Message(
684                     result.getLong(1),
685                     result.getLong(2),
686                     areaID,
687                     result.getLong(3),
688                     result.getTimestamp(4),
689                     result.getTimestamp(5),
690                     result.getLong(6),
691                     result.getString(7),
692                     result.getString(8),
693                     result.getLong(9),
694                     result.getInt(10) == 1));
695             }
696
697             Message r[] = new Message[v.size()];
698             v.toArray(r);
699             return r;
700         }
701         finally { closeAll(c, statement, result); }
702     }
703     public Message[] getPage(long areaID, int page) throws SQLException, AccessDeniedException { return getPage(areaID, page, false); }
704
705     /**
706      * Get all messages in an area.
707      */

708   public Message[] getMessages(long areaID, boolean getHidden) throws SQLException, AccessDeniedException
709     {
710         Connection c = null;
711         Statement statement = null;
712         ResultSet result = null;
713
714         try
715         {
716             c = getNewConnection();
717             statement = c.createStatement();
718
719             result = statement.executeQuery("select AreaGroups.ID from Areas, AreaGroups where Areas.AreaGroup = AreaGroups.ID AND Areas.ID = "+areaID);
720             if (!result.next())return new Message[0];
721
722             checkMyAccess(result.getLong(1), AccessLevel.readArea);
723
724             result = statement.executeQuery("select ID, Parent, Area, User, Timecreated, LastChanged, LastChangedUser, Subject, Body, Words, Visible from Messages where Area = " + areaID + (getHidden?"": " AND Visible = 1") +" order by ID asc");
725             List v = new ArrayList();
726             while (result.next())
727                 v.add(getMessageFromRow(result));
728
729             Message r[] = new Message[v.size()];
730             v.toArray(r);
731
732             return r;
733         }
734         finally { closeAll(c, statement, result); }
735     }
736     protected Message[] getMessages(long areaID) throws SQLException, AccessDeniedException { return getMessages(areaID, false); }
737
738     public Message getMessageFromRow(ResultSet result) throws SQLException
739     {
740         return new Message(
741                     result.getLong(1),
742                     result.getObject(2) == null? -1: result.getLong(2),
743                     result.getLong(3),
744                     result.getLong(4),
745                     result.getTimestamp(5),
746                     result.getTimestamp(6),
747                     result.getLong(7),
748                     result.getString(8),
749                     result.getString(9),
750                     result.getLong(10),
751                     result.getInt(11) == 1);
752     }
753
754     /**
755      * Get message data.
756      */

757     public Message getMessage(long messageID) throws SQLException, AccessDeniedException
758     {
759         Connection c = null;
760         Statement statement = null;
761         ResultSet result = null;
762
763         long areaID = -1;
764         try
765         {
766             c = getNewConnection();
767             statement = c.createStatement();
768
769             result = statement.executeQuery("select AreaGroups.ID from Messages, Areas, AreaGroups where Messages.Area = Areas.ID AND Areas.AreaGroup = AreaGroups.ID AND Messages.ID = "+messageID);
770             if (!result.next())return null;
771
772             areaID = result.getLong(1);
773
774         }
775         finally { closeAll(c, statement, result); }
776
777         checkMyAccess(areaID, AccessLevel.readArea);
778
779         try
780         {
781             c = getNewConnection();
782             statement = c.createStatement();
783             result = statement.executeQuery("select ID, Parent, Area, User, Timecreated, LastChanged, LastChangedUser, Subject, Body, Words, Visible from Messages where ID = "+messageID);
784             Message r = null;
785             if (result.next())
786                 r = getMessageFromRow(result);
787
788             return r;
789         }
790         finally { closeAll(c, statement, result); }
791     }
792
793     /**
794      * Get an area in the form of a tree.
795      */

796     public ParentIDItemTreeNode getMessagesTree(long areaID) throws SQLException, AccessDeniedException
797     {
798         checkMyAccess(getArea(areaID).areaGroupID, AccessLevel.readArea);
799
800         MessageCache cache;
801
802         synchronized(messageCaches)
803         {
804             cache = (MessageCache)messageCaches.get(areaID);
805
806             if (cache == null)
807             {
808                 //node = net.killingar.forum.actions.Utils.buildTree(getMessages(areaID));
809
cache = new MessageCache(areaID, this);
810
811         messageCaches.put(areaID, cache);
812             }
813         }
814
815         return cache.getMessagesTree();
816
817         //return net.killingar.forum.actions.Utils.buildTree(getMessages(areaID, true));
818
}
819
820     public ParentIDItemTreeNode getMessageSubtree(long areaID, long messageID) throws SQLException, AccessDeniedException
821     {
822         checkMyAccess(getArea(areaID).areaGroupID, AccessLevel.readArea);
823
824         MessageCache cache;
825
826         synchronized(messageCaches)
827         {
828             cache = (MessageCache)messageCaches.get(areaID);
829
830             if (cache == null)
831             {
832                 //node = net.killingar.forum.actions.Utils.buildTree(getMessages(areaID));
833
cache = new MessageCache(areaID, this);
834
835         messageCaches.put(areaID, cache);
836             }
837         }
838
839         return cache.getParentIDItemTreeNode(messageID);
840     }
841
842     /**
843      * Get number of messages.
844      */

845     public long getNoMessages() throws SQLException
846     {
847         Connection c = null;
848         Statement statement = null;
849         ResultSet result = null;
850
851         try
852         {
853             c = getNewConnection();
854             statement = c.createStatement();
855
856             result = statement.executeQuery("select count(*) from Messages where Visible != 0");
857             long r = Long.MAX_VALUE;
858             if (result.next())
859                 r = result.getLong(1);
860             return r;
861         }
862         finally { closeAll(c, statement, result); }
863     }
864
865     /**
866      * Get number of messages by a user.
867      */

868     public long getNoMessagesByUser(long userID) throws SQLException
869     {
870         Connection c = null;
871         Statement statement = null;
872         ResultSet result = null;
873
874         try
875         {
876             c = getNewConnection();
877             statement = c.createStatement();
878
879             result = statement.executeQuery("select count(*) from Messages where Visible != 0 AND User = "+userID);
880             long r = Long.MAX_VALUE;
881             if (result.next())
882                 r = result.getLong(1);
883             return r;
884         }
885         finally { closeAll(c, statement, result); }
886     }
887
888     /**
889      * Get number of words by a user.
890      */

891     public long getNoWordsByUser(long userID) throws SQLException
892     {
893         Connection c = null;
894         Statement statement = null;
895         ResultSet result = null;
896
897         try
898         {
899             c = getNewConnection();
900             statement = c.createStatement();
901
902             result = statement.executeQuery("select sum(Words) from Messages where Visible != 0 AND User = "+userID);
903             long r = Long.MAX_VALUE;
904             if (result.next())
905                 r = result.getLong(1);
906             return r;
907         }
908         finally { closeAll(c, statement, result); }
909     }
910
911     /**
912      * Get number of bytes by a user.
913      */

914     public long getNoBytesByUser(long userID) throws SQLException
915     {
916         Connection c = null;
917         Statement statement = null;
918         ResultSet result = null;
919
920         try
921         {
922             c = getNewConnection();
923             statement = c.createStatement();
924
925             result = statement.executeQuery("select sum(length(Body)) from Messages where Visible != 0 AND User = "+userID);
926             long r = Long.MAX_VALUE;
927             if (result.next())
928                 r = result.getLong(1);
929             return r;
930         }
931         finally { closeAll(c, statement, result); }
932     }
933
934     /**
935      * Returns true if the user has the specified access levels, also checks global access.
936      */

937     public boolean hasAccess(long userID, long areaGroupID, long accessLevel) throws SQLException, AccessDeniedException
938     {
939         if ((getUserAccess(userID, areaGroupID) & accessLevel) == accessLevel)
940             return true;
941         return manager.hasAccess(manager.getUserID(), accessLevel);
942     }
943
944     /**
945      * Throws an AccessDeniedException if the access level isn't met.
946      */

947     public void checkMyAccess(long areaGroupID, long accessLevel) throws SQLException, AccessDeniedException
948     {
949         if (
950             !hasAccess(manager.getUserID(), areaGroupID, accessLevel))
951                 throw new AccessDeniedException("access denied ("+AccessLevel.toString(accessLevel)+")");
952     }
953
954     /**
955      * Get access level of a user on an area group.
956      */

957     public long getUserAccess(long userID, long areaGroupID) throws SQLException, AccessDeniedException
958     {
959         /*synchronized (getClass())
960         {
961             // check cache
962             long key1 = areaGroupID;
963             long key2 = userID;
964
965             HashMap areaGroupAccessLevels = (HashMap)accessLevels.get(key1);
966
967             if (areaGroupAccessLevels != null)
968             {
969                 if (areaGroupAccessLevels.containsKey(key2))
970                     return areaGroupAccessLevels.get(key2);
971             }
972
973             // update cache
974
975             // simple check if user owns area
976             AreaGroup areaGroup = getAreaGroup(areaGroupID);
977
978             if (areaGroup != null && areaGroup.ownerID == userID)
979             {
980                 if (manager.getUserID() == userID)
981                 {
982                     if (areaGroupAccessLevels == null)
983                     {
984                         areaGroupAccessLevels = new HashMap();
985                         accessLevels.put(key1, areaGroupAccessLevels);
986                     }
987                     areaGroupAccessLevels.put(key2, AccessLevel.everything);
988                 }
989                 return AccessLevel.everything;
990             }*/

991
992             if (manager.hasAccess(manager.getUserID(), AccessLevel.everything))
993                 return AccessLevel.everything;
994
995             {
996                 AreaGroup ag = getAreaGroup(areaGroupID);
997                 if (ag != null && ag.getOwnerID() == userID)
998                     return AccessLevel.everything;
999             }
1000
1001            // complex check
1002
String JavaDoc groupsString;
1003            {
1004                Group groups[] = manager.getGroupsOfUser(userID);
1005                if (groups.length != 0)
1006                {
1007                    StringBuffer JavaDoc s = new StringBuffer JavaDoc("(");
1008                    for (int i = 0; i < groups.length; i++)
1009                    {
1010                        if (i != 0)
1011                            s.append(" OR ");
1012                        s.append(" Groups.ID = ");
1013                        s.append(groups[i].ID);
1014                    }
1015
1016                    s.append(") AND ");
1017                    groupsString = s.toString();
1018                }
1019
1020                else
1021                    groupsString = "";
1022            }
1023
1024            Connection c = null;
1025            Statement statement = null;
1026            ResultSet result = null;
1027
1028            try
1029            {
1030                c = getNewConnection();
1031                statement = c.createStatement();
1032
1033                result = statement.executeQuery("select AreaGroupAccess.Access from AreaGroupAccess, Groups where "+groupsString+" AreaGroupAccess.UserGroup = Groups.ID AND AreaGroup = "+areaGroupID);
1034                long a = 0;
1035                while(true)
1036                {
1037                    if (!result.next())break;
1038                    a |= result.getLong(1);
1039                }
1040
1041                //a |= manager.getUserAccess(userID);
1042

1043                /*if (areaGroupAccessLevels == null)
1044                {
1045                    areaGroupAccessLevels = new HashMap();
1046                    accessLevels.put(key1, areaGroupAccessLevels);
1047                }
1048                areaGroupAccessLevels.put(key2, a);*/

1049
1050                return a;
1051            }
1052            finally { closeAll(c, statement, result); }
1053        //}
1054
}
1055
1056    /**
1057     * Get the access on a group in the list of groups with access to the specified area group.
1058     */

1059    public long getAreaGroupAccess(long userGroupID, long areaGroupID) throws SQLException
1060    {
1061        Connection c = null;
1062        Statement statement = null;
1063        ResultSet result = null;
1064
1065        try
1066        {
1067            c = getNewConnection();
1068            statement = c.createStatement();
1069
1070            result = statement.executeQuery("select Access from AreaGroupAccess where UserGroup = "+userGroupID+" AND AreaGroup = "+areaGroupID);
1071            long r = AccessLevel.none;
1072            if (result.next())
1073                r = result.getLong(1);
1074            return r;
1075        }
1076        finally { closeAll(c, statement, result); }
1077    }
1078
1079    /**
1080     * Change access on a group in the list of groups with access to the specified area group.
1081     */

1082    public void changeAreaGroupAccess(long userGroupID, long areaGroupID, long accessLevel) throws SQLException, AccessDeniedException
1083    {
1084        AreaGroup areaGroup = getAreaGroup(areaGroupID);
1085        // check access
1086
if (areaGroup.ownerID != manager.getUserID())
1087            checkMyAccess(areaGroupID, AccessLevel.changeAreaGroup);
1088
1089        Connection c = null;
1090        Statement statement = null;
1091        ResultSet result = null;
1092
1093        try
1094        {
1095            c = getNewConnection();
1096            statement = c.createStatement();
1097
1098            if (accessLevel == AccessLevel.none)
1099                statement.executeUpdate("delete from AreaGroupAccess where UserGroup = "+userGroupID+" AND AreaGroup = "+areaGroupID);
1100            else
1101            {
1102                if (getAreaGroupAccess(userGroupID, areaGroupID) == AccessLevel.none)
1103                    statement.executeUpdate("insert into AreaGroupAccess (UserGroup, AreaGroup, Access) values ("+userGroupID+", "+areaGroupID+", "+accessLevel+")");
1104                else
1105                    statement.executeUpdate("update AreaGroupAccess set Access = "+accessLevel+", LastChanged = NOW(), LastChangedUser = "+manager.getUserID()+" where UserGroup = "+userGroupID+" AND AreaGroup = "+areaGroupID);
1106            }
1107        }
1108        finally { closeAll(c, statement, result); }
1109    }
1110
1111    /**
1112     * Search for messages with the specific string in the specified area.
1113     */

1114    public Message[] search(String JavaDoc search, long areaID, boolean searchSubject, boolean searchBody) throws SQLException, AccessDeniedException
1115    {
1116        if (!searchSubject && !searchBody)return new Message[0];
1117
1118        checkMyAccess(getArea(areaID).areaGroupID, AccessLevel.readArea);
1119        String JavaDoc
1120            where,
1121            against = " against ('"+Utils.disableSQL(search)+"')";
1122        if (searchSubject)
1123        {
1124            if (searchBody)
1125                where = "match(Subject) "+against+" or match(Body) "+against;
1126            else
1127                where = "match(Subject) "+against;
1128        }
1129        else
1130            where = "match(Body) "+against;
1131
1132        Connection c = null;
1133        Statement statement = null;
1134        ResultSet result = null;
1135
1136        try
1137        {
1138            c = getNewConnection();
1139            statement = c.createStatement();
1140
1141            result = statement.executeQuery("select ID, Parent, Area, User, Timecreated, LastChanged, LastChangedUser, Subject, Body, Words, Visible from Messages where Area = "+areaID+" AND ("+where+")");
1142            List list = new ArrayList();
1143            while(result.next())
1144                list.add(getMessageFromRow(result));
1145
1146            Message r[] = new Message[list.size()];
1147            list.toArray(r);
1148            return r;
1149        }
1150        finally { closeAll(c, statement, result); }
1151    }
1152}
Popular Tags