use of org.jivesoftware.util.AutoCloseableReentrantLock in project Openfire by igniterealtime.
the class MultiUserChatServiceImpl method processPacket.
@Override
public void processPacket(final Packet packet) {
Log.trace("Routing stanza: {}", packet.toXML());
if (!isServiceEnabled()) {
Log.trace("Service is disabled. Ignoring stanza.");
return;
}
// service itself instead of relying on the server to handle the request.
try {
// Check for IQ Ping responses
if (isPendingPingResponse(packet)) {
Log.debug("Ping response received from occupant '{}', addressed to: '{}'", packet.getFrom(), packet.getTo());
return;
}
// Check for 'ghost' users (OF-910 / OF-2209 / OF-2369)
if (isDeliveryRelatedErrorResponse(packet)) {
Log.info("Received a stanza that contained a delivery-related error response from {}. This is indicative of a 'ghost' user. Removing this user from all chat rooms.", packet.getFrom());
removeChatUser(packet.getFrom());
return;
}
// Check if the packet is a disco request or a packet with namespace iq:register
if (packet instanceof IQ) {
if (process((IQ) packet)) {
Log.trace("Done processing IQ stanza.");
return;
}
}
if (packet.getTo().getNode() == null) {
Log.trace("Stanza was addressed at the service itself, which by now should have been handled.");
if (packet instanceof IQ && ((IQ) packet).isRequest()) {
final IQ reply = IQ.createResultIQ((IQ) packet);
reply.setChildElement(((IQ) packet).getChildElement().createCopy());
reply.setError(PacketError.Condition.feature_not_implemented);
XMPPServer.getInstance().getPacketRouter().route(reply);
}
Log.debug("Ignoring stanza addressed at conference service: {}", packet.toXML());
} else {
Log.trace("The stanza is a normal packet that should possibly be sent to the room.");
final JID recipient = packet.getTo();
final String roomName = recipient != null ? recipient.getNode() : null;
final JID userJid = packet.getFrom();
occupantManager.registerActivity(userJid);
Log.trace("Stanza recipient: {}, room name: {}, sender: {}", recipient, roomName, userJid);
try (final AutoCloseableReentrantLock.AutoCloseableLock ignored = new AutoCloseableReentrantLock(MultiUserChatServiceImpl.class, userJid.toString()).lock()) {
if (!packet.getElement().elements(FMUCHandler.FMUC).isEmpty()) {
Log.trace("Stanza is a FMUC stanza.");
if (roomName == null) {
Log.warn("Unable to process FMUC stanza, as it does not address a room: {}", packet.toXML());
} else {
final Lock lock = getChatRoomLock(roomName);
lock.lock();
try {
final MUCRoom chatRoom = getChatRoom(roomName);
if (chatRoom != null) {
chatRoom.getFmucHandler().process(packet);
// Ensure that other cluster nodes see the changes applied by the method above.
syncChatRoom(chatRoom);
} else {
Log.warn("Unable to process FMUC stanza, as room it's addressed to does not exist: {}", roomName);
// FIXME need to send error back in case of IQ request, and FMUC join. Might want to send error back in other cases too.
}
} finally {
lock.unlock();
}
}
} else {
Log.trace("Stanza is a regular MUC stanza.");
processRegularStanza(packet);
}
}
}
} catch (final Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
Aggregations