1 11 12 package org.jivesoftware.messenger.muc.spi; 13 14 import java.util.*; 15 import java.util.concurrent.ConcurrentHashMap ; 16 import java.util.concurrent.CopyOnWriteArrayList ; 17 import java.util.concurrent.LinkedBlockingQueue ; 18 import java.text.DateFormat ; 19 import java.text.SimpleDateFormat ; 20 21 import org.dom4j.DocumentHelper; 22 import org.dom4j.Element; 23 import org.jivesoftware.messenger.*; 24 import org.jivesoftware.messenger.auth.UnauthorizedException; 25 import org.jivesoftware.messenger.container.BasicModule; 26 import org.jivesoftware.messenger.disco.DiscoInfoProvider; 27 import org.jivesoftware.messenger.disco.DiscoItemsProvider; 28 import org.jivesoftware.messenger.disco.DiscoServerItem; 29 import org.jivesoftware.messenger.disco.ServerItemsProvider; 30 import org.jivesoftware.messenger.forms.DataForm; 31 import org.jivesoftware.messenger.forms.FormField; 32 import org.jivesoftware.messenger.forms.spi.XDataFormImpl; 33 import org.jivesoftware.messenger.forms.spi.XFormFieldImpl; 34 import org.jivesoftware.messenger.muc.HistoryStrategy; 35 import org.jivesoftware.messenger.muc.MUCRole; 36 import org.jivesoftware.messenger.muc.MUCRoom; 37 import org.jivesoftware.messenger.muc.MUCUser; 38 import org.jivesoftware.messenger.muc.MultiUserChatServer; 39 import org.jivesoftware.messenger.muc.NotAllowedException; 40 import org.jivesoftware.messenger.user.UserNotFoundException; 41 import org.jivesoftware.util.LocaleUtils; 42 import org.jivesoftware.util.Log; 43 import org.jivesoftware.util.JiveGlobals; 44 import org.xmpp.packet.*; 45 import org.xmpp.component.ComponentManager; 46 47 63 public class MultiUserChatServerImpl extends BasicModule implements MultiUserChatServer, 64 ServerItemsProvider, DiscoInfoProvider, DiscoItemsProvider, RoutableChannelHandler { 65 66 private static final DateFormat dateFormatter = new SimpleDateFormat ("yyyyMMdd'T'HH:mm:ss"); 67 static { 68 dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); 69 } 70 73 private int user_timeout = 300000; 74 77 private int user_idle = -1; 78 81 private UserTimeoutTask userTimeoutTask; 82 85 private int log_timeout = 300000; 86 89 private int log_batch_size = 50; 90 93 private LogConversationTask logConversationTask; 94 97 private String chatServiceName = null; 98 99 102 private Map <String ,MUCRoom> rooms = new ConcurrentHashMap <String ,MUCRoom>(); 103 104 107 private Map <JID, MUCUser> users = new ConcurrentHashMap <JID, MUCUser>(); 108 private HistoryStrategy historyStrategy; 109 110 private RoutingTable routingTable = null; 111 114 private PacketRouter router = null; 115 118 private IQMUCRegisterHandler registerHandler = null; 119 122 public long totalChatTime; 123 124 128 private Timer timer = new Timer("MUC cleanup"); 129 130 136 private boolean allowToDiscoverLockedRooms = true; 137 138 143 private boolean roomCreationRestricted = false; 144 145 149 private Collection<String > allowedToCreate = new CopyOnWriteArrayList <String >(); 150 151 155 private Collection<String > sysadmins = new CopyOnWriteArrayList <String >(); 156 157 160 private Queue <ConversationLogEntry> logQueue = new LinkedBlockingQueue <ConversationLogEntry>(); 161 162 167 private long emptyLimit = 7 * 24; 168 172 private CleanupTask cleanupTask; 173 176 private final long cleanup_frequency = 60 * 60 * 1000; 177 178 181 public MultiUserChatServerImpl() { 182 super("Basic multi user chat server"); 183 historyStrategy = new HistoryStrategy(null); 184 } 185 186 public String getDescription() { 187 return null; 188 } 189 190 public void process(Packet packet) throws UnauthorizedException, PacketException { 191 processPacket(packet); 193 } 194 195 public void processPacket(Packet packet) { 196 try { 200 if (packet instanceof IQ) { 202 if (process((IQ)packet)) { 203 return; 204 } 205 } 206 MUCUser user = getChatUser(packet.getFrom()); 208 user.process(packet); 209 } 210 catch (Exception e) { 211 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 212 } 213 } 214 215 222 private boolean process(IQ iq) { 223 Element childElement = iq.getChildElement(); 224 String namespace = null; 225 if (childElement != null) { 226 namespace = childElement.getNamespaceURI(); 227 } 228 if ("jabber:iq:register".equals(namespace)) { 229 IQ reply = registerHandler.handleIQ(iq); 230 router.route(reply); 231 } 232 else if ("http://jabber.org/protocol/disco#info".equals(namespace)) { 233 try { 234 IQ reply = XMPPServer.getInstance().getIQDiscoInfoHandler().handleIQ(iq); 237 router.route(reply); 238 } 239 catch (UnauthorizedException e) { 240 } 242 } 243 else if ("http://jabber.org/protocol/disco#items".equals(namespace)) { 244 try { 245 IQ reply = XMPPServer.getInstance().getIQDiscoItemsHandler().handleIQ(iq); 248 router.route(reply); 249 } 250 catch (UnauthorizedException e) { 251 } 253 } 254 else { 255 return false; 256 } 257 return true; 258 } 259 260 public void initialize(JID jid, ComponentManager componentManager) { 261 262 } 263 264 public void shutdown() { 265 266 } 267 268 public String getServiceDomain() { 269 return chatServiceName + "." + XMPPServer.getInstance().getServerInfo().getName(); 270 } 271 272 public JID getAddress() { 273 return new JID(null, getServiceDomain(), null); 274 } 275 276 279 private class UserTimeoutTask extends TimerTask { 280 283 public void run() { 284 checkForTimedOutUsers(); 285 } 286 } 287 288 private void checkForTimedOutUsers() { 289 if (user_idle == -1) { 291 return; 292 } 293 final long deadline = System.currentTimeMillis() - user_idle; 294 for (MUCUser user : users.values()) { 295 try { 296 if (user.getLastPacketTime() < deadline) { 297 Iterator<MUCRole> roles = user.getRoles(); 299 MUCRole role; 300 MUCRoom room; 301 Presence kickedPresence; 302 while (roles.hasNext()) { 303 role = roles.next(); 304 room = role.getChatRoom(); 305 try { 306 kickedPresence = 307 room.kickOccupant(user.getAddress(), null, null); 308 room.send(kickedPresence); 310 } 311 catch (NotAllowedException e) { 312 } 314 } 315 } 316 } 317 catch (Throwable e) { 318 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 319 } 320 } 321 } 322 323 326 private class LogConversationTask extends TimerTask { 327 public void run() { 328 try { 329 logConversation(); 330 } 331 catch (Throwable e) { 332 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 333 } 334 } 335 } 336 337 private void logConversation() { 338 ConversationLogEntry entry = null; 339 boolean success = false; 340 for (int index = 0; index <= log_batch_size && !logQueue.isEmpty(); index++) { 341 entry = logQueue.poll(); 342 if (entry != null) { 343 success = MUCPersistenceManager.saveConversationLogEntry(entry); 344 if (!success) { 345 logQueue.add(entry); 346 } 347 } 348 } 349 } 350 351 355 private void logAllConversation() { 356 ConversationLogEntry entry = null; 357 while (!logQueue.isEmpty()) { 358 entry = logQueue.poll(); 359 if (entry != null) { 360 MUCPersistenceManager.saveConversationLogEntry(entry); 361 } 362 } 363 } 364 365 369 private class CleanupTask extends TimerTask { 370 public void run() { 371 try { 372 cleanupRooms(); 373 } 374 catch (Throwable e) { 375 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 376 } 377 } 378 } 379 380 private void cleanupRooms() { 381 for (MUCRoom room : rooms.values()) { 382 if (room.getEmptyDate() != null && room.getEmptyDate().before(getCleanupDate())) { 383 removeChatRoom(room.getName()); 384 } 385 } 386 } 387 388 public MUCRoom getChatRoom(String roomName, JID userjid) throws UnauthorizedException { 389 MUCRoom room = null; 390 synchronized (roomName.intern()) { 391 room = rooms.get(roomName.toLowerCase()); 392 if (room == null) { 393 room = new MUCRoomImpl(this, roomName, router); 394 try { 396 MUCPersistenceManager.loadFromDB((MUCRoomImpl) room); 400 } 401 catch (IllegalArgumentException e) { 402 if (isRoomCreationRestricted() && 405 !sysadmins.contains(userjid.toBareJID())) { 406 if (!allowedToCreate.contains(userjid.toBareJID())) { 408 throw new UnauthorizedException(); 411 } 412 } 413 room.addFirstOwner(userjid.toBareJID()); 414 } 415 rooms.put(roomName.toLowerCase(), room); 416 } 417 } 418 return room; 419 } 420 421 public MUCRoom getChatRoom(String roomName) { 422 MUCRoom room = rooms.get(roomName.toLowerCase()); 423 if (room == null) { 424 synchronized (roomName.intern()) { 426 room = rooms.get(roomName.toLowerCase()); 427 if (room == null) { 428 room = new MUCRoomImpl(this, roomName, router); 429 try { 431 MUCPersistenceManager.loadFromDB((MUCRoomImpl) room); 435 rooms.put(roomName.toLowerCase(), room); 436 } 437 catch (IllegalArgumentException e) { 438 room = null; 440 } 441 } 442 } 443 } 444 return room; 445 } 446 447 public List <MUCRoom> getChatRooms() { 448 return new ArrayList <MUCRoom>(rooms.values()); 449 } 450 451 public boolean hasChatRoom(String roomName) { 452 return getChatRoom(roomName) != null; 453 } 454 455 public void removeChatRoom(String roomName) { 456 final MUCRoom room = rooms.remove(roomName.toLowerCase()); 457 if (room != null) { 458 final long chatLength = room.getChatLength(); 459 totalChatTime += chatLength; 460 } 461 } 462 463 public String getServiceName() { 464 return chatServiceName; 465 } 466 467 public HistoryStrategy getHistoryStrategy() { 468 return historyStrategy; 469 } 470 471 public void removeUser(JID jabberID) { 472 MUCUser user = users.remove(jabberID); 473 if (user != null) { 474 Iterator<MUCRole> roles = user.getRoles(); 475 while (roles.hasNext()) { 476 MUCRole role = roles.next(); 477 try { 478 role.getChatRoom().leaveRoom(role.getNickname()); 479 } 480 catch (Exception e) { 481 Log.error(e); 482 } 483 } 484 } 485 } 486 487 public MUCUser getChatUser(JID userjid) throws UserNotFoundException { 488 if (router == null) { 489 throw new IllegalStateException ("Not initialized"); 490 } 491 MUCUser user = null; 492 synchronized (userjid.toString().intern()) { 493 user = users.get(userjid); 494 if (user == null) { 495 user = new MUCUserImpl(this, router, userjid); 496 users.put(userjid, user); 497 } 498 } 499 return user; 500 } 501 502 public void serverBroadcast(String msg) throws UnauthorizedException { 503 for (MUCRoom room : rooms.values()) { 504 room.serverBroadcast(msg); 505 } 506 } 507 508 public void setServiceName(String name) { 509 JiveGlobals.setProperty("xmpp.muc.service", name); 510 } 511 512 517 private Date getCleanupDate() { 518 return new Date(System.currentTimeMillis() - (emptyLimit * 3600000)); 519 } 520 521 public void setKickIdleUsersTimeout(int timeout) { 522 if (this.user_timeout == timeout) { 523 return; 524 } 525 if (userTimeoutTask != null) { 527 userTimeoutTask.cancel(); 528 } 529 this.user_timeout = timeout; 530 userTimeoutTask = new UserTimeoutTask(); 532 timer.schedule(userTimeoutTask, user_timeout, user_timeout); 533 JiveGlobals.setProperty("xmpp.muc.tasks.user.timeout", Integer.toString(timeout)); 535 } 536 537 public int getKickIdleUsersTimeout() { 538 return user_timeout; 539 } 540 541 public void setUserIdleTime(int idleTime) { 542 if (this.user_idle == idleTime) { 543 return; 544 } 545 this.user_idle = idleTime; 546 JiveGlobals.setProperty("xmpp.muc.tasks.user.idle", Integer.toString(idleTime)); 548 } 549 550 public int getUserIdleTime() { 551 return user_idle; 552 } 553 554 public void setLogConversationsTimeout(int timeout) { 555 if (this.log_timeout == timeout) { 556 return; 557 } 558 if (logConversationTask != null) { 560 logConversationTask.cancel(); 561 } 562 this.log_timeout = timeout; 563 logConversationTask = new LogConversationTask(); 565 timer.schedule(logConversationTask, log_timeout, log_timeout); 566 JiveGlobals.setProperty("xmpp.muc.tasks.log.timeout", Integer.toString(timeout)); 568 } 569 570 public int getLogConversationsTimeout() { 571 return log_timeout; 572 } 573 574 public void setLogConversationBatchSize(int size) { 575 if (this.log_batch_size == size) { 576 return; 577 } 578 this.log_batch_size = size; 579 JiveGlobals.setProperty("xmpp.muc.tasks.log.batchsize", Integer.toString(size)); 581 } 582 583 public int getLogConversationBatchSize() { 584 return log_batch_size; 585 } 586 587 public Collection<String > getUsersAllowedToCreate() { 588 return allowedToCreate; 589 } 590 591 public Collection<String > getSysadmins() { 592 return sysadmins; 593 } 594 595 public void addSysadmin(String userJID) { 596 sysadmins.add(userJID.trim().toLowerCase()); 597 String [] jids = new String [sysadmins.size()]; 599 jids = (String [])sysadmins.toArray(jids); 600 JiveGlobals.setProperty("xmpp.muc.sysadmin.jid", fromArray(jids)); 601 } 602 603 public void removeSysadmin(String userJID) { 604 sysadmins.remove(userJID.trim().toLowerCase()); 605 String [] jids = new String [sysadmins.size()]; 607 jids = (String [])sysadmins.toArray(jids); 608 JiveGlobals.setProperty("xmpp.muc.sysadmin.jid", fromArray(jids)); 609 } 610 611 617 public boolean isAllowToDiscoverLockedRooms() { 618 return allowToDiscoverLockedRooms; 619 } 620 621 630 public void setAllowToDiscoverLockedRooms(boolean allowToDiscoverLockedRooms) { 631 this.allowToDiscoverLockedRooms = allowToDiscoverLockedRooms; 632 JiveGlobals.setProperty("xmpp.muc.discover.locked", 633 Boolean.toString(allowToDiscoverLockedRooms)); 634 } 635 636 public boolean isRoomCreationRestricted() { 637 return roomCreationRestricted; 638 } 639 640 public void setRoomCreationRestricted(boolean roomCreationRestricted) { 641 this.roomCreationRestricted = roomCreationRestricted; 642 JiveGlobals.setProperty("xmpp.muc.create.anyone", Boolean.toString(roomCreationRestricted)); 643 } 644 645 public void addUserAllowedToCreate(String userJID) { 646 allowedToCreate.add(userJID.trim().toLowerCase()); 649 String [] jids = new String [allowedToCreate.size()]; 651 jids = (String [])allowedToCreate.toArray(jids); 652 JiveGlobals.setProperty("xmpp.muc.create.jid", fromArray(jids)); 653 } 654 655 public void removeUserAllowedToCreate(String userJID) { 656 allowedToCreate.remove(userJID.trim().toLowerCase()); 659 String [] jids = new String [allowedToCreate.size()]; 661 jids = (String [])allowedToCreate.toArray(jids); 662 JiveGlobals.setProperty("xmpp.muc.create.jid", fromArray(jids)); 663 } 664 665 public void initialize(XMPPServer server) { 666 super.initialize(server); 667 668 chatServiceName = JiveGlobals.getProperty("xmpp.muc.service"); 669 historyStrategy.setContext("xmpp.muc.history"); 671 String property = JiveGlobals.getProperty("xmpp.muc.sysadmin.jid"); 673 String [] jids; 674 if (property != null) { 675 jids = property.split(","); 676 for (int i = 0; i < jids.length; i++) { 677 sysadmins.add(jids[i].trim().toLowerCase()); 678 } 679 } 680 allowToDiscoverLockedRooms = 681 Boolean.parseBoolean(JiveGlobals.getProperty("xmpp.muc.discover.locked", "true")); 682 roomCreationRestricted = 683 Boolean.parseBoolean(JiveGlobals.getProperty("xmpp.muc.create.anyone", "false")); 684 property = JiveGlobals.getProperty("xmpp.muc.create.jid"); 686 if (property != null) { 687 jids = property.split(","); 688 for (int i = 0; i < jids.length; i++) { 689 allowedToCreate.add(jids[i].trim().toLowerCase()); 690 } 691 } 692 String value = JiveGlobals.getProperty("xmpp.muc.tasks.user.timeout"); 693 if (value != null) { 694 try { 695 user_timeout = Integer.parseInt(value); 696 } 697 catch (NumberFormatException e) { 698 Log.error("Wrong number format of property xmpp.muc.tasks.user.timeout", e); 699 } 700 } 701 value = JiveGlobals.getProperty("xmpp.muc.tasks.user.idle"); 702 if (value != null) { 703 try { 704 user_idle = Integer.parseInt(value); 705 } 706 catch (NumberFormatException e) { 707 Log.error("Wrong number format of property xmpp.muc.tasks.user.idle", e); 708 } 709 } 710 value = JiveGlobals.getProperty("xmpp.muc.tasks.log.timeout"); 711 if (value != null) { 712 try { 713 log_timeout = Integer.parseInt(value); 714 } 715 catch (NumberFormatException e) { 716 Log.error("Wrong number format of property xmpp.muc.tasks.log.timeout", e); 717 } 718 } 719 value = JiveGlobals.getProperty("xmpp.muc.tasks.log.batchsize"); 720 if (value != null) { 721 try { 722 log_batch_size = Integer.parseInt(value); 723 } 724 catch (NumberFormatException e) { 725 Log.error("Wrong number format of property xmpp.muc.tasks.log.batchsize", e); 726 } 727 } 728 if (chatServiceName == null) { 729 chatServiceName = "conference"; 730 } 731 userTimeoutTask = new UserTimeoutTask(); 734 timer.schedule(userTimeoutTask, user_timeout, user_timeout); 735 logConversationTask = new LogConversationTask(); 738 timer.schedule(logConversationTask, log_timeout, log_timeout); 739 cleanupTask = new CleanupTask(); 741 timer.schedule(cleanupTask, cleanup_frequency, cleanup_frequency); 742 743 routingTable = server.getRoutingTable(); 744 router = server.getPacketRouter(); 745 registerHandler = new IQMUCRegisterHandler(this); 747 } 748 749 public void start() { 750 super.start(); 751 routingTable.addRoute(getAddress(), this); 753 ArrayList params = new ArrayList (); 754 params.clear(); 755 params.add(getServiceDomain()); 756 Log.info(LocaleUtils.getLocalizedString("startup.starting.muc", params)); 757 for (MUCRoom room : MUCPersistenceManager.loadRoomsFromDB(this, this.getCleanupDate(), 759 router)) { 760 rooms.put(room.getName().toLowerCase(), room); 761 } 762 } 763 764 public void stop() { 765 super.stop(); 766 routingTable.removeRoute(getAddress()); 768 timer.cancel(); 769 logAllConversation(); 770 } 771 772 public long getTotalChatTime() { 773 return totalChatTime; 774 } 775 776 public void logConversation(MUCRoom room, Message message, JID sender) { 777 logQueue.add(new ConversationLogEntry(new Date(), room, message, sender)); 778 } 779 780 public Iterator getItems() { 781 ArrayList items = new ArrayList (); 782 783 items.add(new DiscoServerItem() { 784 public String getJID() { 785 return getServiceDomain(); 786 } 787 788 public String getName() { 789 return "Public Chatrooms"; 790 } 791 792 public String getAction() { 793 return null; 794 } 795 796 public String getNode() { 797 return null; 798 } 799 800 public DiscoInfoProvider getDiscoInfoProvider() { 801 return MultiUserChatServerImpl.this; 802 } 803 804 public DiscoItemsProvider getDiscoItemsProvider() { 805 return MultiUserChatServerImpl.this; 806 } 807 }); 808 return items.iterator(); 809 } 810 811 public Iterator<Element> getIdentities(String name, String node, JID senderJID) { 812 ArrayList <Element> identities = new ArrayList <Element>(); 813 if (name == null && node == null) { 814 Element identity = DocumentHelper.createElement("identity"); 816 identity.addAttribute("category", "conference"); 817 identity.addAttribute("name", "Public Chatrooms"); 818 identity.addAttribute("type", "text"); 819 820 identities.add(identity); 821 } 822 else if (name != null && node == null) { 823 MUCRoom room = getChatRoom(name); 825 if (room != null && canDiscoverRoom(room)) { 826 Element identity = DocumentHelper.createElement("identity"); 827 identity.addAttribute("category", "conference"); 828 identity.addAttribute("name", room.getNaturalLanguageName()); 829 identity.addAttribute("type", "text"); 830 831 identities.add(identity); 832 } 833 } 834 else if (name != null && "x-roomuser-item".equals(node)) { 835 MUCRoom room = getChatRoom(name); 837 if (room != null) { 838 String reservedNick = room.getReservedNickname(senderJID.toBareJID()); 839 if (reservedNick != null) { 840 Element identity = DocumentHelper.createElement("identity"); 841 identity.addAttribute("category", "conference"); 842 identity.addAttribute("name", reservedNick); 843 identity.addAttribute("type", "text"); 844 845 identities.add(identity); 846 } 847 } 848 } 849 return identities.iterator(); 850 } 851 852 public Iterator<String > getFeatures(String name, String node, JID senderJID) { 853 ArrayList <String > features = new ArrayList <String >(); 854 if (name == null && node == null) { 855 features.add("http://jabber.org/protocol/muc"); 857 features.add("http://jabber.org/protocol/disco#info"); 858 features.add("http://jabber.org/protocol/disco#items"); 859 } 860 else if (name != null && node == null) { 861 MUCRoom room = getChatRoom(name); 864 if (room != null && canDiscoverRoom(room)) { 865 features.add("http://jabber.org/protocol/muc"); 866 features.add("muc_public"); 868 if (room.isMembersOnly()) { 869 features.add("muc_membersonly"); 870 } 871 else { 872 features.add("muc_open"); 873 } 874 if (room.isModerated()) { 875 features.add("muc_moderated"); 876 } 877 else { 878 features.add("muc_unmoderated"); 879 } 880 if (room.canAnyoneDiscoverJID()) { 881 features.add("muc_nonanonymous"); 882 } 883 else { 884 features.add("muc_semianonymous"); 885 } 886 if (room.isPasswordProtected()) { 887 features.add("muc_passwordprotected"); 888 } 889 else { 890 features.add("muc_unsecured"); 891 } 892 if (room.isPersistent()) { 893 features.add("muc_persistent"); 894 } 895 else { 896 features.add("muc_temporary"); 897 } 898 } 899 } 900 return features.iterator(); 901 } 902 903 public XDataFormImpl getExtendedInfo(String name, String node, JID senderJID) { 904 if (name != null && node == null) { 905 MUCRoom room = getChatRoom(name); 908 if (room != null && canDiscoverRoom(room)) { 909 XDataFormImpl dataForm = new XDataFormImpl(DataForm.TYPE_RESULT); 910 911 XFormFieldImpl field = new XFormFieldImpl("FORM_TYPE"); 912 field.setType(FormField.TYPE_HIDDEN); 913 field.addValue("http://jabber.org/protocol/muc#roominfo"); 914 dataForm.addField(field); 915 916 field = new XFormFieldImpl("muc#roominfo_description"); 917 field.setLabel(LocaleUtils.getLocalizedString("muc.extended.info.desc")); 918 field.addValue(room.getDescription()); 919 dataForm.addField(field); 920 921 field = new XFormFieldImpl("muc#roominfo_subject"); 922 field.setLabel(LocaleUtils.getLocalizedString("muc.extended.info.subject")); 923 field.addValue(room.getSubject()); 924 dataForm.addField(field); 925 926 field = new XFormFieldImpl("muc#roominfo_occupants"); 927 field.setLabel(LocaleUtils.getLocalizedString("muc.extended.info.occupants")); 928 field.addValue(Integer.toString(room.getOccupantsCount())); 929 dataForm.addField(field); 930 931 935 936 field = new XFormFieldImpl("x-muc#roominfo_creationdate"); 937 field.setLabel(LocaleUtils.getLocalizedString("muc.extended.info.creationdate")); 938 field.addValue(dateFormatter.format(room.getCreationDate())); 939 dataForm.addField(field); 940 941 return dataForm; 942 } 943 } 944 return null; 945 } 946 947 public boolean hasInfo(String name, String node, JID senderJID) { 948 if (name == null && node == node) { 949 return true; 951 } 952 else if (name != null && node == null) { 953 return hasChatRoom(name); 955 } 956 else if (name != null && "x-roomuser-item".equals(node)) { 957 return hasChatRoom(name); 959 } 960 return false; 961 } 962 963 public Iterator<Element> getItems(String name, String node, JID senderJID) { 964 List <Element> answer = new ArrayList <Element>(); 965 if (name == null && node == null) { 966 Element item; 967 for (MUCRoom room : rooms.values()) { 969 if (canDiscoverRoom(room)) { 970 item = DocumentHelper.createElement("item"); 971 item.addAttribute("jid", room.getRole().getRoleAddress().toString()); 972 item.addAttribute("name", room.getNaturalLanguageName()); 973 974 answer.add(item); 975 } 976 } 977 } 978 else if (name != null && node == null) { 979 MUCRoom room = getChatRoom(name); 981 if (room != null && canDiscoverRoom(room)) { 982 Element item; 983 for (MUCRole role : room.getOccupants()) { 984 item = DocumentHelper.createElement("item"); 986 item.addAttribute("jid", role.getRoleAddress().toString()); 987 988 answer.add(item); 989 } 990 } 991 } 992 return answer.iterator(); 993 } 994 995 private boolean canDiscoverRoom(MUCRoom room) { 996 if (!allowToDiscoverLockedRooms && room.isLocked()) { 998 return false; 999 } 1000 return room.isPublicRoom(); 1001 } 1002 1003 1009 private static String fromArray(String [] array) { 1010 StringBuilder buf = new StringBuilder (); 1011 for (int i=0; i<array.length; i++) { 1012 buf.append(array[i]); 1013 if (i != array.length-1) { 1014 buf.append(","); 1015 } 1016 } 1017 return buf.toString(); 1018 } 1019} | Popular Tags |