AMPExtension.java

  1. /**
  2.  *
  3.  * Copyright 2014 Vyacheslav Blinov
  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.smackx.amp.packet;

  18. import java.util.Collections;
  19. import java.util.List;
  20. import java.util.concurrent.CopyOnWriteArrayList;

  21. import org.jivesoftware.smack.packet.ExtensionElement;

  22. import org.jivesoftware.smackx.amp.AMPDeliverCondition;
  23. import org.jivesoftware.smackx.amp.AMPExpireAtCondition;
  24. import org.jivesoftware.smackx.amp.AMPMatchResourceCondition;

  25. public class AMPExtension implements ExtensionElement {

  26.     public static final String NAMESPACE = "http://jabber.org/protocol/amp";
  27.     public static final String ELEMENT = "amp";

  28.     private final CopyOnWriteArrayList<Rule> rules = new CopyOnWriteArrayList<>();
  29.     private boolean perHop = false;

  30.     private final String from;
  31.     private final String to;
  32.     private final Status status;

  33.     /**
  34.      * Create a new AMPExtension instance with defined from, to and status attributes. Used to create incoming packets.
  35.      * @param from jid that triggered this amp callback.
  36.      * @param to receiver of this amp receipt.
  37.      * @param status status of this amp receipt.
  38.      */
  39.     public AMPExtension(String from, String to, Status status) {
  40.         this.from = from;
  41.         this.to = to;
  42.         this.status = status;
  43.     }

  44.     /**
  45.      * Create a new amp request extension to be used with outgoing message.
  46.      */
  47.     public AMPExtension() {
  48.         this.from = null;
  49.         this.to = null;
  50.         this.status = null;
  51.     }

  52.     /**
  53.      * Get the JID that triggered this AMP callback.
  54.      * @return jid that triggered this amp callback.
  55.      */
  56.     public String getFrom() {
  57.         return from;
  58.     }

  59.     /**
  60.      * Get the receiver of this AMP receipt.
  61.      * @return receiver of this amp receipt.
  62.      */
  63.     public String getTo() {
  64.         return to;
  65.     }

  66.     /**
  67.      * Status of this amp notification.
  68.      * @return Status for this amp
  69.      */
  70.     public Status getStatus() {
  71.         return status;
  72.     }

  73.     /**
  74.      * Returns a unmodifiable List of the rules in the packet.
  75.      *
  76.      * @return a unmodifiable List of the rules in the packet.
  77.      */
  78.     public List<Rule> getRules() {
  79.         return Collections.unmodifiableList(rules);
  80.     }

  81.     /**
  82.      * Adds a rule to the amp element. Amp can have any number of rules.
  83.      *
  84.      * @param rule the rule to add.
  85.      */
  86.     public void addRule(Rule rule) {
  87.         rules.add(rule);
  88.     }

  89.     /**
  90.      * Returns a count of the rules in the AMP packet.
  91.      *
  92.      * @return the number of rules in the AMP packet.
  93.      */
  94.     public int getRulesCount() {
  95.         return rules.size();
  96.     }

  97.     /**
  98.      * Sets this amp ruleset to be "per-hop".
  99.      *
  100.      * @param enabled true if "per-hop" should be enabled
  101.      */
  102.     public synchronized void setPerHop(boolean enabled) {
  103.         perHop = enabled;
  104.     }

  105.     /**
  106.      * Returns true is this ruleset is "per-hop".
  107.      *
  108.      * @return true is this ruleset is "per-hop".
  109.      */
  110.     public synchronized boolean isPerHop() {
  111.         return perHop;
  112.     }

  113.     /**
  114.      * Returns the XML element name of the extension sub-packet root element.
  115.      * Always returns "amp"
  116.      *
  117.      * @return the XML element name of the stanza extension.
  118.      */
  119.     @Override
  120.     public String getElementName() {
  121.         return ELEMENT;
  122.     }

  123.     /**
  124.      * Returns the XML namespace of the extension sub-packet root element.
  125.      * According the specification the namespace is always "http://jabber.org/protocol/xhtml-im"
  126.      *
  127.      * @return the XML namespace of the stanza extension.
  128.      */
  129.     @Override
  130.     public String getNamespace() {
  131.         return NAMESPACE;
  132.     }

  133.     /**
  134.      * Returns the XML representation of a XHTML extension according the specification.
  135.      **/
  136.     @Override
  137.     public String toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
  138.         StringBuilder buf = new StringBuilder();
  139.         buf.append('<').append(getElementName()).append(" xmlns=\"").append(getNamespace()).append('"');
  140.         if (status != null) {
  141.             buf.append(" status=\"").append(status.toString()).append('"');
  142.         }
  143.         if (to != null) {
  144.             buf.append(" to=\"").append(to).append('"');
  145.         }
  146.         if (from != null) {
  147.             buf.append(" from=\"").append(from).append('"');
  148.         }
  149.         if (perHop) {
  150.             buf.append(" per-hop=\"true\"");
  151.         }
  152.         buf.append('>');

  153.         // Loop through all the rules and append them to the string buffer
  154.         for (Rule rule : getRules()) {
  155.             buf.append(rule.toXML());
  156.         }

  157.         buf.append("</").append(getElementName()).append('>');
  158.         return buf.toString();
  159.     }

  160.     /**
  161.      * XEP-0079 Rule element. Defines AMP Rule parameters. Can be added to AMPExtension.
  162.      */
  163.     public static class Rule {
  164.         public static final String ELEMENT = "rule";

  165.         private final Action action;
  166.         private final Condition condition;

  167.         public Action getAction() {
  168.             return action;
  169.         }

  170.         public Condition getCondition() {
  171.             return condition;
  172.         }

  173.         /**
  174.          * Create a new amp rule with specified action and condition. Value will be taken from condition argument
  175.          * @param action action for this rule
  176.          * @param condition condition for this rule
  177.          */
  178.         public Rule(Action action, Condition condition) {
  179.             if (action == null)
  180.                 throw new NullPointerException("Can't create Rule with null action");
  181.             if (condition == null)
  182.                 throw new NullPointerException("Can't create Rule with null condition");

  183.             this.action = action;
  184.             this.condition = condition;
  185.         }

  186.         private String toXML() {
  187.             return "<" + ELEMENT + " " + Action.ATTRIBUTE_NAME + "=\"" + action.toString() + "\" " +
  188.                     Condition.ATTRIBUTE_NAME + "=\"" + condition.getName() + "\" " +
  189.                     "value=\"" + condition.getValue() + "\"/>";
  190.         }
  191.     }

  192.     /**
  193.      * Interface for defining XEP-0079 Conditions and their values.
  194.      * @see AMPDeliverCondition
  195.      * @see AMPExpireAtCondition
  196.      * @see AMPMatchResourceCondition
  197.      **/
  198.     public interface Condition {
  199.         String getName();
  200.         String getValue();

  201.         String ATTRIBUTE_NAME = "condition";
  202.     }

  203.     /**
  204.      * amp action attribute.
  205.      * See http://xmpp.org/extensions/xep-0079.html#actions-def
  206.      **/
  207.     public enum Action {
  208.         /**
  209.          * The "alert" action triggers a reply &lt;message/&gt; stanza to the sending entity.
  210.          * This &lt;message/&gt; stanza MUST contain the element &lt;amp status='alert'/&gt;,
  211.          * which itself contains the &lt;rule/&gt; that triggered this action. In all other respects,
  212.          * this action behaves as "drop".
  213.          */
  214.         alert,
  215.         /**
  216.          * The "drop" action silently discards the message from any further delivery attempts
  217.          * and ensures that it is not placed into offline storage.
  218.          * The drop MUST NOT result in other responses.
  219.          */
  220.         drop,
  221.         /**
  222.          * The "error" action triggers a reply &lt;message/&gt; stanza of type "error" to the sending entity.
  223.          * The &lt;message/&gt; stanza's &lt;error/&gt; child MUST contain a
  224.          * &lt;failed-rules xmlns='http://jabber.org/protocol/amp#errors'/&gt; error condition,
  225.          * which itself contains the rules that triggered this action.
  226.          */
  227.         error,
  228.         /**
  229.          * The "notify" action triggers a reply &lt;message/&gt; stanza to the sending entity.
  230.          * This &lt;message/&gt; stanza MUST contain the element &lt;amp status='notify'/&gt;, which itself
  231.          * contains the &lt;rule/&gt; that triggered this action. Unlike the other actions,
  232.          * this action does not override the default behavior for a server.
  233.          * Instead, the server then executes its default behavior after sending the notify.
  234.          */
  235.         notify;

  236.         public static final String ATTRIBUTE_NAME = "action";
  237.     }

  238.     /**
  239.      * amp notification status as defined by XEP-0079.
  240.      */
  241.     public enum Status {
  242.         alert,
  243.         error,
  244.         notify
  245.     }
  246. }