EMMA Coverage Report (generated Wed Feb 13 07:49:24 ICT 2008)
[all classes][net.sourceforge.hiveboard.business]

COVERAGE SUMMARY FOR SOURCE FILE [WhiteBoardManagerImpl.java]

nameclass, %method, %block, %line, %
WhiteBoardManagerImpl.java100% (7/7)98%  (45/46)88%  (1244/1419)93%  (297.9/319)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class WhiteBoardManagerImpl100% (1/1)97%  (33/34)86%  (1112/1287)93%  (279.9/301)
getAllAccounts (int): Account [] 0%   (0/1)0%   (0/11)0%   (0/2)
getBoard (int): Board 100% (1/1)30%  (10/33)60%  (3/5)
getRealAccount (int): Account 100% (1/1)48%  (10/21)75%  (3/4)
getSnapshot (int, int): byte [] 100% (1/1)63%  (29/46)84%  (6.8/8)
leave (int, int): void 100% (1/1)67%  (10/15)75%  (3/4)
addParticipant (int, int, int): void 100% (1/1)76%  (53/70)88%  (12.4/14)
requestToken (int, int): void 100% (1/1)81%  (21/26)96%  (5.8/6)
changeAccountPassword (int, int, String): void 100% (1/1)84%  (31/37)88%  (8.8/10)
changePassword (int, String): void 100% (1/1)84%  (31/37)88%  (8.8/10)
userConnected (Principal): void 100% (1/1)86%  (36/42)88%  (12.4/14)
draw (int, int, byte []): void 100% (1/1)86%  (32/37)96%  (6.8/7)
modifyBoard (int, Board): void 100% (1/1)87%  (76/87)93%  (17.8/19)
comment (int, int, String): void 100% (1/1)88%  (35/40)97%  (7.8/8)
takeSnapshot (int, int): void 100% (1/1)88%  (35/40)97%  (7.8/8)
giveToken (int, int, int): void 100% (1/1)89%  (40/45)95%  (11.4/12)
closeBoard (int, int): void 100% (1/1)89%  (41/46)98%  (10.8/11)
userDisconnected (Principal, boolean): void 100% (1/1)90%  (56/62)90%  (15.4/17)
leaveBoard (int, Board): boolean 100% (1/1)91%  (49/54)95%  (12.4/13)
getSnapshots (int, int): List 100% (1/1)92%  (58/63)98%  (13.8/14)
getBoardComments (int, int, Date, Date): List 100% (1/1)92%  (60/65)98%  (12.8/13)
join (int, int): void 100% (1/1)93%  (64/69)96%  (15.4/16)
removeParticipant (int, int, int): void 100% (1/1)93%  (66/71)96%  (16.4/17)
removeAccount (int, int): void 100% (1/1)97%  (30/31)89%  (8/9)
WhiteBoardManagerImpl (Log, Channel, AccountRepository, BoardRepository, Asyn... 100% (1/1)100% (40/40)100% (13/13)
access$000 (WhiteBoardManagerImpl): AccountDAO 100% (1/1)100% (3/3)100% (1/1)
access$100 (WhiteBoardManagerImpl): BoardDAO 100% (1/1)100% (3/3)100% (1/1)
createAccount (int, Account): void 100% (1/1)100% (44/44)100% (14/14)
createBoard (int, Board): void 100% (1/1)100% (42/42)100% (11/11)
fireEvent (Event): void 100% (1/1)100% (5/5)100% (2/2)
getAccount (String): Account 100% (1/1)100% (6/6)100% (1/1)
getAccount (int): Account 100% (1/1)100% (13/13)100% (4/4)
getServerSettings (int): ServerSettings 100% (1/1)100% (3/3)100% (1/1)
login (int): List 100% (1/1)100% (65/65)100% (8/8)
modifyAccount (int, Account): void 100% (1/1)100% (15/15)100% (5/5)
     
class WhiteBoardManagerImpl$1100% (1/1)100% (2/2)100% (21/21)100% (3/3)
WhiteBoardManagerImpl$1 (WhiteBoardManagerImpl, int, String): void 100% (1/1)100% (12/12)100% (1/1)
run (): void 100% (1/1)100% (9/9)100% (2/2)
     
class WhiteBoardManagerImpl$2100% (1/1)100% (2/2)100% (32/32)100% (3/3)
WhiteBoardManagerImpl$2 (WhiteBoardManagerImpl, int, int, String, Event): void 100% (1/1)100% (18/18)100% (1/1)
run (): void 100% (1/1)100% (14/14)100% (2/2)
     
class WhiteBoardManagerImpl$3100% (1/1)100% (2/2)100% (21/21)100% (3/3)
WhiteBoardManagerImpl$3 (WhiteBoardManagerImpl, int, int): void 100% (1/1)100% (12/12)100% (1/1)
run (): void 100% (1/1)100% (9/9)100% (2/2)
     
class WhiteBoardManagerImpl$4100% (1/1)100% (2/2)100% (21/21)100% (3/3)
WhiteBoardManagerImpl$4 (WhiteBoardManagerImpl, int, int): void 100% (1/1)100% (12/12)100% (1/1)
run (): void 100% (1/1)100% (9/9)100% (2/2)
     
class WhiteBoardManagerImpl$5100% (1/1)100% (2/2)100% (21/21)100% (3/3)
WhiteBoardManagerImpl$5 (WhiteBoardManagerImpl, int, String): void 100% (1/1)100% (12/12)100% (1/1)
run (): void 100% (1/1)100% (9/9)100% (2/2)
     
class WhiteBoardManagerImpl$6100% (1/1)100% (2/2)100% (16/16)100% (3/3)
WhiteBoardManagerImpl$6 (WhiteBoardManagerImpl, Account): void 100% (1/1)100% (9/9)100% (1/1)
run (): void 100% (1/1)100% (7/7)100% (2/2)

1//  Copyright 2004-2007 Jean-Francois Poilpret
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14 
15package net.sourceforge.hiveboard.business;
16 
17import java.security.Principal;
18import java.util.ArrayList;
19import java.util.Date;
20import java.util.HashSet;
21import java.util.List;
22 
23import org.apache.commons.logging.Log;
24 
25import net.sourceforge.hiveboard.Account;
26import net.sourceforge.hiveboard.Board;
27import net.sourceforge.hiveboard.DoesNotExistException;
28import net.sourceforge.hiveboard.Event;
29import net.sourceforge.hiveboard.ServerSettings;
30import net.sourceforge.hiveboard.Snapshot;
31import net.sourceforge.hiveboard.dao.AccountDAO;
32import net.sourceforge.hiveboard.dao.BoardDAO;
33import net.sourceforge.hiveboard.dao.CommentDTO;
34import net.sourceforge.hiveboard.dao.SnapshotDTO;
35import net.sourceforge.hiveboard.drawing.DrawingAction;
36import net.sourceforge.hiveboard.security.HiveBoardPrincipal;
37import net.sourceforge.hiveevents.Channel;
38import net.sourceforge.hivelock.UserEventListener;
39import net.sourceforge.hiveutils.service.AsynchronousTaskPerformer;
40import net.sourceforge.hiveutils.service.ObjectTools;
41import net.sourceforge.hiveutils.util.PasswordEncryption;
42import static net.sourceforge.hiveboard.util.TokenStrategyFactory.getStrategy;
43 
44// CSOFF: ClassFanOutComplexityCheck
45/**
46 * Implementation of the Central WhiteBoardManager service.
47 *
48 * @author Jean-Francois Poilpret
49 */
50public class        WhiteBoardManagerImpl
51        implements        WhiteBoardManager, UserEventListener
52{
53        // CSOFF: ParameterNumberCheck
54        public WhiteBoardManagerImpl(        Log                                                        logger, 
55                                                                        Channel<Event>                                channel,
56                                                                        AccountRepository                        accounts,
57                                                                        BoardRepository                                boards,
58                                                                        AsynchronousTaskPerformer        performer,
59                                                                        AccountDAO                                        accountDAO,
60                                                                        BoardDAO                                        boardDAO,
61                                                                        ObjectTools                                        objectTools,
62                                                                        int                                                        maxImageSize)
63        {
64                _logger = logger;
65                _channel = channel;
66                _accounts = accounts;
67                _boards = boards;
68                _performer = performer;
69                _boardDAO = boardDAO;
70                _accountDAO = accountDAO;
71                _objectTools = objectTools;
72                _maxImageSize = maxImageSize;
73                _settings.setMaxBoardSize(_maxImageSize);
74        }
75        // CSON: ParameterNumberCheck
76 
77        public void        userConnected(Principal user)
78        {
79                HiveBoardPrincipal principal = (HiveBoardPrincipal) user;
80                int who = principal.getId();
81                Account account = getRealAccount(who);
82                if (account == null)
83                {
84                        return;
85                }
86                boolean fire = false;
87                synchronized (account)
88                {
89                        if (!account.isConnected())
90                        {
91                                account.setConnected(true);
92                                fire = true;
93                        }
94                }
95                // Notify all connected users
96                if (fire)
97                {
98                        fireEvent(EventFactory.createLogin(who));
99                }
100        }
101 
102        public void        userDisconnected(Principal user, boolean forced)
103        {
104                HiveBoardPrincipal principal = (HiveBoardPrincipal) user;
105                int who = principal.getId();
106                Account account = getRealAccount(who);
107                if (account == null)
108                {
109                        return;
110                }
111                boolean fire = false;
112                synchronized (account)
113                {
114                        if (account.isConnected())
115                        {
116                                account.setConnected(false);
117                                fire = true;
118                        }
119                }
120                if (fire)
121                {
122                        // Notify all connected users
123                        fireEvent(EventFactory.createLogout(who));
124                        // Remove from all boards he is present
125                        Board[] boards = _boards.getBoards(false);
126                        for (int i = 0; i < boards.length; i++)
127                        {
128                                leaveBoard(who, boards[i]);
129                        }
130                }
131        }
132 
133        public Account        getAccount(int id)
134        {
135                Account account = _accounts.getAccount(id, true);
136                if (account != null)
137                {
138                        account.setPassword(null);
139                }
140                return account;
141        }
142 
143        public ServerSettings        getServerSettings(int source)
144        {
145                return _settings;
146        }
147 
148        // NB: this method returns the clear password!!!
149        // It must be used exclusively for authentication purposes        
150        public Account        getAccount(String user)
151        {
152                return _accounts.getAccount(user, true);
153        }
154        
155        public List<Event>        login(int source)
156        {
157                // Get all boards/accounts and push it to listener immediately
158                Account[] accounts = _accounts.getAccounts(true);
159                Board[] boards = _boards.getBoards(true);
160                List<Event> events = new ArrayList<Event>(accounts.length + boards.length);
161                for (Account account: accounts)
162                {
163                        events.add(EventFactory.createCreateAccount(account));
164                }
165                for (Board board: boards)
166                {
167                        events.add(EventFactory.createCreateBoard(board.getInitiator(), board));
168                }
169                return events;
170        }
171 
172        public void        changePassword(final int source, String password)
173        {
174                Account account = getRealAccount(source);
175                if (account == null)
176                {
177                        return;
178                }
179                // Check password not null
180                ValidityChecks.checkPassword(password);
181                final String cryptedPassword = PasswordEncryption.encrypt(password);
182                synchronized (account)
183                {
184                        account.setPassword(cryptedPassword);
185                }
186                // Save to DB
187                _performer.addTask(new Runnable()
188                {
189                        public void        run()
190                        {
191                                _accountDAO.updatePassword(source, cryptedPassword);
192                        }
193                });
194        }
195        
196        public void        join(int source, int where)
197        {
198                Board board = getBoard(where);
199                boolean fireJoin = false;
200                int writer = -1;
201                synchronized (board)
202                {
203                        SecurityChecks.checkParticipant(
204                                source, board, "Must be board participant to join");
205                        if (board.getPresents().add(source))
206                        {
207                                fireJoin = true;
208                                writer = getStrategy(board).updateWriter(board);
209                        }
210                }
211                if (fireJoin)
212                {
213                        // Get current image pixmap
214                        ImageInfo image = _boards.getImageHolder(where).getImage();
215                        // Notify new joining user
216                        fireEvent(EventFactory.createJoinBoard(        source, 
217                                                                                                        where, 
218                                                                                                        image.getImage(),
219                                                                                                        image.getDrawingAction()));
220                        // Notify all connected users
221                        fireEvent(EventFactory.createJoinBoard(source, where, null, null));
222                        if (writer >= 0)
223                        {
224                                fireEvent(EventFactory.createGiveToken(writer, where));
225                        }
226                }
227        }
228        
229        public void        comment(final int source, final int where, final String comment)
230        {
231                Board board = getBoard(where);
232                synchronized (board)
233                {
234                        SecurityChecks.checkPresent(
235                                source, board, "Must be board present participant to send comment");
236                }
237 
238                // Notify all connected users
239                final Event event = EventFactory.createSendComment(source, where, comment);
240                fireEvent(event);
241                // Add comment to DB
242                _performer.addTask(new Runnable()
243                {
244                        public void        run()
245                        {
246                                _boardDAO.insertComment(where, source, comment, event.getWhen());
247                        }
248                });
249        }
250        
251        public void        draw(int source, int where, byte[] drawing)
252        {
253                Board board = getBoard(where);
254                synchronized (board)
255                {
256                        SecurityChecks.checkWriter(source, board, "Must be board current writer to draw");
257                }
258                // Add drawing to DB
259                _boards.getImageHolder(where).addDrawingAction(
260                                                                (DrawingAction) _objectTools.deserialize(drawing));
261                fireEvent(EventFactory.createSendDrawing(source, where, drawing));
262        }
263        
264        public void        requestToken(int source, int where)
265        {
266                Board board = getBoard(where);
267                synchronized (board)
268                {
269                        SecurityChecks.checkPresent(source, 
270                                                                                board,
271                                                                                "Must be board present participant to request write");
272                }
273                fireEvent(EventFactory.createRequestToken(source, where));
274        }
275        
276        public void        giveToken(int source, int where, int target)
277        {
278                Board board = getBoard(where);
279                boolean fire = false;
280                synchronized (board)
281                {
282                        SecurityChecks.checkError(getStrategy(board).canGiveToken(board, source));
283                        SecurityChecks.checkPresent(
284                                target, board, "Cannot set writer to non present person");
285                        if (board.getWriter() != target)
286                        {
287                                fire = true;
288                                board.setWriter(target);
289                        }
290                }
291                if (fire)
292                {
293                        // Notify all connected users
294                        fireEvent(EventFactory.createGiveToken(target, where));
295                }
296        }
297        
298        public void        takeSnapshot(int source, int where)
299        {
300                // Check source is initiator of where
301                Board board = getBoard(where);
302                synchronized (board)
303                {
304                        SecurityChecks.checkInitiator(
305                                source, board, "Must be board initiator to take snapshot");
306                }
307                // Get current snapshot
308                // Note: we don't include current hilites
309                byte[] snapshot = _boards.getImageHolder(where).getImage().getImage();
310                snapshot = _objectTools.compress(snapshot);
311                // Write it to DB
312                _boardDAO.insertSnapshot(where, false, snapshot);
313        }
314        
315        public void        leave(int source, int where)
316        {
317                Board board = getBoard(where);
318                if (!leaveBoard(source, board))
319                {
320                        throw new SecurityException("Must be board present participant to leave");
321                }
322        }
323        
324        public void        addParticipant(int source, final int where, final int target)
325        {
326                Board board = getBoard(where);
327                boolean fire = false;
328                // Check "target" exists as an account first
329                if (_accounts.getAccount(target, false) == null)
330                {
331                        throw new DoesNotExistException("Unknown participant id " + target);
332                }
333                synchronized (board)
334                {
335                        SecurityChecks.checkInitiator(
336                                source, board, "Must be board initiator to add participant");
337                        if (board.getParticipants().add(target))
338                        {
339                                fire = true;
340                        }
341                }
342                if (fire)
343                {
344                        // Notify all connected users
345                        fireEvent(EventFactory.createAddParticipant(target, where));
346                        fireEvent(EventFactory.createAddParticipant(target, board));
347                        // Save to DB
348                        _performer.addTask(new Runnable()
349                        {
350                                public void        run()
351                                {
352                                        _boardDAO.insertParticipant(where, target);
353                                }
354                        });
355                }
356        }
357        
358        public void        removeParticipant(int source, final int where, final int who)
359        {
360                Board board = getBoard(where);
361                boolean fire = false;
362                int writer = -1;
363                synchronized (board)
364                {
365                        SecurityChecks.checkInitiator(
366                                source, board, "Must be board initiator to remove participant");
367                        SecurityChecks.checkNotInitiator(
368                                who, board, "Initiator cannot remove oneself from board");
369                        if (board.getParticipants().remove(who))
370                        {
371                                fire = true;
372                                // Must also remove from present participant if necessary
373                                board.getPresents().remove(who);
374                                // Must also set new writer if removed participant was writer
375                                writer = getStrategy(board).updateWriter(board);
376                        }
377                }
378                if (fire)
379                {
380                        // Notify all connected users
381                        fireEvent(EventFactory.createDelParticipant(who, where));
382                        if (writer >= 0)
383                        {
384                                fireEvent(EventFactory.createGiveToken(writer, where));
385                        }
386                        // Save to DB
387                        _performer.addTask(new Runnable()
388                        {
389                                public void        run()
390                                {
391                                        _boardDAO.deleteParticipant(where, who);
392                                }
393                        });
394                }
395        }
396        
397        public void        createBoard(int source, Board board)
398        {
399                // Initialize various fields
400                board.setId(0);
401                board.setDiscriminator(0);
402                board.setInitiator(source);
403                board.setWriter(0);
404                board.setCreationDate(new Date());
405                board.setPresents(new HashSet<Integer>());
406 
407                // Perform various checks
408                ValidityChecks.checkBoard(board, _maxImageSize, _accounts);
409 
410                // Insert into DB
411                _boardDAO.insertBoard(board);
412 
413                // Add to board repository
414                _boards.addBoard(board);
415                
416                // Notify all connected users
417                fireEvent(EventFactory.createCreateBoard(source, board));
418        }
419        
420        public void        modifyBoard(int source, Board board)
421        {
422                // Check board exists
423                Board oldBoard = getBoard(board.getId());
424                synchronized (oldBoard)
425                {
426                        // Check source is initiator
427                        SecurityChecks.checkInitiator(
428                                source, oldBoard, "Must be board initiator to modify board");
429                }
430                // Prevent size change (forbidden as of 0.3.0)
431                board.setWidth(oldBoard.getWidth());
432                board.setHeight(oldBoard.getHeight());
433                // Prevent some changes
434                board.setInitiator(oldBoard.getInitiator());
435                board.setWriter(oldBoard.getWriter());
436                board.setCreationDate(oldBoard.getCreationDate());
437                // Make sure current present accounts are all participants
438                board.setPresents(new HashSet<Integer>(oldBoard.getPresents()));
439                board.getPresents().retainAll(board.getParticipants());
440 
441                // Perform various checks
442                ValidityChecks.checkBoard(board, _maxImageSize, _accounts);
443                
444                // Must also set new writer if removed participant was writer
445                int writer = getStrategy(board).updateWriter(board);
446 
447                // Update DB
448                _boardDAO.updateBoard(board);
449 
450                // Update board in memory
451                _boards.changeBoard(board);
452                
453                // Notify all connected users
454                fireEvent(EventFactory.createModifyBoard(source, board));
455                if (writer >= 0)
456                {
457                        fireEvent(EventFactory.createGiveToken(writer, board.getId()));
458                }
459        }
460        
461        public void        closeBoard(int source, int board)
462        {
463                // Check board exists
464                Board oldBoard = getBoard(board);
465                int discriminator;
466                synchronized (oldBoard)
467                {
468                        // Check source is initiator
469                        SecurityChecks.checkInitiator(
470                                source, oldBoard, "Must be board initiator to close board");
471                        // Check board has no present person
472                        SecurityChecks.checkEmptyBoard(
473                                oldBoard, "Cannot close board that still has present participants");
474                        // Remove from _boards
475                        discriminator = _boards.removeBoard(board);
476                }
477                // Set Close Date and update DB
478                oldBoard.setClosingDate(new Date());
479                oldBoard.setDiscriminator(discriminator);
480                _boardDAO.updateBoard(oldBoard);
481 
482                // Notify all connected users
483                fireEvent(EventFactory.createDestroyBoard(source, board));
484        }
485 
486        public Account[]        getAllAccounts(int source)
487        {
488                List<Account> accounts = _accountDAO.selectAllAccounts();
489                return accounts.toArray(new Account[accounts.size()]);
490        }
491        
492        public void                        createAccount(int source, Account account)
493        {
494                // Check some fields
495                ValidityChecks.checkAccount(account);
496                ValidityChecks.checkPassword(account.getPassword());
497 
498                // Initialize some fields
499                account.setId(0);
500                account.setDiscriminator(0);
501                account.setPassword(PasswordEncryption.encrypt(account.getPassword()));
502                account.setValid(true);
503                account.setConnected(false);
504                account.setVersion(1);
505 
506                // Create in DB
507                _accountDAO.insertAccount(account);
508 
509                // Create in memory
510                _accounts.addAccount(account);
511                
512                // Notify all connected users
513                Account accountClone = account.copy();
514                accountClone.setPassword(null);
515                fireEvent(EventFactory.createCreateAccount(accountClone));
516        }
517        
518        public void                        modifyAccount(int source, Account account)
519        {
520                // Check some fields
521                ValidityChecks.checkAccount(account);
522 
523                // Modify in DB
524                // NB: cannot be deferred because of potential risk of duplicate visa
525                _accountDAO.updateAccount(account);
526 
527                // Modify in memory
528                _accounts.changeAccount(account);
529                
530                // Notify all connected users
531                fireEvent(EventFactory.createModifyAccount(account));
532        }
533        
534        public void                        changeAccountPassword(int source, final int id, String password)
535        {
536                Account account = getRealAccount(id);
537                if (account == null)
538                {
539                        return;
540                }
541                // Check password not null
542                ValidityChecks.checkPassword(password);
543                final String cryptedPassword = PasswordEncryption.encrypt(password);
544                synchronized (account)
545                {
546                        account.setPassword(cryptedPassword);
547                }
548                // Save to DB
549                _performer.addTask(new Runnable()
550                {
551                        public void        run()
552                        {
553                                _accountDAO.updatePassword(id, cryptedPassword);
554                        }
555                });
556        }
557        
558        public void                        removeAccount(int source, int idAccount)
559        {
560                final Account account = getRealAccount(idAccount);
561                if (account == null)
562                {
563                        return;
564                }
565                // Remove in memory
566                int discriminator = _accounts.removeAccount(idAccount);
567 
568                account.setValid(false);
569                account.setDiscriminator(discriminator);
570 
571                // Save to DB
572                _performer.addTask(new Runnable()
573                {
574                        public void        run()
575                        {
576                                _accountDAO.updateAccount(account);
577                        }
578                });
579 
580                // Notify all connected users
581                fireEvent(EventFactory.createDestroyAccount(idAccount));
582        }
583        
584        public List<Event>        getBoardComments(int source, int where, Date after, Date until)
585        {
586                Board board = getBoard(where);
587                synchronized (board)
588                {
589                        SecurityChecks.checkPresent(
590                                source, board, "Must be board present participant to get past comments");
591                }
592 
593                // Force writing of all comments to DB
594                _performer.executeNowAndWait();
595 
596                //#### Potential async problem here: a new comment may arrive just before
597                // next line is executed: it will not appear on the client (or maybe
598                // just flickering). I wonder if there is one way to solve this?
599                List<CommentDTO> comments = _boardDAO.selectComments(where, after, until);
600                List<Event> events = new ArrayList<Event>(comments.size());
601                for (CommentDTO comment: comments)
602                {
603                        Event event = EventFactory.createSendComment(        comment.getAuthor(),
604                                                                                                                        comment.getBoard(),
605                                                                                                                        comment.getComment());
606                        event.setWhen(comment.getDate());
607                        events.add(event);
608                }
609                return events;
610        }
611 
612        public List<Snapshot>        getSnapshots(int source, int where)
613        {
614                Board board = getBoard(where);
615                synchronized (board)
616                {
617                        SecurityChecks.checkParticipant(
618                                source, board, "Must be board participant to get snapshots list");
619                }
620                
621                List<SnapshotDTO> snaps = _boardDAO.selectSnapshots(where);
622                List<Snapshot> snapshots = new ArrayList<Snapshot>(snaps.size());
623                for (SnapshotDTO snap: snaps)
624                {
625                        Snapshot snapshot = new Snapshot();
626                        snapshot.setId(snap.getId());
627                        snapshot.setBoard(where);
628                        snapshot.setDate(snap.getDate());
629                        snapshots.add(snapshot);
630                }
631                return snapshots;
632        }
633 
634        public byte[]                getSnapshot(int source, int idSnapshot)
635        {
636                // Get Snapshot info for this id
637                SnapshotDTO snapshot = _boardDAO.selectSnapshot(idSnapshot);
638                if (snapshot == null)
639                {
640                        throw new DoesNotExistException("Unknown snapshot id " + idSnapshot);
641                }
642 
643                // Find Board for this snapshot
644                Board board = getBoard(snapshot.getBoard());
645                // Check source is participant to board
646                synchronized (board)
647                {
648                        SecurityChecks.checkParticipant(
649                                source, board, "Must be board participant to get snapshot");
650                }
651                // Get snapshot content
652                return _objectTools.uncompress(snapshot.getContent());
653        }
654 
655        protected void        fireEvent(Event event)
656        {
657                _channel.push(event);
658        }
659 
660        private boolean        leaveBoard(int who, Board board)
661        {
662                int where = board.getId();
663                int writer = -1;
664                synchronized (board)
665                {
666                        if (!board.getPresents().remove(who))
667                        {
668                                return false;
669                        }
670                        writer = getStrategy(board).updateWriter(board);
671                        // Check if there is no present member left in
672                        if (board.getPresents().isEmpty())
673                        {
674                                // No. we can remove the ImageHolder
675                                _boards.removeImageHolder(where);
676                        }
677                }
678                // Notify all connected users
679                fireEvent(EventFactory.createLeaveBoard(who, where));
680                if (writer >= 0)
681                {
682                        fireEvent(EventFactory.createGiveToken(writer, where));
683                }
684                return true;
685        }
686 
687        private Account                getRealAccount(int id)
688        {
689                Account account = _accounts.getAccount(id, false);
690                if (account == null)
691                {
692                        _logger.warn("Unknown account id " + id);
693                }
694                return account;
695        }
696 
697        private Board                getBoard(int id)
698        {
699                Board board = _boards.getBoard(id, false);
700                if (board == null)
701                {
702                        _logger.info("Unknown board id " + id);
703                        throw new DoesNotExistException("Unknown board id " + id);
704                }
705                return board;
706        }
707 
708        private final Log                                                _logger;
709        private final Channel<Event>                        _channel;
710        private final AccountRepository                        _accounts;
711        private final BoardRepository                        _boards;
712        private final AsynchronousTaskPerformer        _performer;
713        private final AccountDAO                                _accountDAO;
714        private final BoardDAO                                        _boardDAO;
715        private final ObjectTools                                _objectTools;
716        private final int                                                _maxImageSize;
717        private final ServerSettings                        _settings = new ServerSettings();
718}
719// CSON: ClassFanOutComplexityCheck

[all classes][net.sourceforge.hiveboard.business]
EMMA 2.0.5312 (C) Vladimir Roubtsov