Home | History | Annotate | Download | only in pubsub
      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.pubsub;
     15 
     16 import java.text.ParseException;
     17 import java.text.SimpleDateFormat;
     18 import java.util.ArrayList;
     19 import java.util.Collection;
     20 import java.util.Date;
     21 import java.util.Iterator;
     22 import java.util.UnknownFormatConversionException;
     23 
     24 import org.jivesoftware.smack.util.StringUtils;
     25 import org.jivesoftware.smackx.Form;
     26 import org.jivesoftware.smackx.FormField;
     27 import org.jivesoftware.smackx.packet.DataForm;
     28 
     29 /**
     30  * A decorator for a {@link Form} to easily enable reading and updating
     31  * of subscription options.  All operations read or update the underlying {@link DataForm}.
     32  *
     33  * <p>Unlike the {@link Form}.setAnswer(XXX)} methods, which throw an exception if the field does not
     34  * exist, all <b>SubscribeForm.setXXX</b> methods will create the field in the wrapped form
     35  * if it does not already exist.
     36  *
     37  * @author Robin Collier
     38  */
     39 public class SubscribeForm extends Form
     40 {
     41 	public SubscribeForm(DataForm configDataForm)
     42 	{
     43 		super(configDataForm);
     44 	}
     45 
     46 	public SubscribeForm(Form subscribeOptionsForm)
     47 	{
     48 		super(subscribeOptionsForm.getDataFormToSend());
     49 	}
     50 
     51 	public SubscribeForm(FormType formType)
     52 	{
     53 		super(formType.toString());
     54 	}
     55 
     56 	/**
     57 	 * Determines if an entity wants to receive notifications.
     58 	 *
     59 	 * @return true if want to receive, false otherwise
     60 	 */
     61 	public boolean isDeliverOn()
     62 	{
     63 		return parseBoolean(getFieldValue(SubscribeOptionFields.deliver));
     64 	}
     65 
     66 	/**
     67 	 * Sets whether an entity wants to receive notifications.
     68 	 *
     69 	 * @param deliverNotifications
     70 	 */
     71 	public void setDeliverOn(boolean deliverNotifications)
     72 	{
     73 		addField(SubscribeOptionFields.deliver, FormField.TYPE_BOOLEAN);
     74 		setAnswer(SubscribeOptionFields.deliver.getFieldName(), deliverNotifications);
     75 	}
     76 
     77 	/**
     78 	 * Determines if notifications should be delivered as aggregations or not.
     79 	 *
     80 	 * @return true to aggregate, false otherwise
     81 	 */
     82 	public boolean isDigestOn()
     83 	{
     84 		return parseBoolean(getFieldValue(SubscribeOptionFields.digest));
     85 	}
     86 
     87 	/**
     88 	 * Sets whether notifications should be delivered as aggregations or not.
     89 	 *
     90 	 * @param digestOn true to aggregate, false otherwise
     91 	 */
     92 	public void setDigestOn(boolean digestOn)
     93 	{
     94 		addField(SubscribeOptionFields.deliver, FormField.TYPE_BOOLEAN);
     95 		setAnswer(SubscribeOptionFields.deliver.getFieldName(), digestOn);
     96 	}
     97 
     98 	/**
     99 	 * Gets the minimum number of milliseconds between sending notification digests
    100 	 *
    101 	 * @return The frequency in milliseconds
    102 	 */
    103 	public int getDigestFrequency()
    104 	{
    105 		return Integer.parseInt(getFieldValue(SubscribeOptionFields.digest_frequency));
    106 	}
    107 
    108 	/**
    109 	 * Sets the minimum number of milliseconds between sending notification digests
    110 	 *
    111 	 * @param frequency The frequency in milliseconds
    112 	 */
    113 	public void setDigestFrequency(int frequency)
    114 	{
    115 		addField(SubscribeOptionFields.digest_frequency, FormField.TYPE_TEXT_SINGLE);
    116 		setAnswer(SubscribeOptionFields.digest_frequency.getFieldName(), frequency);
    117 	}
    118 
    119 	/**
    120 	 * Get the time at which the leased subscription will expire, or has expired.
    121 	 *
    122 	 * @return The expiry date
    123 	 */
    124 	public Date getExpiry()
    125 	{
    126 		String dateTime = getFieldValue(SubscribeOptionFields.expire);
    127 		try
    128 		{
    129 			return StringUtils.parseDate(dateTime);
    130 		}
    131 		catch (ParseException e)
    132 		{
    133 			UnknownFormatConversionException exc = new UnknownFormatConversionException(dateTime);
    134 			exc.initCause(e);
    135 			throw exc;
    136 		}
    137 	}
    138 
    139 	/**
    140 	 * Sets the time at which the leased subscription will expire, or has expired.
    141 	 *
    142 	 * @param expire The expiry date
    143 	 */
    144 	public void setExpiry(Date expire)
    145 	{
    146 		addField(SubscribeOptionFields.expire, FormField.TYPE_TEXT_SINGLE);
    147 		setAnswer(SubscribeOptionFields.expire.getFieldName(), StringUtils.formatXEP0082Date(expire));
    148 	}
    149 
    150 	/**
    151 	 * Determines whether the entity wants to receive an XMPP message body in
    152 	 * addition to the payload format.
    153 	 *
    154 	 * @return true to receive the message body, false otherwise
    155 	 */
    156 	public boolean isIncludeBody()
    157 	{
    158 		return parseBoolean(getFieldValue(SubscribeOptionFields.include_body));
    159 	}
    160 
    161 	/**
    162 	 * Sets whether the entity wants to receive an XMPP message body in
    163 	 * addition to the payload format.
    164 	 *
    165 	 * @param include true to receive the message body, false otherwise
    166 	 */
    167 	public void setIncludeBody(boolean include)
    168 	{
    169 		addField(SubscribeOptionFields.include_body, FormField.TYPE_BOOLEAN);
    170 		setAnswer(SubscribeOptionFields.include_body.getFieldName(), include);
    171 	}
    172 
    173 	/**
    174 	 * Gets the {@link PresenceState} for which an entity wants to receive
    175 	 * notifications.
    176 	 *
    177 	 * @return iterator over the list of states
    178 	 */
    179 	public Iterator<PresenceState> getShowValues()
    180 	{
    181 		ArrayList<PresenceState> result = new ArrayList<PresenceState>(5);
    182 		Iterator<String > it = getFieldValues(SubscribeOptionFields.show_values);
    183 
    184 		while (it.hasNext())
    185 		{
    186 			String state = it.next();
    187 			result.add(PresenceState.valueOf(state));
    188 		}
    189 		return result.iterator();
    190 	}
    191 
    192 	/**
    193 	 * Sets the list of {@link PresenceState} for which an entity wants
    194 	 * to receive notifications.
    195 	 *
    196 	 * @param stateValues The list of states
    197 	 */
    198 	public void setShowValues(Collection<PresenceState> stateValues)
    199 	{
    200 		ArrayList<String> values = new ArrayList<String>(stateValues.size());
    201 
    202 		for (PresenceState state : stateValues)
    203 		{
    204 			values.add(state.toString());
    205 		}
    206 		addField(SubscribeOptionFields.show_values, FormField.TYPE_LIST_MULTI);
    207 		setAnswer(SubscribeOptionFields.show_values.getFieldName(), values);
    208 	}
    209 
    210 
    211 	static private boolean parseBoolean(String fieldValue)
    212 	{
    213 		return ("1".equals(fieldValue) || "true".equals(fieldValue));
    214 	}
    215 
    216 	private String getFieldValue(SubscribeOptionFields field)
    217 	{
    218 		FormField formField = getField(field.getFieldName());
    219 
    220 		return formField.getValues().next();
    221 	}
    222 
    223 	private Iterator<String> getFieldValues(SubscribeOptionFields field)
    224 	{
    225 		FormField formField = getField(field.getFieldName());
    226 
    227 		return formField.getValues();
    228 	}
    229 
    230 	private void addField(SubscribeOptionFields nodeField, String type)
    231 	{
    232 		String fieldName = nodeField.getFieldName();
    233 
    234 		if (getField(fieldName) == null)
    235 		{
    236 			FormField field = new FormField(fieldName);
    237 			field.setType(type);
    238 			addField(field);
    239 		}
    240 	}
    241 }
    242