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 { SubscribeForm(DataForm configDataForm)41 public SubscribeForm(DataForm configDataForm) 42 { 43 super(configDataForm); 44 } 45 SubscribeForm(Form subscribeOptionsForm)46 public SubscribeForm(Form subscribeOptionsForm) 47 { 48 super(subscribeOptionsForm.getDataFormToSend()); 49 } 50 SubscribeForm(FormType formType)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 */ isDeliverOn()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 */ setDeliverOn(boolean deliverNotifications)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 */ isDigestOn()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 */ setDigestOn(boolean digestOn)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 */ getDigestFrequency()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 */ setDigestFrequency(int frequency)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 */ getExpiry()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 */ setExpiry(Date expire)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 */ isIncludeBody()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 */ setIncludeBody(boolean include)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 */ getShowValues()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 */ setShowValues(Collection<PresenceState> stateValues)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 parseBoolean(String fieldValue)211 static private boolean parseBoolean(String fieldValue) 212 { 213 return ("1".equals(fieldValue) || "true".equals(fieldValue)); 214 } 215 getFieldValue(SubscribeOptionFields field)216 private String getFieldValue(SubscribeOptionFields field) 217 { 218 FormField formField = getField(field.getFieldName()); 219 220 return formField.getValues().next(); 221 } 222 getFieldValues(SubscribeOptionFields field)223 private Iterator<String> getFieldValues(SubscribeOptionFields field) 224 { 225 FormField formField = getField(field.getFieldName()); 226 227 return formField.getValues(); 228 } 229 addField(SubscribeOptionFields nodeField, String type)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