001package ezvcard.io.scribe; 002 003import java.util.Set; 004 005import com.github.mangstadt.vinnie.io.VObjectPropertyValues; 006 007import ezvcard.Messages; 008import ezvcard.VCard; 009import ezvcard.VCardDataType; 010import ezvcard.VCardVersion; 011import ezvcard.io.EmbeddedVCardException; 012import ezvcard.io.ParseContext; 013import ezvcard.io.SkipMeException; 014import ezvcard.io.html.HCardElement; 015import ezvcard.io.text.WriteContext; 016import ezvcard.parameter.VCardParameters; 017import ezvcard.property.Agent; 018import ezvcard.property.VCardProperty; 019 020/* 021 Copyright (c) 2012-2023, Michael Angstadt 022 All rights reserved. 023 024 Redistribution and use in source and binary forms, with or without 025 modification, are permitted provided that the following conditions are met: 026 027 1. Redistributions of source code must retain the above copyright notice, this 028 list of conditions and the following disclaimer. 029 2. Redistributions in binary form must reproduce the above copyright notice, 030 this list of conditions and the following disclaimer in the documentation 031 and/or other materials provided with the distribution. 032 033 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 034 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 035 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 036 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 037 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 038 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 039 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 040 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 041 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 042 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 043 */ 044 045/** 046 * Marshals {@link Agent} properties. 047 * @author Michael Angstadt 048 */ 049public class AgentScribe extends VCardPropertyScribe<Agent> { 050 public AgentScribe() { 051 super(Agent.class, "AGENT"); 052 } 053 054 @Override 055 protected VCardDataType _defaultDataType(VCardVersion version) { 056 return null; 057 } 058 059 @Override 060 protected VCardDataType _dataType(Agent property, VCardVersion version) { 061 if (property.getUrl() != null) { 062 return (version == VCardVersion.V2_1) ? VCardDataType.URL : VCardDataType.URI; 063 } 064 return null; 065 } 066 067 @Override 068 protected String _writeText(Agent property, WriteContext context) { 069 String url = property.getUrl(); 070 if (url != null) { 071 return url; 072 } 073 074 VCard vcard = property.getVCard(); 075 if (vcard != null) { 076 throw new EmbeddedVCardException(vcard); 077 } 078 079 //don't write an empty value because parsers could interpret that as there being an embedded vCard on the next line 080 throw new SkipMeException(Messages.INSTANCE.getValidationWarning(8)); 081 } 082 083 @Override 084 protected Agent _parseText(String value, VCardDataType dataType, VCardParameters parameters, ParseContext context) { 085 Agent property = new Agent(); 086 087 if (dataType == null) { 088 throw new EmbeddedVCardException(new Injector(property)); 089 } 090 091 property.setUrl(VObjectPropertyValues.unescape(value)); 092 return property; 093 } 094 095 @Override 096 protected Agent _parseHtml(HCardElement element, ParseContext context) { 097 Agent property = new Agent(); 098 099 Set<String> classes = element.classNames(); 100 if (classes.contains("vcard")) { 101 throw new EmbeddedVCardException(new Injector(property)); 102 } 103 104 String url = element.absUrl("href"); 105 if (url.isEmpty()) { 106 url = element.value(); 107 } 108 property.setUrl(url); 109 110 return property; 111 } 112 113 private static class Injector implements EmbeddedVCardException.InjectionCallback { 114 private final Agent property; 115 116 public Injector(Agent property) { 117 this.property = property; 118 } 119 120 public void injectVCard(VCard vcard) { 121 property.setVCard(vcard); 122 } 123 124 public VCardProperty getProperty() { 125 return property; 126 } 127 } 128}