001/** 002 * 003 * Copyright 2020 Aditya Borikar 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.softwareinfo.form; 018 019import java.util.List; 020 021import org.jivesoftware.smack.util.EqualsUtil; 022import org.jivesoftware.smack.util.HashCode; 023import org.jivesoftware.smackx.mediaelement.element.MediaElement; 024import org.jivesoftware.smackx.xdata.FormField; 025import org.jivesoftware.smackx.xdata.FormFieldChildElement; 026import org.jivesoftware.smackx.xdata.TextSingleFormField; 027import org.jivesoftware.smackx.xdata.form.FilledForm; 028import org.jivesoftware.smackx.xdata.form.Form; 029import org.jivesoftware.smackx.xdata.packet.DataForm; 030import org.jivesoftware.smackx.xdata.packet.DataForm.Type; 031 032/** 033 * {@link Form} that contains the software information. 034 * <br> 035 * Instance of {@link SoftwareInfoForm} can be created using {@link Builder#build()} method. 036 * <br> 037 * To obtain an instance of {@link Builder}, use {@link SoftwareInfoForm#getBuilder()} method. 038 * <br> 039 * An example to illustrate is provided inside SoftwareInfoFormTest inside the test package. 040 */ 041public final class SoftwareInfoForm extends FilledForm { 042 043 public static final String FORM_TYPE = "urn:xmpp:dataforms:softwareinfo"; 044 public static final String OS = "os"; 045 public static final String OS_VERSION = "os_version"; 046 public static final String SOFTWARE = "software"; 047 public static final String SOFTWARE_VERSION = "software_version"; 048 public static final String ICON = "icon"; 049 050 private SoftwareInfoForm(DataForm dataForm) { 051 super(dataForm); 052 } 053 054 /** 055 * Returns name of the OS used by client. 056 * <br> 057 * @return os 058 */ 059 public String getOS() { 060 return readFirstValue(OS); 061 } 062 063 /** 064 * Returns version of the OS used by client. 065 * <br> 066 * @return os_version 067 */ 068 public String getOSVersion() { 069 return readFirstValue(OS_VERSION); 070 } 071 072 /** 073 * Returns name of the software used by client. 074 * <br> 075 * @return software 076 */ 077 public String getSoftwareName() { 078 return readFirstValue(SOFTWARE); 079 } 080 081 /** 082 * Returns version of the software used by client. 083 * <br> 084 * @return software_version 085 */ 086 public String getSoftwareVersion () { 087 return readFirstValue(SOFTWARE_VERSION); 088 } 089 090 /** 091 * Returns the software icon if used by client. 092 * <br> 093 * @return {@link MediaElement} MediaElement or null 094 */ 095 public MediaElement getIcon () { 096 FormField field = getField(ICON); 097 if (field == null) { 098 return null; 099 } 100 FormFieldChildElement media = field.getFormFieldChildElement(MediaElement.QNAME); 101 if (media == null) { 102 return null; 103 } 104 return (MediaElement) media; 105 } 106 107 @Override 108 public boolean equals(Object obj) { 109 return EqualsUtil.equals(this, obj, (equalsBuilder, otherObj) -> { 110 equalsBuilder.append(getDataForm().getType(), otherObj.getDataForm().getType()) 111 .append(getDataForm().getTitle(), otherObj.getDataForm().getTitle()) 112 .append(getDataForm().getReportedData(), otherObj.getDataForm().getReportedData()) 113 .append(getDataForm().getItems(), otherObj.getDataForm().getItems()) 114 .append(getDataForm().getFields(), otherObj.getDataForm().getFields()) 115 .append(getDataForm().getExtensionElements(), otherObj.getDataForm().getExtensionElements()); 116 }); 117 } 118 119 @Override 120 public int hashCode() { 121 HashCode.Builder builder = HashCode.builder(); 122 builder.append(getDataForm().getFields()); 123 builder.append(getDataForm().getItems()); 124 builder.append(getDataForm().getExtensionElements()); 125 return builder.build(); 126 } 127 128 /** 129 * Returns a new instance of {@link Builder}. 130 * <br> 131 * @return Builder 132 */ 133 public static Builder getBuilder() { 134 return new Builder(); 135 } 136 137 /** 138 * Builder class for {@link SoftwareInfoForm}. 139 * <br> 140 * To obtain an instance of {@link Builder}, use {@link SoftwareInfoForm#getBuilder()} method. 141 * <br> 142 * Use appropriate setters to include information inside SoftwareInfoForms. 143 */ 144 public static final class Builder { 145 DataForm.Builder dataFormBuilder; 146 147 private Builder() { 148 dataFormBuilder = DataForm.builder(Type.result); 149 TextSingleFormField formField = FormField.buildHiddenFormType(FORM_TYPE); 150 dataFormBuilder.addField(formField); 151 } 152 153 /** 154 * This will allow to include Icon using height, width and Uri's as a 155 * {@link FormField}. 156 * <br> 157 * @param height Height of the image 158 * @param width Width of the image 159 * @param uriList List of URIs 160 * @return Builder 161 */ 162 public Builder setIcon(int height, int width, List<MediaElement.Uri> uriList) { 163 MediaElement.Builder mediaBuilder = MediaElement.builder(); 164 for (MediaElement.Uri uri : uriList) { 165 mediaBuilder.addUri(uri); 166 } 167 MediaElement mediaElement = mediaBuilder.setHeightAndWidth(height, width).build(); 168 return setIcon(mediaElement); 169 } 170 171 /** 172 * This will allow to include {@link MediaElement} directly as a 173 * {@link FormField}. 174 * <br> 175 * @param mediaElement MediaElement to be included 176 * @return Builder 177 */ 178 public Builder setIcon(MediaElement mediaElement) { 179 FormField.Builder<?, ?> builder = FormField.builder(ICON); 180 builder.addFormFieldChildElement(mediaElement); 181 dataFormBuilder.addField(builder.build()); 182 return this; 183 } 184 185 /** 186 * Include Operating System's name as a {@link FormField}. 187 * <br> 188 * @param os Name of the OS 189 * @return Builder 190 */ 191 public Builder setOS(String os) { 192 TextSingleFormField.Builder builder = FormField.builder(OS); 193 builder.setValue(os); 194 dataFormBuilder.addField(builder.build()); 195 return this; 196 } 197 198 /** 199 * Include Operating System's version as a {@link FormField}. 200 * <br> 201 * @param os_version Version of OS 202 * @return Builder 203 */ 204 public Builder setOSVersion(String os_version) { 205 TextSingleFormField.Builder builder = FormField.builder(OS_VERSION); 206 builder.setValue(os_version); 207 dataFormBuilder.addField(builder.build()); 208 return this; 209 } 210 211 /** 212 * Include Software name as a {@link FormField}. 213 * <br> 214 * @param software Name of the software 215 * @return Builder 216 */ 217 public Builder setSoftware(String software) { 218 TextSingleFormField.Builder builder = FormField.builder(SOFTWARE); 219 builder.setValue(software); 220 dataFormBuilder.addField(builder.build()); 221 return this; 222 } 223 224 /** 225 * Include Software Version as a {@link FormField}. 226 * <br> 227 * @param softwareVersion Version of the Software in use 228 * @return Builder 229 */ 230 public Builder setSoftwareVersion(String softwareVersion) { 231 TextSingleFormField.Builder builder = FormField.builder(SOFTWARE_VERSION); 232 builder.setValue(softwareVersion); 233 dataFormBuilder.addField(builder.build()); 234 return this; 235 } 236 237 /** 238 * Include {@link DataForm} to be encapsulated under SoftwareInfoForm. 239 * <br> 240 * @param dataForm The dataform containing Software Information 241 * @return Builder 242 */ 243 public Builder setDataForm(DataForm dataForm) { 244 if (dataForm.getTitle() != null || !dataForm.getItems().isEmpty() 245 || dataForm.getReportedData() != null || !dataForm.getInstructions().isEmpty()) { 246 throw new IllegalArgumentException("Illegal Arguements for SoftwareInformation"); 247 } 248 String formTypeValue = dataForm.getFormType(); 249 if (formTypeValue == null) { 250 throw new IllegalArgumentException("FORM_TYPE Formfield missing"); 251 } 252 if (!formTypeValue.equals(SoftwareInfoForm.FORM_TYPE)) { 253 throw new IllegalArgumentException("Malformed FORM_TYPE Formfield encountered"); 254 } 255 this.dataFormBuilder = dataForm.asBuilder(); 256 return this; 257 } 258 259 /** 260 * This method is called to build a {@link SoftwareInfoForm}. 261 * <br> 262 * @return Builder 263 */ 264 public SoftwareInfoForm build() { 265 return new SoftwareInfoForm(dataFormBuilder.build()); 266 } 267 } 268}