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