diff options
Diffstat (limited to 'src/com/isode/stroke/queries/IQRouter.java')
-rw-r--r-- | src/com/isode/stroke/queries/IQRouter.java | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/src/com/isode/stroke/queries/IQRouter.java b/src/com/isode/stroke/queries/IQRouter.java index 0dd55f2..7b6e5d7 100644 --- a/src/com/isode/stroke/queries/IQRouter.java +++ b/src/com/isode/stroke/queries/IQRouter.java @@ -10,6 +10,7 @@ import com.isode.stroke.elements.ErrorPayload; import com.isode.stroke.elements.IQ; import com.isode.stroke.signals.Slot1; import com.isode.stroke.jid.JID; +import java.util.Collections; /** * This class is responsible for routing all IQ stanzas to the handlers. It's @@ -21,12 +22,16 @@ import com.isode.stroke.jid.JID; */ public class IQRouter { - private final Vector<IQHandler> handlers_ = new Vector<IQHandler>(); - private final IQChannel channel_; + private Vector<IQHandler> handlers_ = new Vector<IQHandler>(); + private IQChannel channel_; private JID jid_ = new JID(); + private JID from_ = new JID(); + private Vector<IQHandler> queuedRemoves_ = new Vector<IQHandler>(); + private boolean queueRemoves_; public IQRouter(IQChannel channel) { channel_ = channel; + queueRemoves_ = false; channel_.onIQReceived.connect(new Slot1<IQ>() { public void call(IQ p1) { @@ -42,12 +47,20 @@ public class IQRouter { } public void removeHandler(IQHandler handler) { - synchronized (handlers_) { - handlers_.remove(handler); + if (queueRemoves_) { + queuedRemoves_.add(handler); + } + else { + synchronized (handlers_) { + handlers_.remove(handler); + } } } public void sendIQ(IQ iq) { + if (from_.isValid() && !iq.getFrom().isValid()) { + iq.setFrom(from_); + } channel_.sendIQ(iq); } @@ -70,9 +83,13 @@ public class IQRouter { } private void handleIQ(IQ iq) { + queueRemoves_ = true; boolean handled = false; + Vector<IQHandler> i = new Vector<IQHandler>(); + i.addAll(handlers_); + Collections.reverse(i); synchronized (handlers_) { - for (IQHandler handler : handlers_) { + for (IQHandler handler : i) { handled |= handler.handleIQ(iq); if (handled) { break; @@ -82,6 +99,18 @@ public class IQRouter { if (!handled && (iq.getType().equals(IQ.Type.Get) || iq.getType().equals(IQ.Type.Set))) { sendIQ(IQ.createError(iq.getFrom(), iq.getID(), ErrorPayload.Condition.FeatureNotImplemented, ErrorPayload.Type.Cancel)); } + + processPendingRemoves(); + queueRemoves_ = false; + } + + public void processPendingRemoves() { + synchronized(handlers_) { + for(IQHandler handler : queuedRemoves_) { + handlers_.remove(handler); + } + } + queuedRemoves_.clear(); } /** @@ -98,5 +127,15 @@ public class IQRouter { public JID getJID() { return jid_; } - + + /** + * Sets the 'from' JID for all outgoing IQ stanzas. + * + * By default, IQRouter does not add a from to IQ stanzas, since + * this is automatically added by the server. This overrides this + * default behavior, which is necessary for e.g. components. + */ + public void setFrom(final JID from) { + from_ = from; + } } |