001/** 002 * 003 * Copyright the original author or authors 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smackx.pubsub; 018 019import java.text.ParseException; 020import java.util.ArrayList; 021import java.util.Collection; 022import java.util.Date; 023import java.util.List; 024import java.util.UnknownFormatConversionException; 025 026import org.jivesoftware.smackx.xdata.Form; 027import org.jivesoftware.smackx.xdata.FormField; 028import org.jivesoftware.smackx.xdata.packet.DataForm; 029 030import org.jxmpp.util.XmppDateTime; 031 032/** 033 * A decorator for a {@link Form} to easily enable reading and updating 034 * of subscription options. All operations read or update the underlying {@link DataForm}. 035 * 036 * <p>Unlike the {@link Form}.setAnswer(XXX)} methods, which throw an exception if the field does not 037 * exist, all <b>SubscribeForm.setXXX</b> methods will create the field in the wrapped form 038 * if it does not already exist. 039 * 040 * @author Robin Collier 041 */ 042public class SubscribeForm extends Form { 043 public SubscribeForm(DataForm configDataForm) { 044 super(configDataForm); 045 } 046 047 public SubscribeForm(Form subscribeOptionsForm) { 048 super(subscribeOptionsForm.getDataFormToSend()); 049 } 050 051 public SubscribeForm(DataForm.Type formType) { 052 super(formType); 053 } 054 055 /** 056 * Determines if an entity wants to receive notifications. 057 * 058 * @return true if want to receive, false otherwise 059 */ 060 public boolean isDeliverOn() { 061 return parseBoolean(getFieldValue(SubscribeOptionFields.deliver)); 062 } 063 064 /** 065 * Sets whether an entity wants to receive notifications. 066 * 067 * @param deliverNotifications 068 */ 069 public void setDeliverOn(boolean deliverNotifications) { 070 addField(SubscribeOptionFields.deliver, FormField.Type.bool); 071 setAnswer(SubscribeOptionFields.deliver.getFieldName(), deliverNotifications); 072 } 073 074 /** 075 * Determines if notifications should be delivered as aggregations or not. 076 * 077 * @return true to aggregate, false otherwise 078 */ 079 public boolean isDigestOn() { 080 return parseBoolean(getFieldValue(SubscribeOptionFields.digest)); 081 } 082 083 /** 084 * Sets whether notifications should be delivered as aggregations or not. 085 * 086 * @param digestOn true to aggregate, false otherwise 087 */ 088 public void setDigestOn(boolean digestOn) { 089 addField(SubscribeOptionFields.deliver, FormField.Type.bool); 090 setAnswer(SubscribeOptionFields.deliver.getFieldName(), digestOn); 091 } 092 093 /** 094 * Gets the minimum number of milliseconds between sending notification digests. 095 * 096 * @return The frequency in milliseconds 097 */ 098 public int getDigestFrequency() { 099 return Integer.parseInt(getFieldValue(SubscribeOptionFields.digest_frequency)); 100 } 101 102 /** 103 * Sets the minimum number of milliseconds between sending notification digests. 104 * 105 * @param frequency The frequency in milliseconds 106 */ 107 public void setDigestFrequency(int frequency) { 108 addField(SubscribeOptionFields.digest_frequency, FormField.Type.text_single); 109 setAnswer(SubscribeOptionFields.digest_frequency.getFieldName(), frequency); 110 } 111 112 /** 113 * Get the time at which the leased subscription will expire, or has expired. 114 * 115 * @return The expiry date 116 */ 117 public Date getExpiry() { 118 String dateTime = getFieldValue(SubscribeOptionFields.expire); 119 try { 120 return XmppDateTime.parseDate(dateTime); 121 } 122 catch (ParseException e) { 123 UnknownFormatConversionException exc = new UnknownFormatConversionException(dateTime); 124 exc.initCause(e); 125 throw exc; 126 } 127 } 128 129 /** 130 * Sets the time at which the leased subscription will expire, or has expired. 131 * 132 * @param expire The expiry date 133 */ 134 public void setExpiry(Date expire) { 135 addField(SubscribeOptionFields.expire, FormField.Type.text_single); 136 setAnswer(SubscribeOptionFields.expire.getFieldName(), XmppDateTime.formatXEP0082Date(expire)); 137 } 138 139 /** 140 * Determines whether the entity wants to receive an XMPP message body in 141 * addition to the payload format. 142 * 143 * @return true to receive the message body, false otherwise 144 */ 145 public boolean isIncludeBody() { 146 return parseBoolean(getFieldValue(SubscribeOptionFields.include_body)); 147 } 148 149 /** 150 * Sets whether the entity wants to receive an XMPP message body in 151 * addition to the payload format. 152 * 153 * @param include true to receive the message body, false otherwise 154 */ 155 public void setIncludeBody(boolean include) { 156 addField(SubscribeOptionFields.include_body, FormField.Type.bool); 157 setAnswer(SubscribeOptionFields.include_body.getFieldName(), include); 158 } 159 160 /** 161 * Gets the {@link PresenceState} for which an entity wants to receive 162 * notifications. 163 * 164 * @return the list of states 165 */ 166 public List<PresenceState> getShowValues() { 167 ArrayList<PresenceState> result = new ArrayList<>(5); 168 169 for (String state : getFieldValues(SubscribeOptionFields.show_values)) { 170 result.add(PresenceState.valueOf(state)); 171 } 172 return result; 173 } 174 175 /** 176 * Sets the list of {@link PresenceState} for which an entity wants 177 * to receive notifications. 178 * 179 * @param stateValues The list of states 180 */ 181 public void setShowValues(Collection<PresenceState> stateValues) { 182 ArrayList<String> values = new ArrayList<>(stateValues.size()); 183 184 for (PresenceState state : stateValues) { 185 values.add(state.toString()); 186 } 187 addField(SubscribeOptionFields.show_values, FormField.Type.list_multi); 188 setAnswer(SubscribeOptionFields.show_values.getFieldName(), values); 189 } 190 191 192 private static boolean parseBoolean(String fieldValue) { 193 return ("1".equals(fieldValue) || "true".equals(fieldValue)); 194 } 195 196 private String getFieldValue(SubscribeOptionFields field) { 197 FormField formField = getField(field.getFieldName()); 198 199 return formField.getFirstValue(); 200 } 201 202 private List<String> getFieldValues(SubscribeOptionFields field) { 203 FormField formField = getField(field.getFieldName()); 204 205 return formField.getValuesAsString(); 206 } 207 208 private void addField(SubscribeOptionFields nodeField, FormField.Type type) { 209 String fieldName = nodeField.getFieldName(); 210 211 if (getField(fieldName) == null) { 212 FormField field = new FormField(fieldName); 213 field.setType(type); 214 addField(field); 215 } 216 } 217}