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}