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-2026, 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 /* 080 * Don't write an empty value because parsers could interpret that as 081 * there being an embedded vCard on the next line 082 */ 083 throw new SkipMeException(Messages.INSTANCE.getValidationWarning(8)); 084 } 085 086 @Override 087 protected Agent _parseText(String value, VCardDataType dataType, VCardParameters parameters, ParseContext context) { 088 Agent property = new Agent(); 089 090 if (dataType == null) { 091 throw new EmbeddedVCardException(new Injector(property)); 092 } 093 094 property.setUrl(VObjectPropertyValues.unescape(value)); 095 return property; 096 } 097 098 @Override 099 protected Agent _parseHtml(HCardElement element, ParseContext context) { 100 Agent property = new Agent(); 101 102 Set<String> classes = element.classNames(); 103 if (classes.contains("vcard")) { 104 throw new EmbeddedVCardException(new Injector(property)); 105 } 106 107 String url = element.absUrl("href"); 108 if (url.isEmpty()) { 109 url = element.value(); 110 } 111 property.setUrl(url); 112 113 return property; 114 } 115 116 private static class Injector implements EmbeddedVCardException.InjectionCallback { 117 private final Agent property; 118 119 public Injector(Agent property) { 120 this.property = property; 121 } 122 123 public void injectVCard(VCard vcard) { 124 property.setVCard(vcard); 125 } 126 127 public VCardProperty getProperty() { 128 return property; 129 } 130 } 131}