1 /** 2 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 3 * you may not use this file except in compliance with the License. 4 * You may obtain a copy of the License at 5 * 6 * http://www.apache.org/licenses/LICENSE-2.0 7 * 8 * Unless required by applicable law or agreed to in writing, software 9 * distributed under the License is distributed on an "AS IS" BASIS, 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 * See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14 package org.jivesoftware.smackx.bytestreams.ibb; 15 16 import java.util.concurrent.ExecutorService; 17 import java.util.concurrent.Executors; 18 19 import org.jivesoftware.smack.PacketListener; 20 import org.jivesoftware.smack.filter.AndFilter; 21 import org.jivesoftware.smack.filter.IQTypeFilter; 22 import org.jivesoftware.smack.filter.PacketFilter; 23 import org.jivesoftware.smack.filter.PacketTypeFilter; 24 import org.jivesoftware.smack.packet.IQ; 25 import org.jivesoftware.smack.packet.Packet; 26 import org.jivesoftware.smackx.bytestreams.BytestreamListener; 27 import org.jivesoftware.smackx.bytestreams.ibb.packet.Open; 28 29 /** 30 * InitiationListener handles all incoming In-Band Bytestream open requests. If there are no 31 * listeners for a In-Band Bytestream request InitiationListener will always refuse the request and 32 * reply with a <not-acceptable/> error (<a 33 * href="http://xmpp.org/extensions/xep-0047.html#example-5" >XEP-0047</a> Section 2.1). 34 * <p> 35 * All In-Band Bytestream request having a block size greater than the maximum allowed block size 36 * for this connection are rejected with an <resource-constraint/> error. The maximum block 37 * size can be set by invoking {@link InBandBytestreamManager#setMaximumBlockSize(int)}. 38 * 39 * @author Henning Staib 40 */ 41 class InitiationListener implements PacketListener { 42 43 /* manager containing the listeners and the XMPP connection */ 44 private final InBandBytestreamManager manager; 45 46 /* packet filter for all In-Band Bytestream requests */ 47 private final PacketFilter initFilter = new AndFilter(new PacketTypeFilter(Open.class), 48 new IQTypeFilter(IQ.Type.SET)); 49 50 /* executor service to process incoming requests concurrently */ 51 private final ExecutorService initiationListenerExecutor; 52 53 /** 54 * Constructor. 55 * 56 * @param manager the In-Band Bytestream manager 57 */ 58 protected InitiationListener(InBandBytestreamManager manager) { 59 this.manager = manager; 60 initiationListenerExecutor = Executors.newCachedThreadPool(); 61 } 62 63 public void processPacket(final Packet packet) { 64 initiationListenerExecutor.execute(new Runnable() { 65 66 public void run() { 67 processRequest(packet); 68 } 69 }); 70 } 71 72 private void processRequest(Packet packet) { 73 Open ibbRequest = (Open) packet; 74 75 // validate that block size is within allowed range 76 if (ibbRequest.getBlockSize() > this.manager.getMaximumBlockSize()) { 77 this.manager.replyResourceConstraintPacket(ibbRequest); 78 return; 79 } 80 81 // ignore request if in ignore list 82 if (this.manager.getIgnoredBytestreamRequests().remove(ibbRequest.getSessionID())) 83 return; 84 85 // build bytestream request from packet 86 InBandBytestreamRequest request = new InBandBytestreamRequest(this.manager, ibbRequest); 87 88 // notify listeners for bytestream initiation from a specific user 89 BytestreamListener userListener = this.manager.getUserListener(ibbRequest.getFrom()); 90 if (userListener != null) { 91 userListener.incomingBytestreamRequest(request); 92 93 } 94 else if (!this.manager.getAllRequestListeners().isEmpty()) { 95 /* 96 * if there is no user specific listener inform listeners for all initiation requests 97 */ 98 for (BytestreamListener listener : this.manager.getAllRequestListeners()) { 99 listener.incomingBytestreamRequest(request); 100 } 101 102 } 103 else { 104 /* 105 * if there is no listener for this initiation request, reply with reject message 106 */ 107 this.manager.replyRejectPacket(ibbRequest); 108 } 109 } 110 111 /** 112 * Returns the packet filter for In-Band Bytestream open requests. 113 * 114 * @return the packet filter for In-Band Bytestream open requests 115 */ 116 protected PacketFilter getFilter() { 117 return this.initFilter; 118 } 119 120 /** 121 * Shuts down the listeners executor service. 122 */ 123 protected void shutdown() { 124 this.initiationListenerExecutor.shutdownNow(); 125 } 126 127 } 128