summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/isode/stroke/queries/IQRouter.java')
-rw-r--r--src/com/isode/stroke/queries/IQRouter.java51
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;
+ }
}