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}