All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jivesoftware.openfire.interceptor.InterceptorManager Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2005-2008 Jive Software. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jivesoftware.openfire.interceptor;

import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.Packet;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * An InterceptorManager manages the list of global interceptors and per-user
 * interceptors that are invoked before and after packets are read and sent.
 * If an interceptor is installed for a user then it will receive all packets
 * sent or received for any connection of that user.

* * PacketInterceptors that are invoked before the packet is sent or processed * (when read) may change the original packet or reject the packet by throwing * a {@link PacketRejectedException}. If the interceptor rejects a received packet * then the sender of the packet receive a * {@link org.xmpp.packet.PacketError.Condition#not_allowed not_allowed} error. * * @see PacketInterceptor * @author Gaston Dombiak */ public class InterceptorManager { private static final Logger Log = LoggerFactory.getLogger(InterceptorManager.class); private static InterceptorManager instance = new InterceptorManager(); private XMPPServer server = XMPPServer.getInstance(); private List globalInterceptors = new CopyOnWriteArrayList<>(); private Map> usersInterceptors = new ConcurrentHashMap<>(); /** * Returns a singleton instance of InterceptorManager. * * @return an instance of InterceptorManager. */ public static InterceptorManager getInstance() { return instance; } /** * Returns an unmodifiable list of global packet interceptors. Global * interceptors are applied to all packets read and sent by the server. * * @return an unmodifiable list of the global packet interceptors. */ public List getInterceptors() { return Collections.unmodifiableList(globalInterceptors); } /** * Inserts a new interceptor at the end of the list of currently configured * interceptors. This interceptor will be used for all the sent and received packets. * * @param interceptor the interceptor to add. */ public void addInterceptor(PacketInterceptor interceptor) { if (interceptor == null) { throw new NullPointerException("Parameter interceptor was null."); } // Remove the interceptor from the list since the position might have changed if (globalInterceptors.contains(interceptor)) { globalInterceptors.remove(interceptor); } globalInterceptors.add(interceptor); } /** * Inserts a new interceptor at specified index in the list of currently configured * interceptors. This interceptor will be used for all the sent and received packets. * * @param index the index in the list to insert the new interceptor at. * @param interceptor the interceptor to add. */ public void addInterceptor(int index, PacketInterceptor interceptor) { if (index < 0 || (index > globalInterceptors.size())) { throw new IndexOutOfBoundsException("Index " + index + " invalid."); } if (interceptor == null) { throw new NullPointerException("Parameter interceptor was null."); } // Remove the interceptor from the list since the position might have changed if (globalInterceptors.contains(interceptor)) { int oldIndex = globalInterceptors.indexOf(interceptor); if (oldIndex < index) { index -= 1; } globalInterceptors.remove(interceptor); } globalInterceptors.add(index, interceptor); } /** * Removes the global interceptor from the list. * * @param interceptor the interceptor to remove. * @return true if the item was present in the list */ public boolean removeInterceptor(PacketInterceptor interceptor) { return globalInterceptors.remove(interceptor); } /** * Returns an unmodifable list of packet interceptors that are related to the * specified username. * * @param username the name of the user. * @return an unmodifiable list of packet interceptors that are related to * the specified username. */ public List getUserInterceptors(String username) { List userInterceptors = usersInterceptors.get(username); if (userInterceptors == null) { return Collections.emptyList(); } else { return Collections.unmodifiableList(userInterceptors); } } /** * Inserts a new interceptor at specified index in the list of currently configured * interceptors for a specific username. This interceptor will be used only when a packet * was sent or received by the specified username. * * @param username the name of the user. * @param index the index in the list to insert the new interceptor at. * @param interceptor the interceptor to add. */ public void addUserInterceptor(String username, int index, PacketInterceptor interceptor) { List userInterceptors = usersInterceptors.get(username); if (userInterceptors == null) { userInterceptors = new CopyOnWriteArrayList<>(); usersInterceptors.put(username, userInterceptors); } else { if (index < 0 || (index > userInterceptors.size())) { throw new IndexOutOfBoundsException("Index " + index + " invalid."); } if (interceptor == null) { throw new NullPointerException("Parameter interceptor was null."); } // Remove the interceptor from the list since the position might have changed if (userInterceptors.contains(interceptor)) { int oldIndex = userInterceptors.indexOf(interceptor); if (oldIndex < index) { index -= 1; } userInterceptors.remove(interceptor); } } userInterceptors.add(index, interceptor); } /** * Removes the interceptor from the list of interceptors that are related to a specific * username. * * @param username the name of the user. * @param interceptor the interceptor to remove. * @return true if the item was present in the list */ public boolean removeUserInterceptor(String username, PacketInterceptor interceptor) { boolean answer = false; List userInterceptors = usersInterceptors.get(username); if (userInterceptors != null) { answer = userInterceptors.remove(interceptor); // Remove the entry for this username if the list is now empty if (userInterceptors.isEmpty()) { usersInterceptors.remove(username); } } return answer; } /** * Invokes all currently-installed interceptors on the specified packet. * All global interceptors will be invoked as well as interceptors that * are related to the address of the session that received or is sending * the packet.

* * Interceptors are executed before and after processing an incoming packet * and sending a packet to a user. This means that interceptors are able to alter or * reject packets before they are processed further. If possible, interceptors * should perform their work in a short time so that overall performance is not * compromised. * * @param packet the packet that has been read or is about to be sent. * @param session the session that received the packet or that the packet * will be sent to. * @param read true indicates that the packet was read. When false, the packet * is being sent to a user. * @param processed true if the packet has already processed (incoming or outgoing). * If the packet hasn't already been processed, this flag will be false. * @throws PacketRejectedException if the packet should be prevented from being processed. */ public void invokeInterceptors(Packet packet, Session session, boolean read, boolean processed) throws PacketRejectedException { // Invoke the global interceptors for this packet invokeInterceptors( globalInterceptors, packet, session, read, processed ); // Invoke the interceptors that are related to the address of the session if (usersInterceptors.isEmpty()) { // Do nothing return; } String username = session != null ? session.getAddress().getNode() : null; if (username != null && server.isLocal(session.getAddress())) { Collection userInterceptors = usersInterceptors.get(username); invokeInterceptors( userInterceptors, packet, session, read, processed ); } } /** * Invokes a collection of interceptors for the provided packet. * * @param interceptors The interceptors to be triggered (can be null, can be empty). * @param packet the packet that has been read or is about to be sent. * @param session the session that received the packet or that the packet * will be sent to. * @param read true indicates that the packet was read. When false, the packet * is being sent to a user. * @param processed true if the packet has already processed (incoming or outgoing). * If the packet hasn't already been processed, this flag will be false. * @throws PacketRejectedException if the packet should be prevented from being processed. */ protected static void invokeInterceptors( Collection interceptors, Packet packet, Session session, boolean read, boolean processed ) throws PacketRejectedException { if ( interceptors == null || interceptors.isEmpty() ) { return; } for ( final PacketInterceptor interceptor : interceptors ) { try { interceptor.interceptPacket( packet, session, read, processed ); } catch ( PacketRejectedException e ) { if ( processed ) { Log.error( "Post interceptor cannot reject packet.", e ); } else { // Throw this exception since we don't really want to catch it throw e; } } catch ( Throwable e ) { Log.error( "Error in interceptor: " + interceptor + " while intercepting: " + packet, e ); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy