001package ezvcard.property; 002 003import java.text.NumberFormat; 004import java.util.LinkedHashMap; 005import java.util.List; 006import java.util.Locale; 007import java.util.Map; 008 009import ezvcard.SupportedVersions; 010import ezvcard.VCard; 011import ezvcard.VCardVersion; 012import ezvcard.ValidationWarnings; 013import ezvcard.ValidationWarning; 014 015/* 016 Copyright (c) 2012-2023, Michael Angstadt 017 All rights reserved. 018 019 Redistribution and use in source and binary forms, with or without 020 modification, are permitted provided that the following conditions are met: 021 022 1. Redistributions of source code must retain the above copyright notice, this 023 list of conditions and the following disclaimer. 024 2. Redistributions in binary form must reproduce the above copyright notice, 025 this list of conditions and the following disclaimer in the documentation 026 and/or other materials provided with the distribution. 027 028 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 029 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 030 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 031 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 032 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 033 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 034 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 035 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 036 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 037 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 038 039 The views and conclusions contained in the software and documentation are those 040 of the authors and should not be interpreted as representing official policies, 041 either expressed or implied, of the FreeBSD Project. 042 */ 043 044/** 045 * <p> 046 * Defines information about the person's agent. 047 * </p> 048 * 049 * <p> 050 * <b>Code sample (creating)</b> 051 * </p> 052 * 053 * <pre class="brush:java"> 054 * VCard vcard = new VCard(); 055 * 056 * //URL 057 * Agent agent = new Agent("http://www.linkedin.com/BobSmith"); 058 * vcard.setAgent(agent); 059 * 060 * //vCard 061 * VCard agentVCard = new VCard(); 062 * agentVCard.setFormattedName("Bob Smith"); 063 * agentVCard.addTelephoneNumber("(555) 123-4566"); 064 * agentVCard.addUrl("http://www.linkedin.com/BobSmith"); 065 * agent = new Agent(agentVCard); 066 * vcard.setAgent(agent); 067 * </pre> 068 * 069 * <p> 070 * <b>Code sample (retrieving)</b> 071 * </p> 072 * 073 * <pre class="brush:java"> 074 * VCard vcard = ... 075 * Agent agent = vcard.getAgent(); 076 * 077 * String url = agent.getUrl(); 078 * if (url != null) { 079 * //property value is a URL 080 * } 081 * 082 * VCard agentVCard = agent.getVCard(); 083 * if (agentVCard != null) { 084 * //property value is a vCard 085 * } 086 * </pre> 087 * 088 * <p> 089 * <b>Property name:</b> {@code AGENT} 090 * </p> 091 * <p> 092 * <b>Supported versions:</b> {@code 2.1, 3.0} 093 * </p> 094 * 095 * @author Michael Angstadt 096 * @see <a href="http://tools.ietf.org/html/rfc2426#page-19">RFC 2426 p.19</a> 097 * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.18</a> 098 */ 099@SupportedVersions({ VCardVersion.V2_1, VCardVersion.V3_0 }) 100public class Agent extends VCardProperty { 101 private String url; 102 private VCard vcard; 103 104 /** 105 * Creates an empty agent property. 106 */ 107 public Agent() { 108 //empty 109 } 110 111 /** 112 * Creates an agent property. 113 * @param url a URL pointing to the agent's information 114 */ 115 public Agent(String url) { 116 setUrl(url); 117 } 118 119 /** 120 * Creates an agent property. 121 * @param vcard a vCard containing the agent's information 122 */ 123 public Agent(VCard vcard) { 124 setVCard(vcard); 125 } 126 127 /** 128 * Copy constructor. 129 * @param original the property to make a copy of 130 */ 131 public Agent(Agent original) { 132 super(original); 133 url = original.url; 134 vcard = (original.vcard == null) ? null : new VCard(original.vcard); 135 } 136 137 /** 138 * Gets the URL to the agent's information. 139 * @return the URL or null if not set 140 */ 141 public String getUrl() { 142 return url; 143 } 144 145 /** 146 * Sets the URL to the agent's information. 147 * @param url the URL 148 */ 149 public void setUrl(String url) { 150 this.url = url; 151 vcard = null; 152 } 153 154 /** 155 * Gets an embedded vCard with the agent's information. 156 * @return the vCard or null if not set 157 */ 158 public VCard getVCard() { 159 return vcard; 160 } 161 162 /** 163 * Sets an embedded vCard with the agent's information. 164 * @param vcard the vCard 165 */ 166 public void setVCard(VCard vcard) { 167 this.vcard = vcard; 168 url = null; 169 } 170 171 @Override 172 protected void _validate(List<ValidationWarning> warnings, VCardVersion version, VCard vcard) { 173 if (url == null && this.vcard == null) { 174 warnings.add(new ValidationWarning(8)); 175 } 176 177 if (this.vcard != null) { 178 NumberFormat nf = NumberFormat.getIntegerInstance(Locale.ROOT); 179 nf.setMinimumIntegerDigits(2); 180 181 ValidationWarnings validationWarnings = this.vcard.validate(version); 182 for (Map.Entry<VCardProperty, List<ValidationWarning>> entry : validationWarnings) { 183 VCardProperty property = entry.getKey(); 184 List<ValidationWarning> propViolations = entry.getValue(); 185 186 for (ValidationWarning propViolation : propViolations) { 187 String className = (property == null) ? "" : property.getClass().getSimpleName(); 188 189 int code = propViolation.getCode(); 190 String codeStr = (code >= 0) ? "W" + nf.format(code) : ""; 191 String message = propViolation.getMessage(); 192 warnings.add(new ValidationWarning(10, className, codeStr, message)); 193 } 194 } 195 } 196 } 197 198 @Override 199 protected Map<String, Object> toStringValues() { 200 Map<String, Object> values = new LinkedHashMap<>(); 201 values.put("url", url); 202 values.put("vcard", vcard); 203 return values; 204 } 205 206 @Override 207 public Agent copy() { 208 return new Agent(this); 209 } 210 211 @Override 212 public int hashCode() { 213 final int prime = 31; 214 int result = super.hashCode(); 215 result = prime * result + ((url == null) ? 0 : url.hashCode()); 216 result = prime * result + ((vcard == null) ? 0 : vcard.hashCode()); 217 return result; 218 } 219 220 @Override 221 public boolean equals(Object obj) { 222 if (this == obj) return true; 223 if (!super.equals(obj)) return false; 224 Agent other = (Agent) obj; 225 if (url == null) { 226 if (other.url != null) return false; 227 } else if (!url.equals(other.url)) return false; 228 if (vcard == null) { 229 if (other.vcard != null) return false; 230 } else if (!vcard.equals(other.vcard)) return false; 231 return true; 232 } 233}