StreamManagement.java

  1. /**
  2.  *
  3.  * Copyright © 2014 Florian Schmaus
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.jivesoftware.smack.sm.packet;

  18. import org.jivesoftware.smack.packet.FullStreamElement;
  19. import org.jivesoftware.smack.packet.ExtensionElement;
  20. import org.jivesoftware.smack.packet.XMPPError;
  21. import org.jivesoftware.smack.util.XmlStringBuilder;

  22. public class StreamManagement {
  23.     public static final String NAMESPACE = "urn:xmpp:sm:3";

  24.     public static class StreamManagementFeature implements ExtensionElement {

  25.         public static final String ELEMENT = "sm";
  26.         public static final StreamManagementFeature INSTANCE = new StreamManagementFeature();

  27.         private StreamManagementFeature() {
  28.         }

  29.         @Override
  30.         public String getElementName() {
  31.             return ELEMENT;
  32.         }

  33.         @Override
  34.         public String getNamespace() {
  35.             return NAMESPACE;
  36.         }

  37.         @Override
  38.         public CharSequence toXML() {
  39.             XmlStringBuilder xml = new XmlStringBuilder(this);
  40.             xml.closeEmptyElement();
  41.             return xml;
  42.         }
  43.     }

  44.     private static abstract class AbstractEnable extends FullStreamElement {

  45.         /**
  46.          * Preferred maximum resumption time in seconds (optional).
  47.          */
  48.         protected int max = -1;

  49.         protected boolean resume = false;

  50.         protected void maybeAddResumeAttributeTo(XmlStringBuilder xml) {
  51.             if (resume) {
  52.                 // XEP 198 never mentions the case where resume='false', it's either set to true or
  53.                 // not set at all. We reflect this in this code part
  54.                 xml.attribute("resume", "true");
  55.             }
  56.         }

  57.         protected void maybeAddMaxAttributeTo(XmlStringBuilder xml) {
  58.             if (max > 0) {
  59.                 xml.attribute("max", Integer.toString(max));
  60.             }
  61.         }

  62.         public boolean isResumeSet() {
  63.             return resume;
  64.         }

  65.         /**
  66.          * Return the max resumption time in seconds.
  67.          * @return the max resumption time in seconds
  68.          */
  69.         public int getMaxResumptionTime() {
  70.             return max;
  71.         }

  72.         @Override
  73.         public final String getNamespace() {
  74.             return NAMESPACE;
  75.         }
  76.     }

  77.     public static class Enable extends AbstractEnable {
  78.         public static final String ELEMENT = "enable";

  79.         public static final Enable INSTANCE = new Enable();

  80.         private Enable() {
  81.         }

  82.         public Enable(boolean resume) {
  83.             this.resume = resume;
  84.         }

  85.         public Enable(boolean resume, int max) {
  86.             this(resume);
  87.             this.max = max;
  88.         }

  89.         @Override
  90.         public CharSequence toXML() {
  91.             XmlStringBuilder xml = new XmlStringBuilder(this);
  92.             maybeAddResumeAttributeTo(xml);
  93.             maybeAddMaxAttributeTo(xml);
  94.             xml.closeEmptyElement();
  95.             return xml;
  96.         }

  97.         @Override
  98.         public String getElementName() {
  99.             return ELEMENT;
  100.         }
  101.     }

  102.     /**
  103.      * A Stream Management 'enabled' element.
  104.      * <p>
  105.      * Here is a full example, all attributes besides 'xmlns' are optional.
  106.      * </p>
  107.      * <pre>
  108.      * {@code
  109.      * <enabled xmlns='urn:xmpp:sm:3'
  110.      *      id='some-long-sm-id'
  111.      *      location='[2001:41D0:1:A49b::1]:9222'
  112.      *      resume='true'/>
  113.      * }
  114.      * </pre>
  115.      */
  116.     public static class Enabled extends AbstractEnable {
  117.         public static final String ELEMENT = "enabled";

  118.         /**
  119.          * The stream id ("SM-ID")
  120.          */
  121.         private final String id;

  122.         /**
  123.          * The location where the server prefers reconnection.
  124.          */
  125.         private final String location;

  126.         public Enabled(String id, boolean resume) {
  127.             this(id, resume, null, -1);
  128.         }

  129.         public Enabled(String id, boolean resume, String location, int max) {
  130.             this.id = id;
  131.             this.resume = resume;
  132.             this.location = location;
  133.             this.max = max;
  134.         }

  135.         public String getId() {
  136.             return id;
  137.         }

  138.         public String getLocation() {
  139.             return location;
  140.         }

  141.         @Override
  142.         public CharSequence toXML() {
  143.             XmlStringBuilder xml = new XmlStringBuilder(this);
  144.             xml.optAttribute("id", id);
  145.             maybeAddResumeAttributeTo(xml);
  146.             xml.optAttribute("location", location);
  147.             maybeAddMaxAttributeTo(xml);
  148.             xml.closeEmptyElement();
  149.             return xml;
  150.         }

  151.         @Override
  152.         public String getElementName() {
  153.             return ELEMENT;
  154.         }
  155.     }

  156.     public static class Failed extends FullStreamElement {
  157.         public static final String ELEMENT = "failed";

  158.         private XMPPError.Condition condition;

  159.         public Failed() {
  160.         }

  161.         public Failed(XMPPError.Condition condition) {
  162.             this.condition = condition;
  163.         }

  164.         public XMPPError.Condition getXMPPErrorCondition() {
  165.             return condition;
  166.         }

  167.         @Override
  168.         public CharSequence toXML() {
  169.             XmlStringBuilder xml = new XmlStringBuilder(this);
  170.             if (condition != null) {
  171.                 xml.rightAngleBracket();
  172.                 xml.append(condition.toString());
  173.                 xml.xmlnsAttribute(XMPPError.NAMESPACE);
  174.                 xml.closeElement(ELEMENT);
  175.             }
  176.             else {
  177.                 xml.closeEmptyElement();
  178.             }
  179.             return xml;
  180.         }

  181.         @Override
  182.         public String getNamespace() {
  183.             return NAMESPACE;
  184.         }

  185.         @Override
  186.         public String getElementName() {
  187.             return ELEMENT;
  188.         }

  189.     }

  190.     private static abstract class AbstractResume extends FullStreamElement {

  191.         private final long handledCount;
  192.         private final String previd;

  193.         public AbstractResume(long handledCount, String previd) {
  194.             this.handledCount = handledCount;
  195.             this.previd = previd;
  196.         }

  197.         public long getHandledCount() {
  198.             return handledCount;
  199.         }

  200.         public String getPrevId() {
  201.             return previd;
  202.         }

  203.         @Override
  204.         public final String getNamespace() {
  205.             return NAMESPACE;
  206.         }

  207.         @Override
  208.         public final XmlStringBuilder toXML() {
  209.             XmlStringBuilder xml = new XmlStringBuilder(this);
  210.             xml.attribute("h", Long.toString(handledCount));
  211.             xml.attribute("previd", previd);
  212.             xml.closeEmptyElement();
  213.             return xml;
  214.         }
  215.     }

  216.     public static class Resume extends AbstractResume {
  217.         public static final String ELEMENT = "resume";

  218.         public Resume(long handledCount, String previd) {
  219.             super(handledCount, previd);
  220.         }

  221.         @Override
  222.         public String getElementName() {
  223.             return ELEMENT;
  224.         }
  225.     }

  226.     public static class Resumed extends AbstractResume {
  227.         public static final String ELEMENT = "resumed";

  228.         public Resumed(long handledCount, String previd) {
  229.             super(handledCount, previd);
  230.         }

  231.         @Override
  232.         public String getElementName() {
  233.             return ELEMENT;
  234.         }
  235.     }

  236.     public static class AckAnswer extends FullStreamElement {
  237.         public static final String ELEMENT = "a";

  238.         private final long handledCount;

  239.         public AckAnswer(long handledCount) {
  240.             this.handledCount = handledCount;
  241.         }

  242.         public long getHandledCount() {
  243.             return handledCount;
  244.         }

  245.         @Override
  246.         public CharSequence toXML() {
  247.             XmlStringBuilder xml = new XmlStringBuilder(this);
  248.             xml.attribute("h", Long.toString(handledCount));
  249.             xml.closeEmptyElement();
  250.             return xml;
  251.         }

  252.         @Override
  253.         public String getNamespace() {
  254.             return NAMESPACE;
  255.         }

  256.         @Override
  257.         public String getElementName() {
  258.             return ELEMENT;
  259.         }
  260.     }

  261.     public static class AckRequest extends FullStreamElement {
  262.         public static final String ELEMENT = "r";
  263.         public static final AckRequest INSTANCE = new AckRequest();

  264.         private AckRequest() {
  265.         }

  266.         @Override
  267.         public CharSequence toXML() {
  268.             return '<' + ELEMENT + " xmlns='" + NAMESPACE + "'/>";
  269.         }

  270.         @Override
  271.         public String getNamespace() {
  272.             return NAMESPACE;
  273.         }

  274.         @Override
  275.         public String getElementName() {
  276.             return ELEMENT;
  277.         }
  278.     }
  279. }